import t, c import memhub import string import json from stdint import * # Variant 类型标签 (与 _variant.py 保持一致) VARIANT_NONE: t.CDefine = 0 # 无类型/空值 VARIANT_INT: t.CDefine = 1 # int (i64) VARIANT_FLOAT: t.CDefine = 2 # float (f32) VARIANT_DOUBLE: t.CDefine = 3 # double (f64) VARIANT_STR: t.CDefine = 4 # str (i8*) VARIANT_DICT: t.CDefine = 5 # dict* VARIANT_LIST: t.CDefine = 6 # list* VARIANT_BOOL: t.CDefine = 7 # bool (i1/i32) VARIANT_PTR: t.CDefine = 8 # 自定义指针类型 # Variant 结构体大小: vtype(i32, 4 bytes) + padding(4 bytes) + ptr(i8*, 8 bytes) = 16 bytes _VARIANT_SIZE: t.CDefine = 16 class dict: """堆上动态字典容器,基于 mbuddy 分配器。 键类型固定为 str (i8*),值使用 Variant 存储 (类型标签 + 无类型指针)。 支持嵌套 dict/list 和 JSON 序列化。 用法: mb: memhub.MemBuddy = memhub.MemBuddy(arena, arena_size) d: dict = dict(mb) d.set_int("x", 42) p: t.CPtr = d["x"] v: int = c.Deref(p) # 嵌套 dict inner: dict = dict(mb) inner.set_int("a", 1) d.set_dict("sub", inner) sub: dict = c.Deref(d["sub"]) av: int = c.Deref(sub["a"]) """ __keys__: t.CPtr __values__: t.CPtr __count__: t.CSizeT = 0 __capacity__: t.CSizeT = 8 __mbuddy__: memhub.MemBuddy | t.CPtr __iter_index__: t.CSizeT = 0 def __new__(self, mb: memhub.MemBuddy | t.CPtr) -> t.CPtr: # 堆分配 dict 对象 return mb.alloc(dict.__sizeof__()) def __init__(self, mb: memhub.MemBuddy | t.CPtr): self.__mbuddy__ = mb self.__keys__ = mb.alloc(self.__capacity__ * 8) self.__values__ = mb.alloc(self.__capacity__ * _VARIANT_SIZE) def __len__(self) -> t.CSizeT: return self.__count__ def _find(self, key: str) -> t.CSizeT: """查找 key 的索引,找不到返回 __count__""" for i in range(self.__count__): key_ptr: str | t.CPtr = t.CPtr(t.CUInt64T(self.__keys__) + i * 8) if key_ptr[0] == key: return i return self.__count__ def __getitem__(self, key: str) -> t.CPtr: """返回值的无类型指针。用户用 c.Deref 解引用获取实际值。 例: p: t.CPtr = d["x"]; v: int = c.Deref(p)""" idx: t.CSizeT = self._find(key) if idx >= self.__count__: return None # Variant.ptr 在 Variant 结构体偏移 8 处 val_ptr: str | t.CPtr = t.CPtr(t.CUInt64T(self.__values__) + idx * _VARIANT_SIZE + 8) return val_ptr[0] def __setitem__(self, key: str, val: t.CNeedPtr): """存储值为 VARIANT_PTR。val 自动取地址 (t.CNeedPtr)。 注意: val 指向的值生命周期由调用者管理。 如需持久存储,请使用 set_int / set_str 等类型化方法。""" self._set_variant_raw(key, VARIANT_PTR, val) def _set_variant_raw(self, key: str, vtype: t.CInt, ptr: t.CPtr): """内部方法: 存储 Variant (vtype + ptr)。不自动取地址。""" idx: t.CSizeT = self._find(key) if idx < self.__count__: # 更新已有键 vtype_ptr: t.CInt | t.CPtr = t.CPtr(t.CUInt64T(self.__values__) + idx * _VARIANT_SIZE) vtype_ptr[0] = vtype val_ptr: str | t.CPtr = t.CPtr(t.CUInt64T(self.__values__) + idx * _VARIANT_SIZE + 8) val_ptr[0] = ptr return if self.__count__ >= self.__capacity__: new_cap: t.CSizeT = self.__capacity__ * 2 new_keys: t.CPtr = self.__mbuddy__.alloc(new_cap * 8) new_values: t.CPtr = self.__mbuddy__.alloc(new_cap * _VARIANT_SIZE) if new_keys is None or new_values is None: return string.memcpy(new_keys, self.__keys__, self.__count__ * 8) string.memcpy(new_values, self.__values__, self.__count__ * _VARIANT_SIZE) self.__keys__ = new_keys self.__values__ = new_values self.__capacity__ = new_cap key_ptr: str | t.CPtr = t.CPtr(t.CUInt64T(self.__keys__) + self.__count__ * 8) key_ptr[0] = key vtype_ptr: t.CInt | t.CPtr = t.CPtr(t.CUInt64T(self.__values__) + self.__count__ * _VARIANT_SIZE) vtype_ptr[0] = vtype val_ptr: str | t.CPtr = t.CPtr(t.CUInt64T(self.__values__) + self.__count__ * _VARIANT_SIZE + 8) val_ptr[0] = ptr self.__count__ += 1 # ============================================================ # 类型化 setter — 在 __mbuddy__ 中分配持久存储 # ============================================================ def set_int(self, key: str, val: int): """存储 int 值 (VARIANT_INT)。值复制到 __mbuddy__ 持久存储。""" storage: t.CPtr = self.__mbuddy__.alloc(8) int_ptr: int | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) int_ptr[0] = val self._set_variant_raw(key, VARIANT_INT, storage) def set_str(self, key: str, val: str): """存储 str 值 (VARIANT_STR)。直接存储字符串指针。""" self._set_variant_raw(key, VARIANT_STR, val) def set_float(self, key: str, val: float): """存储 float 值 (VARIANT_FLOAT)。值复制到 __mbuddy__ 持久存储。""" storage: t.CPtr = self.__mbuddy__.alloc(8) float_ptr: float | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) float_ptr[0] = val self._set_variant_raw(key, VARIANT_FLOAT, storage) def set_double(self, key: str, val: t.CDouble): """存储 double 值 (VARIANT_DOUBLE)。值复制到 __mbuddy__ 持久存储。""" storage: t.CPtr = self.__mbuddy__.alloc(8) dbl_ptr: t.CDouble | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) dbl_ptr[0] = val self._set_variant_raw(key, VARIANT_DOUBLE, storage) def set_dict(self, key: str, val: dict | t.CPtr): """存储嵌套 dict 指针 (VARIANT_DICT)。""" self._set_variant_raw(key, VARIANT_DICT, val) def set_list(self, key: str, val: t.CPtr): """存储嵌套 list 指针 (VARIANT_LIST)。""" self._set_variant_raw(key, VARIANT_LIST, val) def set_bool(self, key: str, val: t.CInt): """存储 bool 值 (VARIANT_BOOL)。值复制到 __mbuddy__ 持久存储。""" storage: t.CPtr = self.__mbuddy__.alloc(8) bool_ptr: t.CInt | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) bool_ptr[0] = val self._set_variant_raw(key, VARIANT_BOOL, storage) # ============================================================ # 查询方法 # ============================================================ def get_vtype(self, key: str) -> t.CInt: """返回 key 对应值的 Variant 类型标签。""" idx: t.CSizeT = self._find(key) if idx >= self.__count__: return VARIANT_NONE vtype_ptr: t.CInt | t.CPtr = t.CVoid(t.CUInt64T(self.__values__) + idx * _VARIANT_SIZE, t.CPtr) return vtype_ptr[0] def get(self, key: str, default: t.CPtr) -> t.CPtr: """返回值指针,不存在则返回 default。""" idx: t.CSizeT = self._find(key) if idx >= self.__count__: return default val_ptr: str | t.CPtr = t.CVoid(t.CUInt64T(self.__values__) + idx * _VARIANT_SIZE + 8, t.CPtr) return val_ptr[0] def contains(self, key: str) -> t.CInt: """检查 key 是否存在。""" idx: t.CSizeT = self._find(key) if idx < self.__count__: return 1 return 0 def __iter__(self) -> dict | t.CPtr: self.__iter_index__ = 0 return self def __next__(self) -> str: if self.__iter_index__ >= self.__count__: raise StopIteration idx: t.CSizeT = self.__iter_index__ self.__iter_index__ = idx + 1 key_ptr: str | t.CPtr = t.CVoid(t.CUInt64T(self.__keys__) + idx * 8, t.CPtr) return key_ptr[0] # ============================================================ # JSON 处理:利用 includes/json 库实现序列化/反序列化 # ============================================================ def to_json(self, pool: memhub.MemManager | t.CPtr) -> json.JsonValue | t.CPtr: """将 dict 转换为 JsonValue 对象 (JSON_OBJECT)。 根据 Variant 类型标签自动选择合适的 JSON 值类型。""" obj: json.JsonValue | t.CPtr = json.object(pool) i: t.CSizeT = 0 while i < self.__count__: key_ptr: str | t.CPtr = t.CVoid(t.CUInt64T(self.__keys__) + i * 8, t.CPtr) vtype_ptr: t.CInt | t.CPtr = t.CVoid(t.CUInt64T(self.__values__) + i * _VARIANT_SIZE, t.CPtr) val_ptr: str | t.CPtr = t.CVoid(t.CUInt64T(self.__values__) + i * _VARIANT_SIZE + 8, t.CPtr) vt: t.CInt = vtype_ptr[0] vp: t.CPtr = val_ptr[0] jv: json.JsonValue | t.CPtr = json.null(pool) if jv != None: if vt == VARIANT_INT: jv.vtype = 2 # JSON_INT ip: int | t.CPtr = t.CVoid(t.CUInt64T(vp), t.CPtr) jv.int_val = ip[0] elif vt == VARIANT_STR: jv.vtype = 4 # JSON_STRING jv.str_val = vp elif vt == VARIANT_BOOL: jv.vtype = 1 # JSON_BOOL bp: t.CInt | t.CPtr = t.CVoid(t.CUInt64T(vp), t.CPtr) jv.bool_val = bp[0] elif vt == VARIANT_FLOAT: jv.vtype = 3 # JSON_FLOAT fp: float | t.CPtr = t.CVoid(t.CUInt64T(vp), t.CPtr) jv.float_val = fp[0] elif vt == VARIANT_PTR: # 默认: 将 PTR 作为整数处理 jv.vtype = 2 # JSON_INT ip: int | t.CPtr = t.CVoid(t.CUInt64T(vp), t.CPtr) jv.int_val = ip[0] json.object_set(pool, obj, key_ptr[0], jv) i += 1 return obj def from_json(self, pool: memhub.MemManager | t.CPtr, root: json.JsonValue | t.CPtr): """从 JsonValue 对象填充 dict。 根据 JSON 值类型自动提取并存储为对应 Variant 类型。""" if root == None: return if root.vtype != 6: # JSON_OBJECT return cur: json.JsonValue | t.CPtr = root.child while cur != None: if cur.key != None: if cur.vtype == 2: # JSON_INT storage: t.CPtr = self.__mbuddy__.alloc(8) ip: int | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) ip[0] = cur.int_val self._set_variant_raw(cur.key, VARIANT_INT, storage) elif cur.vtype == 4: # JSON_STRING self._set_variant_raw(cur.key, VARIANT_STR, cur.str_val) elif cur.vtype == 1: # JSON_BOOL storage: t.CPtr = self.__mbuddy__.alloc(8) bp: t.CInt | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) bp[0] = cur.bool_val self._set_variant_raw(cur.key, VARIANT_BOOL, storage) elif cur.vtype == 3: # JSON_FLOAT storage: t.CPtr = self.__mbuddy__.alloc(8) fp: float | t.CPtr = t.CVoid(t.CUInt64T(storage), t.CPtr) fp[0] = cur.float_val self._set_variant_raw(cur.key, VARIANT_FLOAT, storage) cur = cur.next def dumps(self, pool: memhub.MemManager | t.CPtr) -> str: """将 dict 序列化为 JSON 字符串。""" obj: json.JsonValue | t.CPtr = self.to_json(pool) return json.write(pool, obj, False) def loads(self, pool: memhub.MemManager | t.CPtr, json_str: str): """从 JSON 字符串解析并填充 dict。""" root: json.JsonValue | t.CPtr = json.parse(pool, json_str) self.from_json(pool, root)