首页 > 其他分享 >Json-Tutorial04 Unicode解析

Json-Tutorial04 Unicode解析

时间:2023-01-06 10:33:08浏览次数:56  
标签:0x3F Unicode PUTC Tutorial04 代理 Json 0x80 unicode 解析

前言

本节实际上做的工作是上一节的遗留工作:\u转义字符的解析。

UTF-8的解析规则

在本教程所设计的Json库中,只涉及UTF-8的解析。具体的解析规则教程中都已经说的非常清楚了,这里就不再赘述。值得注意的是包含高代理项和低代理项的情况。为什么会有高代理项和低代理项呢?因为咱们的unicode字符\uxxxx是一个4位的16进制数,而unicode的码点范围是0至0x10FFFF,显然一个unicode字符是无法表示所有的码点范围的。所以我们使用高代理项和低代理项两个unicode字符\uXXXX\uYYYY来表示U+FFFF以上的码点。具体计算的过程见Tutorial。写代码的时候,在解析完第一个unicode字符时,也需要注意下一个字符是不是unicode,如果是的话,需要按照高低代理项的计算规则一起计算出码点解析。

代码设计

1. 实现 lept_parse_hex4(),不合法的十六进位数返回 LEPT_PARSE_INVALID_UNICODE_HEX

这个函数只应负责解析4位的16进制数,如果后面还有字符,不用管,等下一次循环会解析。所以,我们只需要挨个解析4个字符就可以。如果遇到不是16进制的字符,直接返回NULL,表示解析失败。

static const char* lept_parse_hex4(const char* p, unsigned* u) {
    *u = 0;
    int i;
    for (i = 0; i < 4; i++) {
        switch (*p++) {
            case '0':
                *u = (*u << 4) | 0x0; break;
            case '1':
                *u = (*u << 4) | 0x1; break;
            case '2':
                *u = (*u << 4) | 0x2; break;
            case '3':
                *u = (*u << 4) | 0x3; break;
            case '4':
                *u = (*u << 4) | 0x4; break;
            case '5':
                *u = (*u << 4) | 0x5; break;
            case '6':
                *u = (*u << 4) | 0x6; break;
            case '7':
                *u = (*u << 4) | 0x7; break;
            case '8':
                *u = (*u << 4) | 0x8; break;
            case '9':
                *u = (*u << 4) | 0x9; break;
            case 'A':
            case 'a':
                *u = (*u << 4) | 0xA; break;
            case 'B':
            case 'b':
                *u = (*u << 4) | 0xB; break;
            case 'C':
            case 'c':
                *u = (*u << 4) | 0xC; break;
            case 'D':
            case 'd':
                *u = (*u << 4) | 0xD; break;
            case 'E':
            case 'e':
                *u = (*u << 4) | 0xE; break;
            case 'F':
            case 'f':
                *u = (*u << 4) | 0xF; break;
            default:
                return NULL;
        }
    }
    return p;
}

我这个是比较笨的版本,简洁明了的版本请移步tutorial。

2. 按第 3 节谈到的 UTF-8 编码原理,实现 lept_encode_utf8()

static void lept_encode_utf8(lept_context* c, unsigned u) {
    if (u <= 0x7F) {
        PUTC(c, u & 0x7F);
    } else if (u <= 0x7FF) {
        PUTC(c, 0xC0 | ((u >> 6) & 0x1F));
        PUTC(c, 0x80 | (u        & 0x3F));
    } else if (u <= 0xFFFF) {
        PUTC(c, 0xE0 | ((u >> 12) & 0xF));
        PUTC(c, 0x80 | ((u >> 6)  & 0x3F));
        PUTC(c, 0x80 | (u         & 0x3F));
    } else {
        assert(u <= 0x10FFFF);
        PUTC(c, 0xF0 | ((u >> 18) & 0x7));
        PUTC(c, 0x80 | ((u >> 12) & 0x3F));
        PUTC(c, 0x80 | ((u >> 6)  & 0x3F));
        PUTC(c, 0x80 | (u         & 0x3F));
    }
}

这里u是无符号数右移,左边最高位会补0,所以不需要像tutorial中把所有位都&上一遍1。其他的步骤就都跟UTF-8的编码完全吻合了。

3. 加入对代理对的处理,不正确的代理对范围要返回 LEPT_PARSE_INVALID_UNICODE_SURROGATE 错误

当我们解析出来的码点在0xDC00和0xDFFF之间时,说明这只是一个高代理项,还需要后面的一个低代理项才能计算出来真正的码点。
img

标签:0x3F,Unicode,PUTC,Tutorial04,代理,Json,0x80,unicode,解析
From: https://www.cnblogs.com/muuu520/p/17029718.html

相关文章

  • 4_jsonp跨域处理
    ​  jsonp跨域处理4.4.1什么是跨域?出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览......
  • 4_jsonp跨域处理
    ​  jsonp跨域处理4.4.1什么是跨域?出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览......
  • 4_JSON格式
    ​ AJAX数据格式处理响应普通文本数据如果服务器给我们响应的数据非常简答,那么使用字符串就好了,不需要我们做复杂的处理,后台编码也简单.页面代码 <%@pagecon......
  • 4_JSON格式
    ​ AJAX数据格式处理响应普通文本数据如果服务器给我们响应的数据非常简答,那么使用字符串就好了,不需要我们做复杂的处理,后台编码也简单.页面代码 <%@pagecon......
  • JAVA_Fastjson
    0x00前言Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和JavaObject之间互相转换。提供两个主要接口来分别实现序列化和反序列化操作......
  • mybatis使用postgresql中的jsonb数据类型
    最近新开发的一个功能使用到postgresql中的jsonb数据类型。架构师可能考虑到这种数据格式更加便于存储json格式的数据,因此考虑使用这种数据类型。自己以前未曾使用过这......
  • 封装HttpUtils类,根据实际业务返回值 封装JsonRootBean 对象
    packagecom.tf.jcfx.util;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importorg.apache.commons.logging.Log;......
  • Jmeter BeanShell处理JSON响应
    一:Json响应如下:二:添加beanshell后置处理器  三:Json处理代码如下:importcom.alibaba.fastjson.*;publicstaticStringline_code_list(Stringjson_text){  ......
  • 前端利用formData格式进行数据上传,前端formData 传值 和 json传值的区别?
    前端利用formData格式进行数据上传,前端formData传值和json传值的区别? contentType常见的格式text/plain:纯文本格式application/json:JSON数据格式application/......
  • JSON.stringify踩坑
    JSON.stringify将忽略所有未定义的对象属性。constuser={name:'Stanko',phone:undefined};user.phone;//->undefinedconststringifiedUser=JSON.stringi......