]>
Dogcows Code - chaz/yoink/blob - src/yajl_encode.c
2 * Copyright 2007-2009, Lloyd Hilaiel.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. Neither the name of Lloyd Hilaiel nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include "yajl_encode.h"
40 static void CharToHex(unsigned char c
, char * hexBuf
)
42 const char * hexchar
= "0123456789ABCDEF";
43 hexBuf
[0] = hexchar
[c
>> 4];
44 hexBuf
[1] = hexchar
[c
& 0x0F];
48 yajl_string_encode(yajl_buf buf
, const unsigned char * str
,
54 hexBuf
[0] = '\\'; hexBuf
[1] = 'u'; hexBuf
[2] = '0'; hexBuf
[3] = '0';
58 const char * escaped
= NULL
;
60 case '\r': escaped
= "\\r"; break;
61 case '\n': escaped
= "\\n"; break;
62 case '\\': escaped
= "\\\\"; break;
63 /* case '/': escaped = "\\/"; break; */
64 case '"': escaped
= "\\\""; break;
65 case '\f': escaped
= "\\f"; break;
66 case '\b': escaped
= "\\b"; break;
67 case '\t': escaped
= "\\t"; break;
69 if ((unsigned char) str
[end
] < 32) {
70 CharToHex(str
[end
], hexBuf
+ 4);
75 if (escaped
!= NULL
) {
76 yajl_buf_append(buf
, str
+ beg
, end
- beg
);
77 yajl_buf_append(buf
, escaped
, strlen(escaped
));
83 yajl_buf_append(buf
, str
+ beg
, end
- beg
);
86 static void hexToDigit(unsigned int * val
, const unsigned char * hex
)
90 unsigned char c
= hex
[i
];
91 if (c
>= 'A') c
= (c
& ~0x20) - 7;
94 *val
= (*val
<< 4) | c
;
98 static void Utf32toUtf8(unsigned int codepoint
, char * utf8Buf
)
100 if (codepoint
< 0x80) {
101 utf8Buf
[0] = (char) codepoint
;
103 } else if (codepoint
< 0x0800) {
104 utf8Buf
[0] = (char) ((codepoint
>> 6) | 0xC0);
105 utf8Buf
[1] = (char) ((codepoint
& 0x3F) | 0x80);
107 } else if (codepoint
< 0x10000) {
108 utf8Buf
[0] = (char) ((codepoint
>> 12) | 0xE0);
109 utf8Buf
[1] = (char) (((codepoint
>> 6) & 0x3F) | 0x80);
110 utf8Buf
[2] = (char) ((codepoint
& 0x3F) | 0x80);
112 } else if (codepoint
< 0x200000) {
113 utf8Buf
[0] =(char)((codepoint
>> 18) | 0xF0);
114 utf8Buf
[1] =(char)(((codepoint
>> 12) & 0x3F) | 0x80);
115 utf8Buf
[2] =(char)(((codepoint
>> 6) & 0x3F) | 0x80);
116 utf8Buf
[3] =(char)((codepoint
& 0x3F) | 0x80);
124 void yajl_string_decode(yajl_buf buf
, const unsigned char * str
,
127 unsigned int beg
= 0;
128 unsigned int end
= 0;
131 if (str
[end
] == '\\') {
133 const char * unescaped
= "?";
134 yajl_buf_append(buf
, str
+ beg
, end
- beg
);
135 switch (str
[++end
]) {
136 case 'r': unescaped
= "\r"; break;
137 case 'n': unescaped
= "\n"; break;
138 case '\\': unescaped
= "\\"; break;
139 case '/': unescaped
= "/"; break;
140 case '"': unescaped
= "\""; break;
141 case 'f': unescaped
= "\f"; break;
142 case 'b': unescaped
= "\b"; break;
143 case 't': unescaped
= "\t"; break;
145 unsigned int codepoint
= 0;
146 hexToDigit(&codepoint
, str
+ ++end
);
148 /* check if this is a surrogate */
149 if ((codepoint
& 0xFC00) == 0xD800) {
151 if (str
[end
] == '\\' && str
[end
+ 1] == 'u') {
152 unsigned int surrogate
= 0;
153 hexToDigit(&surrogate
, str
+ end
+ 2);
155 (((codepoint
& 0x3F) << 10) |
156 ((((codepoint
>> 6) & 0xF) + 1) << 16) |
157 (surrogate
& 0x3FF));
165 Utf32toUtf8(codepoint
, utf8Buf
);
170 assert("this should never happen" == NULL
);
172 yajl_buf_append(buf
, unescaped
, strlen(unescaped
));
178 yajl_buf_append(buf
, str
+ beg
, end
- beg
);
This page took 0.039431 seconds and 4 git commands to generate.