xref: /inferno-os/libbio/bgetrune.c (revision 72335078034e3cd7edcb1739556b405a3e1e9bf8)
137da2899SCharles.Forsyth #include	"lib9.h"
237da2899SCharles.Forsyth #include	<bio.h>
337da2899SCharles.Forsyth 
437da2899SCharles.Forsyth long
Bgetrune(Biobuf * bp)537da2899SCharles.Forsyth Bgetrune(Biobuf *bp)
637da2899SCharles.Forsyth {
737da2899SCharles.Forsyth 	int c, i;
837da2899SCharles.Forsyth 	Rune rune;
9*72335078SCharles Forsyth 	char str[UTFmax];
1037da2899SCharles.Forsyth 
1137da2899SCharles.Forsyth 	c = Bgetc(bp);
1237da2899SCharles.Forsyth 	if(c < Runeself) {		/* one char */
1337da2899SCharles.Forsyth 		bp->runesize = 1;
1437da2899SCharles.Forsyth 		return c;
1537da2899SCharles.Forsyth 	}
1637da2899SCharles.Forsyth 	str[0] = c;
17*72335078SCharles Forsyth 	bp->runesize = 0;
1837da2899SCharles.Forsyth 
1937da2899SCharles.Forsyth 	for(i=1;;) {
2037da2899SCharles.Forsyth 		c = Bgetc(bp);
2137da2899SCharles.Forsyth 		if(c < 0)
2237da2899SCharles.Forsyth 			return c;
23*72335078SCharles Forsyth 		if (i >= sizeof str)
24*72335078SCharles Forsyth 			return Runeerror;
2537da2899SCharles.Forsyth 		str[i++] = c;
2637da2899SCharles.Forsyth 
2737da2899SCharles.Forsyth 		if(fullrune(str, i)) {
28*72335078SCharles Forsyth 			/* utf is long enough to be a rune, but could be bad. */
2937da2899SCharles.Forsyth 			bp->runesize = chartorune(&rune, str);
30*72335078SCharles Forsyth 			if (rune == Runeerror)
31*72335078SCharles Forsyth 				bp->runesize = 0;	/* push back nothing */
32*72335078SCharles Forsyth 			else
33*72335078SCharles Forsyth 				/* push back bytes unconsumed by chartorune */
34*72335078SCharles Forsyth 				for(; i > bp->runesize; i--)
3537da2899SCharles.Forsyth 					Bungetc(bp);
3637da2899SCharles.Forsyth 			return rune;
3737da2899SCharles.Forsyth 		}
3837da2899SCharles.Forsyth 	}
3937da2899SCharles.Forsyth }
4037da2899SCharles.Forsyth 
4137da2899SCharles.Forsyth int
Bungetrune(Biobuf * bp)4237da2899SCharles.Forsyth Bungetrune(Biobuf *bp)
4337da2899SCharles.Forsyth {
4437da2899SCharles.Forsyth 
4537da2899SCharles.Forsyth 	if(bp->state == Bracteof)
4637da2899SCharles.Forsyth 		bp->state = Bractive;
4737da2899SCharles.Forsyth 	if(bp->state != Bractive)
4837da2899SCharles.Forsyth 		return Beof;
4937da2899SCharles.Forsyth 	bp->icount -= bp->runesize;
5037da2899SCharles.Forsyth 	bp->runesize = 0;
5137da2899SCharles.Forsyth 	return 1;
5237da2899SCharles.Forsyth }
53