123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694 |
- #include "JSON.h"
- #include "Datei.h"
- using namespace Framework;
- using namespace JSON;
- #pragma region JSONValue
- JSONValue::JSONValue()
- : ReferenceCounter()
- {
- this->type = AbstractType::NULL_;
- }
- JSONValue::~JSONValue() {}
- JSONValue::JSONValue(AbstractType type)
- : ReferenceCounter()
- {
- this->type = type;
- }
- AbstractType JSONValue::getType() const
- {
- return type;
- }
- Text JSONValue::toString() const
- {
- return Text("null");
- }
- JSONValue* JSONValue::clone() const
- {
- return new JSONValue();
- }
- JSONBool* JSONValue::asBool() const
- {
- return (JSONBool*)this;
- }
- JSONNumber* JSONValue::asNumber() const
- {
- return (JSONNumber*)this;
- }
- JSONString* JSONValue::asString() const
- {
- return (JSONString*)this;
- }
- JSONArray* JSONValue::asArray() const
- {
- return (JSONArray*)this;
- }
- JSONObject* JSONValue::asObject() const
- {
- return (JSONObject*)this;
- }
- const AbstractBool* Framework::JSON::JSONValue::asAbstractBool() const
- {
- return dynamic_cast<const AbstractBool*>(this);
- }
- const AbstractNumber* Framework::JSON::JSONValue::asAbstractNumber() const
- {
- return dynamic_cast<const AbstractNumber*>(this);
- }
- const AbstractString* Framework::JSON::JSONValue::asAbstractString() const
- {
- return dynamic_cast<const AbstractString*>(this);
- }
- const AbstractArray* Framework::JSON::JSONValue::asAbstractArray() const
- {
- return dynamic_cast<const AbstractArray*>(this);
- }
- const AbstractObject* Framework::JSON::JSONValue::asAbstractObject() const
- {
- return dynamic_cast<const AbstractObject*>(this);
- }
- #pragma endregion Cotent
- #pragma region JSONBool
- JSONBool::JSONBool(bool b)
- : JSONValue(AbstractType::BOOLEAN)
- {
- this->b = b;
- }
- bool JSONBool::getBool() const
- {
- return b;
- }
- Text JSONBool::toString() const
- {
- if (b)
- return Text("true");
- else
- return Text("false");
- }
- JSONValue* JSONBool::clone() const
- {
- return new JSONBool(b);
- }
- #pragma endregion Cotent
- #pragma region JSONNumber
- JSONNumber::JSONNumber(double num)
- : JSONValue(AbstractType::NUMBER)
- {
- number = num;
- }
- double JSONNumber::getNumber() const
- {
- return number;
- }
- Text JSONNumber::toString() const
- {
- return Text(number);
- }
- JSONValue* JSONNumber::clone() const
- {
- return new JSONNumber(number);
- }
- #pragma endregion Cotent
- #pragma region JSONString
- JSONString::JSONString(Text string)
- : JSONValue(AbstractType::STRING)
- {
- this->string = string;
- this->string.ersetzen("\\\"", "\"");
- this->string.ersetzen("\\n", "\n");
- }
- Text JSONString::getString() const
- {
- return string;
- }
- Text JSONString::toString() const
- {
- Text esc = string;
- esc.ersetzen("\"", "\\\"");
- esc.ersetzen("\n", "\\n");
- return Text(Text("\"") += esc.getText()) += "\"";
- }
- JSONValue* JSONString::clone() const
- {
- Text esc = string;
- esc.ersetzen("\"", "\\\"");
- esc.ersetzen("\n", "\\n");
- return new JSONString(esc);
- }
- #pragma endregion Cotent
- #pragma region JSONArray
- JSONArray::JSONArray()
- : JSONValue(AbstractType::ARRAY)
- {
- array = new RCArray<JSONValue>();
- }
- JSONArray::JSONArray(Text string)
- : JSONValue(AbstractType::ARRAY)
- {
- array = new RCArray<JSONValue>();
- string = Parser::removeWhitespace(string);
- if (string.getText()[0] == '['
- && string.getText()[string.getLength() - 1] == ']')
- {
- string.remove(0, 1);
- string.remove(string.getLength() - 1, string.getLength());
- while (string.getLength())
- {
- int end = Parser::findObjectEndInArray(string);
- Text* objStr = string.getTeilText(0, end);
- string.remove(0, end + 1);
- array->add(Parser::getValue(*objStr));
- objStr->release();
- }
- }
- }
- JSONArray::JSONArray(const JSONArray& arr)
- : JSONValue(AbstractType::ARRAY)
- {
- array = dynamic_cast<RCArray<JSONValue>*>(arr.array->getThis());
- }
- JSONArray::~JSONArray()
- {
- array->release();
- }
- JSONArray& JSONArray::operator=(const JSONArray& arr)
- {
- array->release();
- array = dynamic_cast<RCArray<JSONValue>*>(arr.array->getThis());
- return *this;
- }
- void JSONArray::addValue(JSONValue* value)
- {
- array->add(value);
- }
- void JSONArray::setValue(int i, JSONValue* value)
- {
- array->set(value, i);
- }
- void JSONArray::removeValue(int i)
- {
- array->remove(i);
- }
- JSONValue* JSONArray::getValue(int i) const
- {
- return array->get(i);
- }
- JSONValue* JSONArray::zValue(int i) const
- {
- return array->z(i);
- }
- AbstractElement* JSONArray::zAbstractValue(int i) const
- {
- return zValue(i);
- }
- int JSONArray::getLength() const
- {
- return array->getEintragAnzahl();
- }
- bool JSONArray::isValueOfType(int i, AbstractType type) const
- {
- return i >= 0 && i < array->getEintragAnzahl()
- && array->z(i)->getType() == type;
- }
- ArrayIterator<JSONValue*> JSONArray::begin() const
- {
- return array->begin();
- }
- ArrayIterator<JSONValue*> JSONArray::end() const
- {
- return array->end();
- }
- Text JSONArray::toString() const
- {
- Text str = "[";
- for (auto i = array->begin(); i; i++)
- {
- str += i->toString();
- if (i.hasNext()) str += ",";
- }
- str += "]";
- return str;
- }
- JSONValue* JSONArray::clone() const
- {
- JSONArray* arr = new JSONArray();
- for (JSONValue* value : *this)
- {
- arr->addValue(value->clone());
- }
- return arr;
- }
- #pragma endregion Cotent
- #pragma region JSONObject
- JSONObject::JSONObject()
- : JSONValue(AbstractType::OBJECT)
- {
- fields = new Array<Text>();
- values = new RCArray<JSONValue>();
- }
- JSONObject::JSONObject(Text string)
- : JSONValue(AbstractType::OBJECT)
- {
- fields = new Array<Text>();
- values = new RCArray<JSONValue>();
- string = Parser::removeWhitespace(string);
- if (string.getText()[0] == '{'
- && string.getText()[string.getLength() - 1] == '}')
- {
- string.remove(0, 1);
- string.remove(string.getLength() - 1, string.getLength());
- while (string.getLength())
- {
- int endField = Parser::findFieldEndInObject(string);
- Text* fieldName = string.getTeilText(0, endField);
- string.remove(0, endField + 1);
- fieldName->remove(0, 1);
- fieldName->remove(
- fieldName->getLength() - 1, fieldName->getLength());
- int endValue = Parser::findValueEndInObject(string);
- Text* value = string.getTeilText(0, endValue);
- string.remove(0, endValue + 1);
- fields->add(Text(fieldName->getText()));
- values->add(Parser::getValue(*value));
- fieldName->release();
- value->release();
- }
- }
- }
- JSONObject::JSONObject(const JSONObject& obj)
- : JSONValue(AbstractType::OBJECT)
- {
- fields = dynamic_cast<Array<Text>*>(obj.fields->getThis());
- values = dynamic_cast<RCArray<JSONValue>*>(obj.values->getThis());
- }
- JSONObject::~JSONObject()
- {
- fields->release();
- values->release();
- }
- JSONObject& JSONObject::operator=(const JSONObject& obj)
- {
- fields->release();
- values->release();
- fields = dynamic_cast<Array<Text>*>(obj.fields->getThis());
- values = dynamic_cast<RCArray<JSONValue>*>(obj.values->getThis());
- return *this;
- }
- bool JSONObject::addValue(Text field, JSONValue* value)
- {
- if (hasValue(field)) return 0;
- fields->add(field);
- values->add(value);
- return 1;
- }
- bool JSONObject::removeValue(Text field)
- {
- for (int i = 0; i < fields->getEintragAnzahl(); i++)
- {
- if (fields->get(i).istGleich(field))
- {
- fields->remove(i);
- values->remove(i);
- return 1;
- }
- }
- return 0;
- }
- bool JSONObject::hasValue(Text field) const
- {
- return zValue(field);
- }
- JSONValue* JSONObject::getValue(Text field) const
- {
- for (int i = 0; i < fields->getEintragAnzahl(); i++)
- {
- if (fields->get(i).istGleich(field)) return values->get(i);
- }
- return 0;
- }
- JSONValue* JSONObject::zValue(Text field) const
- {
- for (int i = 0; i < fields->getEintragAnzahl(); i++)
- {
- if (fields->get(i).istGleich(field)) return values->z(i);
- }
- return 0;
- }
- AbstractElement* JSONObject::zAbstractValue(Text field) const
- {
- return zValue(field);
- }
- ArrayIterator<Text> JSONObject::getFields()
- {
- return fields->begin();
- }
- ArrayIterator<JSONValue*> JSONObject::getValues()
- {
- return values->begin();
- }
- Text Framework::JSON::JSONObject::getFieldKey(int i) const
- {
- return fields->get(i);
- }
- AbstractElement* Framework::JSON::JSONObject::zAbstractValue(int i) const
- {
- return values->z(i);
- }
- int JSONObject::getFieldCount() const
- {
- return fields->getEintragAnzahl();
- }
- bool JSONObject::isValueOfType(Text field, AbstractType type) const
- {
- for (int i = 0; i < fields->getEintragAnzahl(); i++)
- {
- if (fields->get(i).istGleich(field))
- return values->z(i)->getType() == type;
- }
- return 0;
- }
- Text JSONObject::toString() const
- {
- Text str = "{";
- ArrayIterator<Text> k = fields->begin();
- for (auto v = values->begin(); k && v; k++, v++)
- {
- str += "\"";
- str += k._.getText();
- str += "\":";
- str += v->toString().getText();
- if (v.hasNext()) str += ",";
- }
- str += "}";
- return str;
- }
- JSONValue* JSONObject::clone() const
- {
- JSONObject* obj = new JSONObject();
- auto field = fields->begin();
- auto value = values->begin();
- for (; field && value; field++, value++)
- {
- obj->addValue(field.val(), value->clone());
- }
- return obj;
- }
- #pragma endregion Cotent
- JSONValue* JSON::loadJSONFromFile(Text path)
- {
- Datei d;
- d.setDatei(path);
- if (!d.open(Datei::Style::lesen))
- {
- return new JSONValue();
- }
- int size = (int)d.getSize();
- char* buffer = new char[size + 1];
- buffer[size] = 0;
- d.lese(buffer, size);
- d.close();
- JSONValue* result = Parser::getValue(buffer);
- delete[] buffer;
- return result;
- }
- #pragma region Parser
- int Parser::findObjectEndInArray(const char* str)
- {
- return findValueEndInObject(str);
- }
- Text Parser::removeWhitespace(const char* str)
- {
- int wsc = 0;
- int i = 0;
- bool esc = 0;
- bool strO = 0;
- for (; str[i]; i++)
- {
- switch (str[i])
- {
- case '\\':
- if (strO)
- esc = !esc;
- else
- esc = 0;
- break;
- case '"':
- if (!esc) strO = !strO;
- esc = 0;
- break;
- case ' ':
- case '\n':
- case '\t':
- case '\r':
- if (!strO) wsc++;
- esc = 0;
- break;
- default:
- esc = 0;
- break;
- }
- }
- Text ret;
- i = 0;
- esc = 0;
- strO = 0;
- for (; str[i]; i++)
- {
- switch (str[i])
- {
- case '\\':
- if (strO)
- esc = !esc;
- else
- esc = 0;
- ret.append(str[i]);
- break;
- case '"':
- if (!esc) strO = !strO;
- esc = 0;
- ret.append(str[i]);
- break;
- case ' ':
- case '\n':
- case '\t':
- case '\r':
- if (strO) ret.append(str[i]);
- esc = 0;
- break;
- default:
- ret.append(str[i]);
- esc = 0;
- break;
- }
- }
- return ret;
- }
- JSONValue* Parser::getValue(const char* str)
- {
- Text string = Parser::removeWhitespace(str);
- if (string.istGleich("true")) return new JSONBool(1);
- if (string.istGleich("false")) return new JSONBool(0);
- if (string.getText()[0] == '"')
- {
- string.remove(0, 1);
- string.remove(string.getLength() - 1, string.getLength());
- return new JSONString(string);
- }
- if (string.getText()[0] == '[') return new JSONArray(string);
- if (string.getText()[0] == '{') return new JSONObject(string);
- if (Text((int)string).istGleich(string.getText()))
- return new JSONNumber((double)string);
- if (string.anzahlVon('.') == 1)
- {
- bool isNumber = 1;
- for (const char* c = (*string.getText() == '-') ? string.getText() + 1
- : string.getText();
- *c;
- c++)
- isNumber &= (*c >= '0' && *c <= '9') || *c == '.';
- if (isNumber) return new JSONNumber((double)string);
- }
- return new JSONValue();
- }
- int Parser::findFieldEndInObject(const char* str)
- {
- int i = 0;
- bool esc = 0;
- bool strO = 0;
- int objOc = 0;
- int arrayOc = 0;
- for (; str[i]; i++)
- {
- switch (str[i])
- {
- case '\\':
- if (strO)
- esc = !esc;
- else
- esc = 0;
- break;
- case '"':
- if (!esc) strO = !strO;
- esc = 0;
- break;
- case '[':
- if (!strO) arrayOc++;
- esc = 0;
- break;
- case ']':
- if (!strO) arrayOc--;
- esc = 0;
- break;
- case '{':
- if (!strO) objOc++;
- esc = 0;
- break;
- case '}':
- if (!strO) objOc--;
- esc = 0;
- break;
- case ':':
- if (!strO && objOc == 0 && arrayOc == 0) return i;
- esc = 0;
- break;
- default:
- esc = 0;
- break;
- }
- }
- return i;
- }
- int Parser::findValueEndInObject(const char* str)
- {
- int i = 0;
- bool esc = 0;
- bool strO = 0;
- int objOc = 0;
- int arrayOc = 0;
- for (; str[i]; i++)
- {
- switch (str[i])
- {
- case '\\':
- if (strO)
- esc = !esc;
- else
- esc = 0;
- break;
- case '"':
- if (!esc) strO = !strO;
- esc = 0;
- break;
- case '[':
- if (!strO) arrayOc++;
- esc = 0;
- break;
- case ']':
- if (!strO) arrayOc--;
- esc = 0;
- break;
- case '{':
- if (!strO) objOc++;
- esc = 0;
- break;
- case '}':
- if (!strO) objOc--;
- esc = 0;
- break;
- case ',':
- if (!strO && objOc == 0 && arrayOc == 0) return i;
- esc = 0;
- break;
- default:
- esc = 0;
- break;
- }
- }
- return i;
- }
- #pragma endregion Cotent
|