summaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorsuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:24:22 -0500
committersuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:24:22 -0500
commit0bb69cb67078dfa921b5b8a42275ef31dfbc9a56 (patch)
treeb579695576ae27f7316866b18bd54073f8e2ca1f /std
parent0bd7b99fbf813415b9a0217eaa2a4e8f6f74e1ea (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.zc203
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) {