diff options
| author | suresh <sureshkrishnan.ai@gmail.com> | 2026-01-25 11:24:22 -0500 |
|---|---|---|
| committer | suresh <sureshkrishnan.ai@gmail.com> | 2026-01-25 11:24:22 -0500 |
| commit | 0bb69cb67078dfa921b5b8a42275ef31dfbc9a56 (patch) | |
| tree | b579695576ae27f7316866b18bd54073f8e2ca1f /std | |
| parent | 0bd7b99fbf813415b9a0217eaa2a4e8f6f74e1ea (diff) | |
fixed beffer overflow in vector. Added serialize and deserialize in json with vector reading from the struct with json
Diffstat (limited to 'std')
| -rw-r--r-- | std/json.zc | 203 |
1 files changed, 201 insertions, 2 deletions
diff --git a/std/json.zc b/std/json.zc index cfef2c3..6c4a0da 100644 --- a/std/json.zc +++ b/std/json.zc @@ -4,6 +4,7 @@ import "./vec.zc" import "./map.zc" import "./string.zc" import "./result.zc" +import "./option.zc" @derive(Eq) enum JsonType { @@ -201,7 +202,47 @@ impl JsonValue { *m = Map_JsonValuePtr::new(); return JsonValue { kind: JsonType::JSON_OBJECT(), string_val: 0, number_val: 0, bool_val: false, array_val: 0, object_val: m }; } - + + // ============================================ + // Heap-allocated factory methods (returns pointers) + // ============================================ + + fn null_ptr() -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::null(); + return p; + } + + fn bool_ptr(b: bool) -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::bool(b); + return p; + } + + fn number_ptr(n: double) -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::number(n); + return p; + } + + fn string_ptr(s: char*) -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::string(s); + return p; + } + + fn array_ptr() -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::array(); + return p; + } + + fn object_ptr() -> JsonValue* { + var p: JsonValue* = malloc(sizeof(JsonValue)); + *p = JsonValue::object(); + return p; + } + fn push(self, val: JsonValue) { if (self.kind.tag != JsonType::JSON_ARRAY().tag) return; var p: JsonValue* = malloc(sizeof(JsonValue)); @@ -223,7 +264,165 @@ impl JsonValue { } return Result<JsonValue*>::Err("JSON parse error"); } - + + // ============================================ + // Type checking helpers + // ============================================ + + fn is_null(self) -> bool { + return self.kind.tag == JsonType::JSON_NULL().tag; + } + + fn is_bool(self) -> bool { + return self.kind.tag == JsonType::JSON_BOOL().tag; + } + + fn is_number(self) -> bool { + return self.kind.tag == JsonType::JSON_NUMBER().tag; + } + + fn is_string(self) -> bool { + return self.kind.tag == JsonType::JSON_STRING().tag; + } + + fn is_array(self) -> bool { + return self.kind.tag == JsonType::JSON_ARRAY().tag; + } + + fn is_object(self) -> bool { + return self.kind.tag == JsonType::JSON_OBJECT().tag; + } + + // ============================================ + // Direct value extractors + // ============================================ + + fn as_string(self) -> Option<char*> { + if self.kind.tag == JsonType::JSON_STRING().tag { + return Option<char*>::Some(self.string_val); + } + return Option<char*>::None(); + } + + fn as_int(self) -> Option<int> { + if self.kind.tag == JsonType::JSON_NUMBER().tag { + return Option<int>::Some((int)self.number_val); + } + return Option<int>::None(); + } + + fn as_float(self) -> Option<double> { + if self.kind.tag == JsonType::JSON_NUMBER().tag { + return Option<double>::Some(self.number_val); + } + return Option<double>::None(); + } + + fn as_bool(self) -> Option<bool> { + if self.kind.tag == JsonType::JSON_BOOL().tag { + return Option<bool>::Some(self.bool_val); + } + return Option<bool>::None(); + } + + // ============================================ + // Object key accessors + // ============================================ + + fn get(self, key: char*) -> Option<JsonValue*> { + if self.kind.tag != JsonType::JSON_OBJECT().tag { + return Option<JsonValue*>::None(); + } + if Map<JsonValue*>::contains(self.object_val, key) { + return Map<JsonValue*>::get(self.object_val, key); + } + return Option<JsonValue*>::None(); + } + + fn get_string(self, key: char*) -> Option<char*> { + var opt = self.get(key); + if opt.is_none() { + return Option<char*>::None(); + } + var val = opt.unwrap(); + return (*val).as_string(); + } + + fn get_int(self, key: char*) -> Option<int> { + var opt = self.get(key); + if opt.is_none() { + return Option<int>::None(); + } + var val = opt.unwrap(); + return (*val).as_int(); + } + + fn get_float(self, key: char*) -> Option<double> { + var opt = self.get(key); + if opt.is_none() { + return Option<double>::None(); + } + var val = opt.unwrap(); + return (*val).as_float(); + } + + fn get_bool(self, key: char*) -> Option<bool> { + var opt = self.get(key); + if opt.is_none() { + return Option<bool>::None(); + } + var val = opt.unwrap(); + return (*val).as_bool(); + } + + fn get_object(self, key: char*) -> Option<JsonValue*> { + var opt = self.get(key); + if opt.is_none() { + return Option<JsonValue*>::None(); + } + var val = opt.unwrap(); + if (*val).kind.tag == JsonType::JSON_OBJECT().tag { + return Option<JsonValue*>::Some(val); + } + return Option<JsonValue*>::None(); + } + + fn get_array(self, key: char*) -> Option<JsonValue*> { + var opt = self.get(key); + if opt.is_none() { + return Option<JsonValue*>::None(); + } + var val = opt.unwrap(); + if (*val).kind.tag == JsonType::JSON_ARRAY().tag { + return Option<JsonValue*>::Some(val); + } + return Option<JsonValue*>::None(); + } + + // ============================================ + // Array accessors + // ============================================ + + fn at(self, index: usize) -> Option<JsonValue*> { + if self.kind.tag != JsonType::JSON_ARRAY().tag { + return Option<JsonValue*>::None(); + } + if index >= self.array_val.length() { + return Option<JsonValue*>::None(); + } + return Option<JsonValue*>::Some(self.array_val.get(index)); + } + + fn len(self) -> usize { + if self.kind.tag == JsonType::JSON_ARRAY().tag { + return self.array_val.length(); + } + if self.kind.tag == JsonType::JSON_OBJECT().tag { + return self.object_val.length(); + } + return 0; + } + fn free(self) { if (self.kind.tag == JsonType::JSON_STRING().tag) free(self.string_val); if (self.kind.tag == JsonType::JSON_ARRAY().tag) { |
