--- parser3/src/classes/json.C 2024/10/02 21:24:41 1.63 +++ parser3/src/classes/json.C 2024/11/04 03:53:25 1.66 @@ -1,7 +1,7 @@ /** @file Parser: @b json parser class. - Copyright (c) 2000-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2000-2024 Art. Lebedev Studio (http://www.artlebedev.com) Authors: Konstantin Morshnev */ @@ -20,19 +20,24 @@ #include "pa_vxdoc.h" #endif -volatile const char * IDENT_JSON_C="$Id: json.C,v 1.63 2024/10/02 21:24:41 moko Exp $"; +volatile const char * IDENT_JSON_C="$Id: json.C,v 1.66 2024/11/04 03:53:25 moko Exp $"; // class class MJson: public Methoded { public: MJson(); + + override Value* get_element(const String&); + override const VJunction* put_element(const String&, Value*); }; // global variable DECLARE_CLASS_VAR(json, new MJson); +bool handle_array_default=true; + // methods struct Json : public PA_Allocated { Stack stack; @@ -55,7 +60,7 @@ struct Json : public PA_Allocated { Json(Charset* acharset): stack(), key_stack(), key(NULL), result(NULL), hook_object(NULL), hook_array(NULL), request(NULL), charset(acharset), taint(String::L_TAINTED), handle_double(true), handle_int(true), - handle_array(true), distinct(D_EXCEPTION){} + handle_array(handle_array_default), distinct(D_EXCEPTION){} bool set_distinct(const String &value){ if (value == "first") distinct = D_FIRST; @@ -73,6 +78,31 @@ struct Json : public PA_Allocated { } }; + +Value* MJson::get_element(const String& aname) { + if (aname=="array"){ + return new VString(*new String(handle_array_default ? "array" : "hash")); + } + return Methoded::get_element(aname); +} + +const VJunction* MJson::put_element(const String& aname, Value* avalue) { + if (aname=="array"){ + Json json(NULL); + if (avalue->get_string()){ + const String& sarray=avalue->as_string(); + if (json.set_handle_array(sarray)){ + handle_array_default=json.handle_array; + return 0; + } + throw Exception(PARSER_RUNTIME, &sarray, "$json:array must be 'array' or 'hash'"); + } + throw Exception(PARSER_RUNTIME, 0, "$json:array must be 'array' or 'hash'"); + } + return Methoded::put_element(aname, avalue); +} + + static void set_json_value(Json *json, Value *value){ VHashBase *top = json->stack.top_value(); if(json->key == NULL){ @@ -492,7 +522,7 @@ const String* Json_options::array_json_s result << indent; delim = get_array_delim(json_string_recursion); } - result << value_json_string(i.key(), i.value() ? *i.value() : *VVoid::get(), *this); + result << value_json_string(i.key(), i.value() ? *i.value() : static_cast(*VVoid::get()), *this); } result << "\n" << (indent=get_indent(json_string_recursion-1)) << "]"; @@ -501,7 +531,7 @@ const String* Json_options::array_json_s bool need_delim=false; for(ArrayValue::Iterator i(*array); i; i.next() ){ if(need_delim) result << ",\n"; - result << value_json_string(i.key(), i.value() ? *i.value() : *VVoid::get(), *this); + result << value_json_string(i.key(), i.value() ? *i.value() : static_cast(*VVoid::get()), *this); need_delim=true; } result << "\n]";