commit acf3cdc

default  ·  2023-11-17 02:51:04 +0000 UTC
parent 57ab8df
Backport from xs.
4 files changed,  +39, -11
M xs.h
M xs.h
+5, -2
 1@@ -1180,6 +1180,8 @@ void *xs_memmem(const char *haystack, int h_size, const char *needle, int n_size
 2 
 3 /** hex **/
 4 
 5+static char xs_hex_digits[] = "0123456789abcdef";
 6+
 7 xs_str *xs_hex_enc(const xs_val *data, int size)
 8 /* returns an hexdump of data */
 9 {
10@@ -1190,8 +1192,9 @@ xs_str *xs_hex_enc(const xs_val *data, int size)
11     p = s = xs_realloc(NULL, _xs_blk_size(size * 2 + 1));
12 
13     for (n = 0; n < size; n++) {
14-        snprintf(p, 3, "%02x", (unsigned char)data[n]);
15-        p += 2;
16+        *p++ = xs_hex_digits[*data >> 4 & 0xf];
17+        *p++ = xs_hex_digits[*data      & 0xf];
18+        data++;
19     }
20 
21     *p = '\0';
+4, -8
 1@@ -248,24 +248,20 @@ static xs_val *_xs_json_load_lexer(FILE *f, js_type *t)
 2                         break;
 3                     }
 4 
 5-                    if (cp >= 0xd800 && cp <= 0xdfff) {
 6-                        /* it's a surrogate pair */
 7-                        cp = (cp & 0x3ff) << 10;
 8-
 9+                    if (xs_is_surrogate(cp)) {
10                         /* \u must follow */
11                         if (fgetc(f) != '\\' || fgetc(f) != 'u') {
12                             *t = JS_ERROR;
13                             break;
14                         }
15 
16-                        unsigned int i;
17-                        if (fscanf(f, "%04x", &i) != 1) {
18+                        unsigned int p2;
19+                        if (fscanf(f, "%04x", &p2) != 1) {
20                             *t = JS_ERROR;
21                             break;
22                         }
23 
24-                        cp |= (i & 0x3ff);
25-                        cp += 0x10000;
26+                        cp = xs_surrogate_dec(cp, p2);
27                     }
28 
29                     /* replace dangerous control codes with their visual representations */
+29, -0
 1@@ -8,6 +8,9 @@
 2  xs_str *xs_utf8_enc(xs_str *str, unsigned int cpoint);
 3  unsigned int xs_utf8_dec(char **str);
 4  int xs_unicode_width(unsigned int cpoint);
 5+ int xs_is_surrogate(unsigned int cpoint);
 6+ unsigned int xs_surrogate_dec(unsigned int p1, unsigned int p2);
 7+ unsigned int xs_surrogate_enc(unsigned int cpoint);
 8  unsigned int *_xs_unicode_upper_search(unsigned int cpoint);
 9  unsigned int *_xs_unicode_lower_search(unsigned int cpoint);
10  #define xs_unicode_is_upper(cpoint) (!!_xs_unicode_upper_search(cpoint))
11@@ -138,6 +141,32 @@ int xs_unicode_width(unsigned int cpoint)
12 }
13 
14 
15+/** surrogate pairs **/
16+
17+int xs_is_surrogate(unsigned int cpoint)
18+/* checks if cpoint is the first element of a Unicode surrogate pair */
19+{
20+    return cpoint >= 0xd800 && cpoint <= 0xdfff;
21+}
22+
23+
24+unsigned int xs_surrogate_dec(unsigned int p1, unsigned int p2)
25+/* "decodes" a surrogate pair into a codepoint */
26+{
27+    return 0x10000 | ((p1 & 0x3ff) << 10) | (p2 & 0x3ff);
28+}
29+
30+
31+unsigned int xs_surrogate_enc(unsigned int cpoint)
32+/* "encodes" a Unicode into a surrogate pair (p1 in the MSB word) */
33+{
34+    unsigned int p1 = 0xd7c0 + (cpoint >> 10);
35+    unsigned int p2 = 0xdc00 + (cpoint & 0x3ff);
36+
37+    return (p1 << 16) | p2;
38+}
39+
40+
41 #ifdef _XS_UNICODE_TBL_H
42 
43 /* include xs_unicode_tbl.h before this one to use these functions */
+1, -1
1@@ -1 +1 @@
2-/* 40d63c59610c642d1c8b2e2b94bbf5cdde69ad6a */
3+/* 0932615dfe85e5d8544c4b2052eb66f3a430eb8c */