** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. */
| 38 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. |
| 39 | */ |
| 40 | static const char *utf8_decode (const char *o, int *val) { |
| 41 | static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; |
| 42 | const unsigned char *s = (const unsigned char *)o; |
| 43 | unsigned int c = s[0]; |
| 44 | unsigned int res = 0; /* final result */ |
| 45 | if (c < 0x80) /* ascii? */ |
| 46 | res = c; |
| 47 | else { |
| 48 | int count = 0; /* to count number of continuation bytes */ |
| 49 | while (c & 0x40) { /* still have continuation bytes? */ |
| 50 | int cc = s[++count]; /* read next byte */ |
| 51 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ |
| 52 | return NULL; /* invalid byte sequence */ |
| 53 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ |
| 54 | c <<= 1; /* to test next bit */ |
| 55 | } |
| 56 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ |
| 57 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) |
| 58 | return NULL; /* invalid byte sequence */ |
| 59 | s += count; /* skip continuation bytes read */ |
| 60 | } |
| 61 | if (val) *val = res; |
| 62 | return (const char *)s + 1; /* +1 to include first byte */ |
| 63 | } |
| 64 | |
| 65 | |
| 66 | /* |