/* ======================================== Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. ======================================== */ #pragma once /// @brief Kernel JSON API. #include #include #include #include #include #define kNeJsonMaxLen (8196) #define kNeJsonLen (256) #define kNeJsonNullArr "[]" #define kNeJsonNullObj "{}" namespace Kernel { /// @brief JavaScript object class class JsonObject final { public: explicit JsonObject() { auto len = kNeJsonMaxLen; KBasicString<> key = KString(len); key += kNeJsonNullObj; this->AsKey() = key; this->AsValue() = key; } explicit JsonObject(SizeT lhsLen, SizeT rhsLen) : fKey(lhsLen), fValue(rhsLen) {} ~JsonObject() = default; NE_COPY_DEFAULT(JsonObject) Bool& IsUndefined() { return fUndefined; } private: Bool fUndefined; // is this instance undefined? KBasicString<> fKey; KBasicString<> fValue; public: /// @brief returns the key of the json /// @return the key as string view. KBasicString<>& AsKey() { return fKey; } /// @brief returns the value of the json. /// @return the key as string view. KBasicString<>& AsValue() { return fValue; } static JsonObject kNull; }; /// @brief JsonObject stream reader helper. struct JsonStreamReader final { STATIC JsonObject In(const Char* full_array) { auto start_val = '{'; auto end_val = '}'; Boolean probe_value = false; if (full_array[0] != start_val) { if (full_array[0] != '[') return JsonObject::kNull; start_val = '['; end_val = ']'; probe_value = true; } SizeT len = rt_string_len(full_array); SizeT key_len = 0; SizeT value_len = 0; JsonObject type(kNeJsonMaxLen, kNeJsonMaxLen); for (SizeT i = 1; i < len; ++i) { if (full_array[i] == '\r' || full_array[i] == '\n') continue; if (probe_value) { if (full_array[i] == end_val || full_array[i] == ',') { probe_value = false; ++value_len; } else { if (full_array[i] == '\'') { type.AsValue().Data()[value_len] = 0; break; } type.AsValue().Data()[value_len] = full_array[i]; ++value_len; } } else { if (start_val == '[') continue; if (full_array[i] == ':') { type.AsKey().Data()[key_len] = 0; ++key_len; ++i; while (full_array[i] == ' ' || full_array[i] == '\t') ++i; probe_value = true; } else { type.AsKey().Data()[key_len] = full_array[i]; ++key_len; } } } type.AsValue().Data()[value_len] = 0; return type; } }; using JsonStream = Stream; } // namespace Kernel