import t, c from stdint import * import memhub 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: memhub.MemManager | 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: memhub.MemManager | 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