xref: /inferno-os/emu/Nt/r16.c (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
1 #define UNICODE
2 #define Unknown win_Unknown
3 #include	<windows.h>
4 #include	<winbase.h>
5 #undef Unknown
6 #undef	Sleep
7 #include	"dat.h"
8 #include	"fns.h"
9 #include	"error.h"
10 #include	"r16.h"
11 
12 #define Bit(i) (7-(i))
13 /* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */
14 #define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF)
15 /* 0000 0000 0000 0111 1111 1111 */
16 #define	RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1)
17 
18 enum
19 {
20 	Bitx	= Bit(1),
21 
22 	Tx	= T(1),			/* 1000 0000 */
23 	Rune1 = (1<<(Bit(0)+0*Bitx))-1,	/* 0000 0000 0000 0000 0111 1111 */
24 
25 	Maskx	= (1<<Bitx)-1,		/* 0011 1111 */
26 	Testx	= Maskx ^ 0xFF,		/* 1100 0000 */
27 
28 	SurrogateMin	= 0xD800,
29 	SurrogateMax	= 0xDFFF,
30 
31 	Bad	= Runeerror,
32 };
33 
34 Rune16*
35 runes16dup(Rune16 *r)
36 {
37 	int n;
38 	Rune16 *s;
39 
40 	n = runes16len(r) + 1;
41 	s = malloc(n * sizeof(Rune16));
42 	if(s == nil)
43 		error(Enomem);
44 	memmove(s, r, n * sizeof(Rune16));
45 	return s;
46 }
47 
48 int
49 runes16len(Rune16 *r)
50 {
51 	int n;
52 
53 	n = 0;
54 	while(*r++ != 0)
55 		n++;
56 	return n;
57 }
58 
59 char*
60 runes16toutf(char *p, Rune16 *r, int nc)
61 {
62 	char *op, *ep;
63 	int n, c;
64 	Rune rc;
65 
66 	op = p;
67 	ep = p + nc;
68 	while(c = *r++) {
69 		n = 1;
70 		if(c >= Runeself)
71 			n = runelen(c);
72 		if(p + n >= ep)
73 			break;
74 		rc = c;
75 		if(c < Runeself)
76 			*p++ = c;
77 		else
78 			p += runetochar(p, &rc);
79 	}
80 	*p = '\0';
81 	return op;
82 }
83 
84 int
85 rune16nlen(Rune16 *r, int nrune)
86 {
87 	int nb, i;
88 	Rune c;
89 
90 	nb = 0;
91 	while(nrune--) {
92 		c = *r++;
93 		if(c <= Rune1){
94 			nb++;
95 		} else {
96 			for(i = 2; i < UTFmax + 1; i++)
97 				if(c <= RuneX(i) || i == UTFmax){
98 					nb += i;
99 					break;
100 				}
101 		}
102 	}
103 	return nb;
104 }
105 
106 Rune16*
107 utftorunes16(Rune16 *r, char *p, int nc)
108 {
109 	Rune16 *or, *er;
110 	Rune rc;
111 
112 	or = r;
113 	er = r + nc;
114 	while(*p != '\0' && r + 1 < er){
115 		p += chartorune(&rc, p);
116 		*r++ = rc;	/* we'll ignore surrogate pairs */
117 	}
118 	*r = '\0';
119 	return or;
120 }
121 
122 int
123 runes16cmp(Rune16 *s1, Rune16 *s2)
124 {
125 	Rune16 r1, r2;
126 
127 	for(;;) {
128 		r1 = *s1++;
129 		r2 = *s2++;
130 		if(r1 != r2) {
131 			if(r1 > r2)
132 				return 1;
133 			return -1;
134 		}
135 		if(r1 == 0)
136 			return 0;
137 	}
138 }
139 
140 wchar_t *
141 widen(char *s)
142 {
143 	int n;
144 	wchar_t *ws;
145 
146 	n = utflen(s) + 1;
147 	ws = smalloc(n*sizeof(wchar_t));
148 	utftorunes16(ws, s, n);
149 	return ws;
150 }
151 
152 
153 char *
154 narrowen(wchar_t *ws)
155 {
156 	char *s;
157 	int n;
158 
159 	n = widebytes(ws);
160 	s = smalloc(n);
161 	runes16toutf(s, ws, n);
162 	return s;
163 }
164 
165 
166 int
167 widebytes(wchar_t *ws)
168 {
169 	int n = 0;
170 
171 	while (*ws)
172 		n += runelen(*ws++);
173 	return n+1;
174 }
175