예제 #1
0
def read_number(reader, ch):
    u"""用于读取数字内容,ch表示上一个被读取到的字符"""
    num_str = ch
    isfloat = False
    while reader.has_next():
        ch = reader.get_next()

        if ch.isspace():
            break
        # 读取到逗号,冒号或结束符('}', ']')需要回退一个位置,交给后面的方法处理
        elif ch in (',', ':', '}', ']'):
            reader.get_prev()
            break
        elif ch in ('e', '.'):
            isfloat = True
            num_str += ch
        elif ch.isdigit() or ch == '-':
            num_str += ch
        else:
            raise JsonFormatError("Invalid char when read number : %s" % ch)

    # 根据标记位进行对应转换
    try:
        if isfloat:
            return float(num_str)
        else:
            return int(num_str)
    except ValueError:
        log.warning("Json num format error, string:%s", string)
        raise JsonFormatError("Invalid num format, num string:%s" % string)
예제 #2
0
def _process_escape_char(reader, next_ch):
    u"""用于处理,并返回一个合法转义字符"""
    if next_ch == '"':
        escape_char = '"'
    elif next_ch == '\'':
        escape_char = '\''
    elif next_ch == 'n':
        escape_char = '\n'
    elif next_ch == 't':
        escape_char = '\t'
    elif next_ch == 'r':
        escape_char = '\r'
    elif next_ch == 'b':
        escape_char = '\b'
    elif next_ch == 'f':
        escape_char = '\f'
    elif next_ch == '\\':
        escape_char = '\\'
    elif next_ch == 'u':
        # 处理Unicode编码
        unicode_char = '\u'
        for i in range(4):
            ch = reader.get_next()
            if ch not in hexdigits:
                raise JsonFormatError("Invalid hex char : %s" % ch)
            unicode_char += ch
        escape_char = unicode_char.decode("raw_unicode_escape")
    else:
        raise JsonFormatError("Invalid escape char : %s" % next_ch)
    return escape_char
예제 #3
0
def read_array(reader):
    json_array = []
    while reader.has_next():
        ch = reader.get_next()
        if ch.isspace():
            continue
        if ch == ']':
            break

        # 前移一位,在read_value中获取值
        reader.get_prev()
        json_array.append(read_value(reader))

        # 读取下一个非空字符,判断是否 , 或者 ]
        non_space_char = read_non_space_char(reader)
        if non_space_char == ']':
            break
        elif non_space_char == ',':
            continue
        else:
            log.warning("Char after array value must be ',' or ']', ch:%s", ch)
            raise JsonFormatError(
                "Next char after array value must be ',' or ']', ch:%s" % ch)
    else:
        log.warning("Invalid json array format, lost ']'")
        raise JsonFormatError("Json array lost ']'")
    return json_array
예제 #4
0
def read_object(reader):
    json_obj = {}
    while reader.has_next():
        ch = reader.get_next()
        if ch.isspace():
            continue
        elif ch == '}':
            break

        # 按照 key , : , value顺序读取数据
        key = read_key(reader, ch)
        ch = read_non_space_char(reader)
        if ch != ":":
            raise JsonFormatError("After key must be colon ':'")
        value = read_value(reader)

        # 忽略非字符串类型的key
        if not isinstance(key, (str, unicode)):
            log.info("Key must be str, key:%s, ignore it.", key)
        else:
            json_obj[key] = value

        # 读取下一个非空字符,判断是否 , 或者 }
        non_space_char = read_non_space_char(reader)
        if non_space_char == '}':
            break
        elif non_space_char == ',':
            continue
        else:
            log.warning("Char after value must be ',' or '}'")
            raise JsonFormatError(
                "Char after value must be ',' or '}', ch:%s" % ch)
    else:
        log.warning("Invalid json obj format, lost '}'")
        raise JsonFormatError("Json obj lost '}'")
    return json_obj
예제 #5
0
def read_identifier(reader, identifier_chars, ret_val):
    u"""
    读取Json中的标识符,比如:null,则传入:('u', 'l', 'l'), None
    头一个字符可以忽略,因为头个字符在判断时已经被读取
    :param reader:
    :param identifier_chars:
    :param ret_val:
    :return:
    """
    length = len(identifier_chars)
    for i in range(length):
        ch = reader.get_next()
        if ch is None or ch != identifier_chars[i]:
            raise JsonFormatError("Invalid identifier value when read %s"
                                  % str(ret_val))
    else:
        return ret_val
예제 #6
0
def json_to_object(json):
    if not isinstance(json, (str, unicode)):
        log.debug("Argument type was not str, argument:%s", json)
        raise TypeError("Argument must be str type")

    json = json.strip()
    res_obj = None
    reader = StringReader(json)
    while reader.has_next():
        ch = reader.get_next()
        if ch == '{':
            res_obj = read_object(reader)
        elif ch == '[':
            res_obj = read_array(reader)
        else:
            log.debug("Invalid json format, json string should start with "
                      "start with '{' or '[', argument:%s", json)
            raise JsonFormatError("Json string must start with '{' or '['")
    return res_obj
예제 #7
0
def read_value(reader):
    while reader.has_next():
        ch = reader.get_next()
        if ch.isspace():
            continue
        elif ch == '"':
            return read_string(reader)
        elif ch == '-' or ch.isdigit():
            return read_number(reader, ch)
        elif ch in ('i',):
            return read_inf(reader)
        elif ch in ('n',):
            return read_null(reader)
        elif ch in ('t',):
            return read_true(reader)
        elif ch in ('f',):
            return read_false(reader)
        elif ch == '{':
            return read_object(reader)
        elif ch == '[':
            return read_array(reader)
        else:
            raise JsonFormatError("Invalid value format, read char:%s" % ch)
예제 #8
0
def read_key(reader, ch):
    if ch == '"':
        return read_string(reader)
    else:
        log.warning("Key must be string type")
        raise JsonFormatError("Invalid key type")