24 static void CharToHex(
unsigned char c,
char * hexBuf)
26 const char * hexchar =
"0123456789ABCDEF";
27 hexBuf[0] = hexchar[c >> 4];
28 hexBuf[1] = hexchar[c & 0x0F];
34 const unsigned char *
str,
41 hexBuf[0] =
'\\'; hexBuf[1] =
'u'; hexBuf[2] =
'0'; hexBuf[3] =
'0';
45 const char * escaped =
NULL;
47 case '\r': escaped =
"\\r";
break;
48 case '\n': escaped =
"\\n";
break;
49 case '\\': escaped =
"\\\\";
break;
55 case '/':
if (escape_solidus) escaped =
"\\/";
break;
56 case '"': escaped =
"\\\"";
break;
57 case '\f': escaped =
"\\f";
break;
58 case '\b': escaped =
"\\b";
break;
59 case '\t': escaped =
"\\t";
break;
61 if ((
unsigned char) str[end] < 32) {
62 CharToHex(str[end], hexBuf + 4);
67 if (escaped !=
NULL) {
68 print(ctx, (
const char *) (str + beg), end - beg);
69 print(ctx, escaped, (
unsigned int)strlen(escaped));
75 print(ctx, (
const char *) (str + beg), end - beg);
78 static void hexToDigit(
unsigned int * val,
const unsigned char *
hex)
82 unsigned char c = hex[
i];
83 if (c >=
'A') c = (c & ~0x20) - 7;
86 *val = (*val << 4) | c;
90 static void Utf32toUtf8(
unsigned int codepoint,
char * utf8Buf)
92 if (codepoint < 0x80) {
93 utf8Buf[0] = (char) codepoint;
95 }
else if (codepoint < 0x0800) {
96 utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0);
97 utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80);
99 }
else if (codepoint < 0x10000) {
100 utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0);
101 utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80);
102 utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80);
104 }
else if (codepoint < 0x200000) {
105 utf8Buf[0] =(char)((codepoint >> 18) | 0xF0);
106 utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80);
107 utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80);
108 utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80);
123 if (str[end] ==
'\\') {
125 const char * unescaped =
"?";
127 switch (str[++end]) {
128 case 'r': unescaped =
"\r";
break;
129 case 'n': unescaped =
"\n";
break;
130 case '\\': unescaped =
"\\";
break;
131 case '/': unescaped =
"/";
break;
132 case '"': unescaped =
"\"";
break;
133 case 'f': unescaped =
"\f";
break;
134 case 'b': unescaped =
"\b";
break;
135 case 't': unescaped =
"\t";
break;
137 unsigned int codepoint = 0;
138 hexToDigit(&codepoint, str + ++end);
141 if ((codepoint & 0xFC00) == 0xD800) {
143 if (str[end] ==
'\\' && str[end + 1] ==
'u') {
144 unsigned int surrogate = 0;
145 hexToDigit(&surrogate, str + end + 2);
147 (((codepoint & 0x3F) << 10) |
148 ((((codepoint >> 6) & 0xF) + 1) << 16) |
149 (surrogate & 0x3FF));
157 Utf32toUtf8(codepoint, utf8Buf);
160 if (codepoint == 0) {
180 #define ADV_PTR s++; if (!(len--)) return 0; 193 else if ((*s >> 5) == 0x6) {
195 if (!((*s >> 6) == 0x2))
return 0;
198 else if ((*s >> 4) == 0x0e) {
200 if (!((*s >> 6) == 0x2))
return 0;
202 if (!((*s >> 6) == 0x2))
return 0;
205 else if ((*s >> 3) == 0x1e) {
207 if (!((*s >> 6) == 0x2))
return 0;
209 if (!((*s >> 6) == 0x2))
return 0;
211 if (!((*s >> 6) == 0x2))
return 0;
int yajl_string_validate_utf8(const unsigned char *s, size_t len)
#define assert(exp)
Declare that a condition should be true.
void yajl_buf_append(yajl_buf buf, const void *data, size_t len)
void(* yajl_print_t)(void *ctx, const char *str, size_t len)
void yajl_string_encode(const yajl_print_t print, void *ctx, const unsigned char *str, size_t len, int escape_solidus)
void yajl_string_decode(yajl_buf buf, const unsigned char *str, size_t len)