补充
This commit is contained in:
119
includes/json/__writer.py
Normal file
119
includes/json/__writer.py
Normal file
@@ -0,0 +1,119 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import mpool
|
||||
import string
|
||||
from stdio import snprintf
|
||||
from . import (
|
||||
JsonValue, JSON_NULL, JSON_BOOL, JSON_INT, JSON_FLOAT,
|
||||
JSON_STRING, JSON_ARRAY, JSON_OBJECT,
|
||||
)
|
||||
|
||||
|
||||
def _write_char(buf: t.CChar | t.CPtr, pos: t.CSizeT, ch: t.CChar) -> t.CSizeT:
|
||||
buf[pos] = ch
|
||||
return pos + 1
|
||||
|
||||
def _write_str(buf: t.CChar | t.CPtr, pos: t.CSizeT, s: t.CChar | t.CPtr) -> t.CSizeT:
|
||||
if s == None: return pos
|
||||
slen: t.CSizeT = string.strlen(s)
|
||||
string.memcpy(t.CChar(t.CUInt64T(buf) + pos, t.CPtr), s, slen)
|
||||
return pos + slen
|
||||
|
||||
def _write_string_escaped(buf: t.CChar | t.CPtr, pos: t.CSizeT, s: t.CChar | t.CPtr) -> t.CSizeT:
|
||||
if s == None:
|
||||
pos = _write_str(buf, pos, "null")
|
||||
return pos
|
||||
pos = _write_char(buf, pos, '"')
|
||||
i: t.CSizeT = 0
|
||||
slen: t.CSizeT = string.strlen(s)
|
||||
while i < slen:
|
||||
ch: t.CChar = s[i]
|
||||
if ch == '"':
|
||||
pos = _write_str(buf, pos, "\\\"")
|
||||
elif ch == '\\':
|
||||
pos = _write_str(buf, pos, "\\\\")
|
||||
elif ch == '\n':
|
||||
pos = _write_str(buf, pos, "\\n")
|
||||
elif ch == '\r':
|
||||
pos = _write_str(buf, pos, "\\r")
|
||||
elif ch == '\t':
|
||||
pos = _write_str(buf, pos, "\\t")
|
||||
else:
|
||||
pos = _write_char(buf, pos, ch)
|
||||
i += 1
|
||||
pos = _write_char(buf, pos, '"')
|
||||
return pos
|
||||
|
||||
|
||||
def _write_value(buf: t.CChar | t.CPtr, pos: t.CSizeT, val: JsonValue | t.CPtr, pool: mpool.MPool | t.CPtr) -> t.CSizeT:
|
||||
if val == None:
|
||||
pos = _write_str(buf, pos, "null")
|
||||
return pos
|
||||
|
||||
if val.vtype == JSON_NULL:
|
||||
pos = _write_str(buf, pos, "null")
|
||||
|
||||
elif val.vtype == JSON_BOOL:
|
||||
if val.bool_val != 0:
|
||||
pos = _write_str(buf, pos, "true")
|
||||
else:
|
||||
pos = _write_str(buf, pos, "false")
|
||||
|
||||
elif val.vtype == JSON_INT:
|
||||
tmp: t.CChar | t.CPtr = pool.alloc(32)
|
||||
if tmp != None:
|
||||
snprintf(tmp, 32, "%lld", val.int_val)
|
||||
pos = _write_str(buf, pos, tmp)
|
||||
|
||||
elif val.vtype == JSON_FLOAT:
|
||||
tmp2: t.CChar | t.CPtr = pool.alloc(32)
|
||||
if tmp2 != None:
|
||||
snprintf(tmp2, 32, "%.6g", val.float_val)
|
||||
pos = _write_str(buf, pos, tmp2)
|
||||
|
||||
elif val.vtype == JSON_STRING:
|
||||
pos = _write_string_escaped(buf, pos, val.str_val)
|
||||
|
||||
elif val.vtype == JSON_ARRAY:
|
||||
if val.child == None:
|
||||
pos = _write_str(buf, pos, "[]")
|
||||
return pos
|
||||
pos = _write_char(buf, pos, '[')
|
||||
cur: JsonValue | t.CPtr = val.child
|
||||
first: bool = True
|
||||
while cur != None:
|
||||
if not first:
|
||||
pos = _write_char(buf, pos, ',')
|
||||
pos = _write_value(buf, pos, cur, pool)
|
||||
first = False
|
||||
cur = cur.next
|
||||
pos = _write_char(buf, pos, ']')
|
||||
|
||||
elif val.vtype == JSON_OBJECT:
|
||||
if val.child == None:
|
||||
pos = _write_str(buf, pos, "{}")
|
||||
return pos
|
||||
pos = _write_char(buf, pos, '{')
|
||||
cur2: JsonValue | t.CPtr = val.child
|
||||
first2: bool = True
|
||||
while cur2 != None:
|
||||
if not first2:
|
||||
pos = _write_char(buf, pos, ',')
|
||||
pos = _write_string_escaped(buf, pos, cur2.key)
|
||||
pos = _write_char(buf, pos, ':')
|
||||
pos = _write_value(buf, pos, cur2, pool)
|
||||
first2 = False
|
||||
cur2 = cur2.next
|
||||
pos = _write_char(buf, pos, '}')
|
||||
|
||||
return pos
|
||||
|
||||
|
||||
def write(pool: mpool.MPool | t.CPtr, val: JsonValue | t.CPtr, pretty: bool) -> t.CChar | t.CPtr:
|
||||
"""将 JsonValue 序列化为 JSON 字符串"""
|
||||
buf: t.CChar | t.CPtr = pool.alloc(4096)
|
||||
if buf == None:
|
||||
return None
|
||||
end_pos: t.CSizeT = _write_value(buf, 0, val, pool)
|
||||
buf[end_pos] = '\0'
|
||||
return buf
|
||||
Reference in New Issue
Block a user