xref: /plan9/sys/src/libbio/bgetrune.c (revision eaba85aa6b158bdf68fdb77f770e3ba0899a8b5e)
1 #include	<u.h>
2 #include	<libc.h>
3 #include	<bio.h>
4 
5 long
Bgetrune(Biobufhdr * bp)6 Bgetrune(Biobufhdr *bp)
7 {
8 	int c, i;
9 	Rune rune;
10 	char str[UTFmax];
11 
12 	c = Bgetc(bp);
13 	if(c < Runeself) {		/* one char */
14 		bp->runesize = 1;
15 		return c;
16 	}
17 	str[0] = c;
18 	bp->runesize = 0;
19 
20 	for(i=1;;) {
21 		c = Bgetc(bp);
22 		if(c < 0)
23 			return c;
24 		if (i >= sizeof str)
25 			return Runeerror;
26 		str[i++] = c;
27 
28 		if(fullrune(str, i)) {
29 			/* utf is long enough to be a rune, but could be bad. */
30 			bp->runesize = chartorune(&rune, str);
31 			if (rune == Runeerror)
32 				bp->runesize = 0;	/* push back nothing */
33 			else
34 				/* push back bytes unconsumed by chartorune */
35 				for(; i > bp->runesize; i--)
36 					Bungetc(bp);
37 			return rune;
38 		}
39 	}
40 }
41 
42 int
Bungetrune(Biobufhdr * bp)43 Bungetrune(Biobufhdr *bp)
44 {
45 
46 	if(bp->state == Bracteof)
47 		bp->state = Bractive;
48 	if(bp->state != Bractive)
49 		return Beof;
50 	bp->icount -= bp->runesize;
51 	bp->runesize = 0;
52 	return 1;
53 }
54