Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
int
4
fz_is_big_endian(void)
5
{
6
	static const int one = 1;
7
	return *(char*)&one == 0;
8
}
9
 
10
char *
11
fz_strsep(char **stringp, const char *delim)
12
{
13
	char *ret = *stringp;
14
	if (ret == NULL) return NULL;
15
	if ((*stringp = strpbrk(*stringp, delim)) != NULL)
16
		*((*stringp)++) = '\0';
17
	return ret;
18
}
19
 
20
int
21
fz_strlcpy(char *dst, const char *src, int siz)
22
{
23
	register char *d = dst;
24
	register const char *s = src;
25
	register int n = siz;
26
 
27
	/* Copy as many bytes as will fit */
28
	if (n != 0 && --n != 0) {
29
		do {
30
			if ((*d++ = *s++) == 0)
31
				break;
32
		} while (--n != 0);
33
	}
34
 
35
	/* Not enough room in dst, add NUL and traverse rest of src */
36
	if (n == 0) {
37
		if (siz != 0)
38
			*d = '\0';		/* NUL-terminate dst */
39
			while (*s++)
40
				;
41
	}
42
 
43
	return(s - src - 1);	/* count does not include NUL */
44
}
45
 
46
int
47
fz_strlcat(char *dst, const char *src, int siz)
48
{
49
	register char *d = dst;
50
	register const char *s = src;
51
	register int n = siz;
52
	int dlen;
53
 
54
	/* Find the end of dst and adjust bytes left but don't go past end */
55
	while (*d != '\0' && n-- != 0)
56
		d++;
57
	dlen = d - dst;
58
	n = siz - dlen;
59
 
60
	if (n == 0)
61
		return dlen + strlen(s);
62
	while (*s != '\0') {
63
		if (n != 1) {
64
			*d++ = *s;
65
			n--;
66
		}
67
		s++;
68
	}
69
	*d = '\0';
70
 
71
	return dlen + (s - src);	/* count does not include NUL */
72
}
73
 
74
enum
75
{
76
	UTFmax = 4, /* maximum bytes per rune */
77
	Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
78
	Runeself = 0x80, /* rune and UTF sequences are the same (<) */
79
	Runeerror = 0xFFFD, /* decoding error in UTF */
80
	Runemax = 0x10FFFF, /* maximum rune value */
81
};
82
 
83
enum
84
{
85
	Bit1 = 7,
86
	Bitx = 6,
87
	Bit2 = 5,
88
	Bit3 = 4,
89
	Bit4 = 3,
90
	Bit5 = 2,
91
 
92
	T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
93
	Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
94
	T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
95
	T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
96
	T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
97
	T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */
98
 
99
	Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
100
	Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
101
	Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
102
	Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0001 1111 1111 1111 1111 1111 */
103
 
104
	Maskx = (1<
105
	Testx = Maskx ^ 0xFF,	/* 1100 0000 */
106
 
107
	Bad = Runeerror,
108
};
109
 
110
int
111
chartorune(int *rune, char *str)
112
{
113
	int c, c1, c2, c3;
114
	long l;
115
 
116
	/*
117
	 * one character sequence
118
	 *	00000-0007F => T1
119
	 */
120
	c = *(unsigned char*)str;
121
	if(c < Tx) {
122
		*rune = c;
123
		return 1;
124
	}
125
 
126
	/*
127
	 * two character sequence
128
	 *	0080-07FF => T2 Tx
129
	 */
130
	c1 = *(unsigned char*)(str+1) ^ Tx;
131
	if(c1 & Testx)
132
		goto bad;
133
	if(c < T3) {
134
		if(c < T2)
135
			goto bad;
136
		l = ((c << Bitx) | c1) & Rune2;
137
		if(l <= Rune1)
138
			goto bad;
139
		*rune = l;
140
		return 2;
141
	}
142
 
143
	/*
144
	 * three character sequence
145
	 *	0800-FFFF => T3 Tx Tx
146
	 */
147
	c2 = *(unsigned char*)(str+2) ^ Tx;
148
	if(c2 & Testx)
149
		goto bad;
150
	if(c < T4) {
151
		l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
152
		if(l <= Rune2)
153
			goto bad;
154
		*rune = l;
155
		return 3;
156
	}
157
 
158
	/*
159
	 * four character sequence (21-bit value)
160
	 *	10000-1FFFFF => T4 Tx Tx Tx
161
	 */
162
	c3 = *(unsigned char*)(str+3) ^ Tx;
163
	if (c3 & Testx)
164
		goto bad;
165
	if (c < T5) {
166
		l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
167
		if (l <= Rune3)
168
			goto bad;
169
		*rune = l;
170
		return 4;
171
	}
172
	/*
173
	 * Support for 5-byte or longer UTF-8 would go here, but
174
	 * since we don't have that, we'll just fall through to bad.
175
	 */
176
 
177
	/*
178
	 * bad decoding
179
	 */
180
bad:
181
	*rune = Bad;
182
	return 1;
183
}
184
 
185
int
186
runetochar(char *str, int *rune)
187
{
188
	/* Runes are signed, so convert to unsigned for range check. */
189
	unsigned long c;
190
 
191
	/*
192
	 * one character sequence
193
	 *	00000-0007F => 00-7F
194
	 */
195
	c = *rune;
196
	if(c <= Rune1) {
197
		str[0] = c;
198
		return 1;
199
	}
200
 
201
	/*
202
	 * two character sequence
203
	 *	0080-07FF => T2 Tx
204
	 */
205
	if(c <= Rune2) {
206
		str[0] = T2 | (c >> 1*Bitx);
207
		str[1] = Tx | (c & Maskx);
208
		return 2;
209
	}
210
 
211
	/*
212
	 * If the Rune is out of range, convert it to the error rune.
213
	 * Do this test here because the error rune encodes to three bytes.
214
	 * Doing it earlier would duplicate work, since an out of range
215
	 * Rune wouldn't have fit in one or two bytes.
216
	 */
217
	if (c > Runemax)
218
		c = Runeerror;
219
 
220
	/*
221
	 * three character sequence
222
	 *	0800-FFFF => T3 Tx Tx
223
	 */
224
	if (c <= Rune3) {
225
		str[0] = T3 | (c >> 2*Bitx);
226
		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
227
		str[2] = Tx | (c & Maskx);
228
		return 3;
229
	}
230
 
231
	/*
232
	 * four character sequence (21-bit value)
233
	 *	10000-1FFFFF => T4 Tx Tx Tx
234
	 */
235
	str[0] = T4 | (c >> 3*Bitx);
236
	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
237
	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
238
	str[3] = Tx | (c & Maskx);
239
	return 4;
240
}
241
 
242
int
243
runelen(int c)
244
{
245
	char str[10];
246
	return runetochar(str, &c);
247
}
248
 
249
float fz_atof(const char *s)
250
{
251
	double d;
252
 
253
	/* The errno voodoo here checks for us reading numbers that are too
254
	 * big to fit into a double. The checks for FLT_MAX ensure that we
255
	 * don't read a number that's OK as a double and then become invalid
256
	 * as we convert to a float. */
257
	errno = 0;
258
	d = strtod(s, NULL);
259
	if (errno == ERANGE || d > FLT_MAX || d < -FLT_MAX) {
260
		/* Return 1.0, as it's a small known value that won't cause a
261
		 * divide by 0. */
262
		return 1.0;
263
	}
264
	return (float)d;
265
}