diff --git a/ejson/Array.cpp b/ejson/Array.cpp index 80f298c..e8134b8 100644 --- a/ejson/Array.cpp +++ b/ejson/Array.cpp @@ -5,387 +5,159 @@ * * @license APACHE v2.0 (see license file) */ - - -#include #include -#include -#include -#include -#include #include -#include +#include -ememory::SharedPtr ejson::Array::create() { - return ememory::SharedPtr(new ejson::Array()); +ejson::Array::Array(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isArray() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } } -void ejson::Array::clear() { - m_value.clear(); +ejson::Array::Array(const ejson::Array& _obj) : + ejson::Value(_obj.m_data) { + } -bool ejson::Array::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Object' "); - for (size_t iii=_pos+1; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - ejson::FilePos tmpPos; - if( _data[iii] == ' ' - || _data[iii] == '\t' - || _data[iii] == '\n' - || _data[iii] == '\r') { - // white space == > nothing to do ... - } else if(_data[iii] == '#') { - // comment Line ... - for (iii++; iii<_data.size(); iii++) { - if( _data[iii] == '\n' - || _data[iii] == '\r') { - break; - } - } - } else if(_data[iii] == ']') { - // find end of value: - _pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed - return true; - } else if (_data[iii] == '{') { - // find an object: - JSON_PARSE_ELEMENT("find Object"); - ememory::SharedPtr tmpElement = ejson::Object::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in object"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if ( _data[iii] == '"' - || _data[iii] == '\'') { - // find a string: - JSON_PARSE_ELEMENT("find String quoted"); - ememory::SharedPtr tmpElement = ejson::String::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if (_data[iii] == '[') { - // find a list: - JSON_PARSE_ELEMENT("find List"); - ememory::SharedPtr tmpElement = ejson::Array::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Array"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if( _data[iii] == 'f' - || _data[iii] == 't' ) { - // find boolean: - JSON_PARSE_ELEMENT("find Boolean"); - ememory::SharedPtr tmpElement = ejson::Boolean::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if( _data[iii] == 'n') { - // find null: - JSON_PARSE_ELEMENT("find Null"); - ememory::SharedPtr tmpElement = ejson::Null::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if(true == checkNumber(_data[iii])) { - // find number: - JSON_PARSE_ELEMENT("find Number"); - ememory::SharedPtr tmpElement = ejson::Number::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - m_value.push_back(tmpElement); - } else if(_data[iii] == ',') { - // find Separator : Restart cycle ... - // TODO : check if element are separated with ',' - } else { - // find an error .... - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Find '?' with no element in the element..."); - // move the curent index - _pos = iii+1; - return false; - } - } - _pos = _data.size(); - return false; +ejson::Array::Array() : + ejson::Value() { + m_data = ejson::internal::Array::create(); } - -bool ejson::Array::iGenerate(std::string& _data, size_t _indent) const { - bool oneLine=true; - if (m_value.size()>3) { - oneLine=false; - } else { - for (size_t iii=0; iii tmp = m_value[iii]; - if (tmp == nullptr) { - continue; - } - if (true == tmp->isObject()) { - oneLine=false; - break; - } - if (true == tmp->isArray()) { - oneLine=false; - break; - } - if (true == tmp->isString()) { - ememory::SharedPtr tmp2 = tmp->toString(); - if (tmp2 != nullptr) { - if(tmp2->get().size()>40) { - oneLine=false; - break; - } - } - } - } - } - if (true == oneLine) { - _data += "[ "; - } else { - _data += "[\n"; - } - for (size_t iii=0; iiiiGenerate(_data, _indent+1); - if (iii _element) { - if (_element == nullptr) { - JSON_ERROR("Request add on an nullptr pointer"); - return false; +size_t ejson::Array::size() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not size (nullptr) ..."); + return 0; } - m_value.push_back(_element); - return true; + return static_cast(m_data.get())->size(); } -bool ejson::Array::addString(const std::string& _value) { - return add(ejson::String::create(_value)); -} - -bool ejson::Array::addNull() { - return add(ejson::Null::create()); -} - -bool ejson::Array::addBoolean(bool _value) { - return add(ejson::Boolean::create(_value)); -} - -bool ejson::Array::addNumber(double _value) { - return add(ejson::Number::create(_value)); -} - - -bool ejson::Array::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an nullptr pointer"); - return false; +ejson::Value ejson::Array::operator[] (size_t _id) { + if (m_data == nullptr) { + EJSON_ERROR("Can not get (nullptr) ..."); + return ejson::Value(nullptr); } - ememory::SharedPtr other = _obj->toArray(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an array"); - return false; - } - // remove destination elements - other->clear(); - // Copy to the destination - other->m_value = m_value; - // remove current: - m_value.clear(); - return true; + return ejson::Value(static_cast(m_data.get())->get(_id)); } -// TODO : Manage error ... -ememory::SharedPtr ejson::Array::clone() const { - ememory::SharedPtr output = ejson::Array::create(); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); +const ejson::Value ejson::Array::operator[] (size_t _id) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not get (nullptr) ..."); + return ejson::Value(nullptr);; } - for (size_t iii=0; iii val = m_value[iii]; - if (val == nullptr) { - continue; - } - output->add(val->clone()); - } - return output; -} - -ememory::SharedPtr ejson::Array::getObject(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toObject(); -} -const ememory::SharedPtr ejson::Array::getObject(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toObject(); -} - -ememory::SharedPtr ejson::Array::getString(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toString(); -} - -const ememory::SharedPtr ejson::Array::getString(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toString(); -} - -ememory::SharedPtr ejson::Array::getArray(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toArray(); -} - -const ememory::SharedPtr ejson::Array::getArray(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toArray(); -} - -ememory::SharedPtr ejson::Array::getNull(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toNull(); -} - -const ememory::SharedPtr ejson::Array::getNull(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toNull(); -} - -ememory::SharedPtr ejson::Array::getNumber(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toNumber(); -} - -const ememory::SharedPtr ejson::Array::getNumber(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toNumber(); -} - -ememory::SharedPtr ejson::Array::getBoolean(size_t _id) { - ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toBoolean(); -} - -const ememory::SharedPtr ejson::Array::getBoolean(size_t _id) const { - const ememory::SharedPtr tmpElement = m_value[_id]; - if (tmpElement == nullptr) { - return ememory::SharedPtr(); - } - return tmpElement->toBoolean(); + return ejson::Value(static_cast(m_data.get())->get(_id)); } std::string ejson::Array::getStringValue(size_t _id) { - ememory::SharedPtr tmpElement = getString(_id); - if (tmpElement == nullptr) { + if (m_data == nullptr) { + EJSON_ERROR("Can not parse (nullptr) ..."); return ""; } - return tmpElement->get(); + return static_cast(m_data.get())->getStringValue(_id); } const std::string& ejson::Array::getStringValue(size_t _id) const { - static const std::string errorValue(""); - const ememory::SharedPtr tmpElement = getString(_id); - if (tmpElement == nullptr) { + if (m_data == nullptr) { + static const std::string errorValue = ""; + EJSON_ERROR("Can not getStringValue (nullptr) ..."); return errorValue; } - return tmpElement->get(); + return static_cast(m_data.get())->getStringValue(_id); } std::string ejson::Array::getStringValue(size_t _id, const std::string& _errorValue) const { - const ememory::SharedPtr tmpElement = getString(_id); - if (tmpElement == nullptr) { + if (m_data == nullptr) { + EJSON_ERROR("Can not getStringValue (nullptr) ..."); return _errorValue; } - return tmpElement->get(); + return static_cast(m_data.get())->getStringValue(_id, _errorValue); } double ejson::Array::getNumberValue(size_t _id, double _errorValue) const { - const ememory::SharedPtr tmpElement = getNumber(_id); - if (tmpElement == nullptr) { + if (m_data == nullptr) { + EJSON_ERROR("Can not getNumberValue (nullptr) ..."); return _errorValue; } - return tmpElement->get(); + return static_cast(m_data.get())->getNumberValue(_id, _errorValue); } bool ejson::Array::getBooleanValue(size_t _id, bool _errorValue) const { - const ememory::SharedPtr tmpElement = getBoolean(_id); - if (tmpElement == nullptr) { + if (m_data == nullptr) { + EJSON_ERROR("Can not getBooleanValue (nullptr) ..."); return _errorValue; } - return tmpElement->get(); + return static_cast(m_data.get())->getBooleanValue(_id, _errorValue); +} + +bool ejson::Array::add(const ejson::Value& _element) { + if (m_data == nullptr) { + EJSON_ERROR("Can not add (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->add(_element.m_data); +} + +bool ejson::Array::addString(const std::string& _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not addString (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addString(_value); +} + +bool ejson::Array::addNull() { + if (m_data == nullptr) { + EJSON_ERROR("Can not addNull (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addNull(); +} + +bool ejson::Array::addBoolean(bool _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not addBoolean (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addBoolean(_value); +} + +bool ejson::Array::addNumber(double _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not addNumber (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addNumber(_value); +} + +ejson::Array::iterator ejson::Array::begin() { + return ejson::Array::iterator(*this, 0); +} + +ejson::Array::iterator ejson::Array::end() { + return ejson::Array::iterator(*this, size()); +} + +const ejson::Array::iterator ejson::Array::begin() const { + return ejson::Array::iterator(*this, 0); +} + +const ejson::Array::iterator ejson::Array::end() const { + return ejson::Array::iterator(*this, size()); } +#include + +template class ejson::iterator; + diff --git a/ejson/Array.h b/ejson/Array.h index d5493e8..21c42b9 100644 --- a/ejson/Array.h +++ b/ejson/Array.h @@ -9,66 +9,43 @@ #include #include +#include namespace ejson { class Array : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - Array() { }; public: - static ememory::SharedPtr create(); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~Array() { }; - private: - std::vector > m_value; //!< vector of sub elements + Array(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Array(const ejson::Array& _obj); + /** + * @brief Constructor + */ + Array(); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Array& operator= (const ejson::Array& _obj); public: /** * @brief get the number of sub element in the current one * @return the Number of stored element */ - size_t size() const { - return m_value.size(); - }; + size_t size() const; /** * @brief get the pointer on an element reference with his ID. * @param[in] _id Id of the element. * @return nullptr if the element does not exist. */ - ememory::SharedPtr get(size_t _id) { - return m_value[_id]; - }; - //! @previous - const ememory::SharedPtr get(size_t _id) const{ - return m_value[_id]; - }; - //! @previous - ememory::SharedPtr operator[] (size_t _id) { - return m_value[_id]; - } - //! @previous - const ememory::SharedPtr operator[] (size_t _id) const { - return m_value[_id]; - } - /** - * @brief get the pointer on an element reference with his ID (casted in Object if it is an object). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getObject(size_t _id); - //! @previous - const ememory::SharedPtr getObject(size_t _id) const; - /** - * @brief get the pointer on an element reference with his ID (casted in String if it is an String). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getString(size_t _id); - //! @previous - const ememory::SharedPtr getString(size_t _id) const; + ejson::Value operator[] (size_t _id); + const ejson::Value operator[] (size_t _id) const; /** * @brief get the value of the string element (if not a string return "") * @param[in] _id Id of the element. @@ -84,30 +61,6 @@ namespace ejson { * @return value of the element, or the _errorValue. */ std::string getStringValue(size_t _id, const std::string& _errorValue) const; - /** - * @brief get the pointer on an element reference with his ID (casted in Array if it is an Array). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getArray(size_t _id); - //! @previous - const ememory::SharedPtr getArray(size_t _id) const; - /** - * @brief get the pointer on an element reference with his ID (casted in Null if it is an Null). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getNull(size_t _id); - //! @previous - const ememory::SharedPtr getNull(size_t _id) const; - /** - * @brief get the pointer on an element reference with his ID (casted in Number if it is an Number). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getNumber(size_t _id); - //! @previous - const ememory::SharedPtr getNumber(size_t _id) const; /** * @brief get the value of the Number element * @param[in] _id Id of the element. @@ -115,14 +68,6 @@ namespace ejson { * @return value of the element, or the _errorValue. */ double getNumberValue(size_t _id, double _errorValue) const; - /** - * @brief get the pointer on an element reference with his ID (casted in Boolean if it is an Boolean). - * @param[in] _id Id of the element. - * @return nullptr if the element does not exist. - */ - ememory::SharedPtr getBoolean(size_t _id); - //! @previous - const ememory::SharedPtr getBoolean(size_t _id) const; /** * @brief get the value of the Boolean element * @param[in] _id Id of the element. @@ -135,7 +80,7 @@ namespace ejson { * @param[in] _element element to add. * @return false if an error occured. */ - bool add(ememory::SharedPtr _element); + bool add(const ejson::Value& _element); /** * @brief add a string element in the Object (automatic creation) * @param[in] _value string value to add @@ -159,13 +104,12 @@ namespace ejson { * @return false if an error occured */ bool addNumber(double _value); - - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual void clear(); - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual ememory::SharedPtr clone() const; + public: + using iterator = ejson::iterator; + iterator begin(); + iterator end(); + const iterator begin() const; + const iterator end() const; }; } diff --git a/ejson/Boolean.cpp b/ejson/Boolean.cpp index c53dcf7..5a76d87 100644 --- a/ejson/Boolean.cpp +++ b/ejson/Boolean.cpp @@ -8,75 +8,48 @@ #include #include -#include +#include -ememory::SharedPtr ejson::Boolean::create(bool _value) { - return ememory::SharedPtr(new ejson::Boolean(_value)); + +ejson::Boolean::Boolean(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isBoolean() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } } - -bool ejson::Boolean::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Boolean' "); - m_value=false; - if( _data[_pos] == 't' - && _pos+3 < _data.size() - && _data[_pos+1] == 'r' - && _data[_pos+2] == 'u' - && _data[_pos+3] == 'e'){ - m_value=true; - _pos+=3; - _filePos+=3; - return true; - } - if( _data[_pos] == 'f' - && _pos+4 < _data.size() - && _data[_pos+1] == 'a' - && _data[_pos+2] == 'l' - && _data[_pos+3] == 's' - && _data[_pos+4] == 'e'){ - m_value=false; - _pos+=4; - _filePos+=4; - return true; - } - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "boolean parsing error ..."); - return false; +ejson::Boolean::Boolean(const ejson::Boolean& _obj) : + ejson::Value(_obj.m_data) { + } - -bool ejson::Boolean::iGenerate(std::string& _data, size_t _indent) const { - if (true == m_value) { - _data += "true"; - } else { - _data += "false"; - } - return true; +ejson::Boolean::Boolean(bool _value) : + ejson::Value() { + m_data = ejson::internal::Boolean::create(_value); } +ejson::Boolean& ejson::Boolean::operator= (const ejson::Boolean& _obj) { + m_data = _obj.m_data; + return *this; +} -bool ejson::Boolean::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an NULL pointer"); +void ejson::Boolean::set(bool _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not set (nullptr) ..."); + return; + } + static_cast(m_data.get())->set(_value); +} + +bool ejson::Boolean::get() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not get (nullptr) ..."); return false; } - ememory::SharedPtr other = _obj->toBoolean(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an Boolean"); - return false; - } - // remove destination elements - other->m_value = m_value; - m_value = false; - return true; + return static_cast(m_data.get())->get(); } -ememory::SharedPtr ejson::Boolean::clone() const { - ememory::SharedPtr output = ejson::Boolean::create(m_value); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); - } - return output; -} - - diff --git a/ejson/Boolean.h b/ejson/Boolean.h index 7404ad1..9feda8f 100644 --- a/ejson/Boolean.h +++ b/ejson/Boolean.h @@ -12,44 +12,38 @@ namespace ejson { class Boolean : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - Boolean(bool _value=false) : - m_value(_value) { - - }; public: - static ememory::SharedPtr create(bool _value=false); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~Boolean() { - - }; - protected: - bool m_value; //!< value of the node + Boolean(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Boolean(const ejson::Boolean& _obj); + /** + * @brief Constructor + * @param[in] _value bool value to store + */ + Boolean(bool _value=false); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Boolean& operator= (const ejson::Boolean& _obj); public: /** * @brief set the value of the node. * @param[in] _value New value of the node. */ - void set(bool _value) { - m_value = _value; - }; + void set(bool _value); /** * @brief get the current element Value. * @return the reference of the string value. */ - bool get() const { - return m_value; - }; - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual ememory::SharedPtr clone() const; + bool get() const; }; } diff --git a/ejson/Document.cpp b/ejson/Document.cpp new file mode 100644 index 0000000..766f034 --- /dev/null +++ b/ejson/Document.cpp @@ -0,0 +1,92 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#include +#include +#include + +ejson::Document::Document(ememory::SharedPtr _internalValue) : + ejson::Object(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isDocument() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } +} + +ejson::Document::Document(const ejson::Document& _obj) : + ejson::Object(_obj.m_data) { + +} + +ejson::Document::Document() : + ejson::Object() { + m_data = ejson::internal::Document::create(); +} + +ejson::Document& ejson::Document::operator= (const ejson::Document& _obj) { + m_data = _obj.m_data; + return *this; +} + +bool ejson::Document::parse(const std::string& _data) { + if (m_data == nullptr) { + EJSON_ERROR("Can not parse (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->parse(_data); +} + +bool ejson::Document::generate(std::string& _data) { + if (m_data == nullptr) { + EJSON_ERROR("Can not generate (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->generate(_data); +} + +bool ejson::Document::load(const std::string& _file) { + if (m_data == nullptr) { + EJSON_ERROR("Can not load (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->load(_file); +} + +bool ejson::Document::store(const std::string& _file) { + if (m_data == nullptr) { + EJSON_ERROR("Can not store (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->store(_file); +} + +void ejson::Document::displayErrorWhenDetected() { + if (m_data == nullptr) { + EJSON_ERROR("Can not displayErrorWhenDetected (nullptr) ..."); + return; + } + static_cast(m_data.get())->displayErrorWhenDetected(); +} + +void ejson::Document::notDisplayErrorWhenDetected() { + if (m_data == nullptr) { + EJSON_ERROR("Can not notDisplayErrorWhenDetected (nullptr) ..."); + return; + } + static_cast(m_data.get())->notDisplayErrorWhenDetected(); +} + +void ejson::Document::displayError() { + if (m_data == nullptr) { + EJSON_ERROR("Can not displayError (nullptr) ..."); + return; + } + static_cast(m_data.get())->displayError(); +} diff --git a/ejson/Document.h b/ejson/Document.h new file mode 100644 index 0000000..7f10c8d --- /dev/null +++ b/ejson/Document.h @@ -0,0 +1,74 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace ejson { + class Document : public ejson::Object { + public: + /** + * @brief Constructor + * @param[in] _internalValue Internal Value to set data + */ + Document(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Document(const ejson::Document& _obj); + /** + * @brief Constructor + */ + Document(); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Document& operator= (const ejson::Document& _obj); + public: + /** + * @brief parse a string that contain an XML + * @param[in] _data Data to parse + * @return false : An error occured + * @return true : Parsing is OK + */ + bool parse(const std::string& _data); + /** + * @brief generate a string that contain the created XML + * @param[out] _data Data where the xml is stored + * @return false : An error occured + * @return true : Parsing is OK + */ + bool generate(std::string& _data); + /** + * @brief Load the file that might contain the xml + * @param[in] _file Filename of the xml (compatible with etk FSNode naming) + * @return false : An error occured + * @return true : Parsing is OK + */ + bool load(const std::string& _file); + /** + * @brief Store the Xml in the file + * @param[in] _file Filename of the xml (compatible with etk FSNode naming) + * @return false : An error occured + * @return true : Parsing is OK + */ + bool store(const std::string& _file); + public: + void displayErrorWhenDetected(); + void notDisplayErrorWhenDetected(); + void displayError(); + }; +} + diff --git a/ejson/Null.cpp b/ejson/Null.cpp index 3abfdc3..5252717 100644 --- a/ejson/Null.cpp +++ b/ejson/Null.cpp @@ -5,61 +5,33 @@ * * @license APACHE v2.0 (see license file) */ - #include #include -#include +#include -ememory::SharedPtr ejson::Null::create() { - return ememory::SharedPtr(new ejson::Null()); +ejson::Null::Null(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isNull() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } } - -bool ejson::Null::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Null' "); - if (_pos+3 >= _data.size()){ - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "can not parse null !!! "); - return false; - } - if( _data[_pos] != 'n' - || _data[_pos+1] != 'u' - || _data[_pos+2] != 'l' - || _data[_pos+3] != 'l' ) { - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "Not a corect 'null' element"); - return false; - } - _pos+=4; - _filePos+=4; - return true; +ejson::Null::Null(const ejson::Null& _obj) : + ejson::Value(_obj.m_data) { + } - -bool ejson::Null::iGenerate(std::string& _data, size_t _indent) const { - _data += "null"; - return true; +ejson::Null::Null() : + ejson::Value() { + m_data = ejson::internal::Null::create(); } - -bool ejson::Null::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an nullptr pointer"); - return false; - } - ememory::SharedPtr other = _obj->toNull(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an Null"); - return false; - } - return true; +ejson::Null& ejson::Null::operator= (const ejson::Null& _obj) { + m_data = _obj.m_data; + return *this; } -ememory::SharedPtr ejson::Null::clone() const { - ememory::SharedPtr output = ejson::Null::create(); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); - } - return output; -} - - diff --git a/ejson/Null.h b/ejson/Null.h index 8e84d92..1d12f92 100644 --- a/ejson/Null.h +++ b/ejson/Null.h @@ -12,22 +12,26 @@ namespace ejson { class Null : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - Null() { }; public: - static ememory::SharedPtr create(); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~Null() { }; - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual ememory::SharedPtr clone() const; + Null(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Null(const ejson::Null& _obj); + /** + * @brief Constructor + */ + Null(); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Null& operator= (const ejson::Null& _obj); }; } diff --git a/ejson/Number.cpp b/ejson/Number.cpp index 88d4ff3..8643e1f 100644 --- a/ejson/Number.cpp +++ b/ejson/Number.cpp @@ -5,74 +5,74 @@ * * @license APACHE v2.0 (see license file) */ - - #include #include -#include +#include -ememory::SharedPtr ejson::Number::create(double _value) { - return ememory::SharedPtr(new ejson::Number(_value)); + +ejson::Number::Number(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isNumber() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } } -bool ejson::Number::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Number' "); - std::string tmpVal; - for (size_t iii=_pos; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - if(true == checkNumber(_data[iii])) { - tmpVal+=_data[iii]; - } else { - _pos = iii-1; - m_value = etk::string_to_double(tmpVal); - JSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> " << m_value); - return true; - } - } - _pos=_data.size(); - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); - return false; +ejson::Number::Number(const ejson::Number& _obj) : + ejson::Value(_obj.m_data) { + } - -bool ejson::Number::iGenerate(std::string& _data, size_t _indent) const { - // special thing to remove .000000 at the end of perfect number ... - int64_t tmpVal = m_value; - if ((double)tmpVal == m_value) { - _data += etk::to_string(tmpVal); - } else { - _data += etk::to_string(m_value); - } - return true; +ejson::Number::Number(double _value) : + ejson::Value() { + m_data = ejson::internal::Number::create(_value); } - -bool ejson::Number::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an nullptr pointer"); - return false; - } - ememory::SharedPtr other = _obj->toNumber(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an Number"); - return false; - } - // remove destination elements - other->m_value = m_value; - m_value = 0; - return true; +ejson::Number& ejson::Number::operator= (const ejson::Number& _obj) { + m_data = _obj.m_data; + return *this; } -ememory::SharedPtr ejson::Number::clone() const { - ememory::SharedPtr output = ejson::Number::create(m_value); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); +void ejson::Number::set(double _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not set (nullptr) ..."); + return; } - return output; + static_cast(m_data.get())->set(_value); } +double ejson::Number::get() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not parse (nullptr) ..."); + return 0.0; + } + return static_cast(m_data.get())->get(); +} + +double ejson::Number::get(double _errorValue) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not parse (nullptr) ..."); + return _errorValue; + } + return static_cast(m_data.get())->get(); +} + +int32_t ejson::Number::getInt32() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not getInt32 (nullptr) ..."); + return 0; + } + return static_cast(m_data.get())->getInt32(); +} + +int64_t ejson::Number::getInt64() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not getInt64 (nullptr) ..."); + return 0; + } + return static_cast(m_data.get())->getInt64(); +} diff --git a/ejson/Number.h b/ejson/Number.h index 4ccfc33..e5d4c7e 100644 --- a/ejson/Number.h +++ b/ejson/Number.h @@ -12,56 +12,55 @@ namespace ejson { class Number : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - Number(double _value=0.0) : - m_value(_value) { - - }; public: - static ememory::SharedPtr create(double _value=0.0); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~Number() { }; - protected: - double m_value; //!< value of the node + Number(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Number(const ejson::Number& _obj); + /** + * @brief Constructor + * @param[in] _value number value + */ + Number(double _value=0.0); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Number& operator= (const ejson::Number& _obj); + public: /** * @brief set the value of the node. * @param[in] _value New value of the node. */ - void set(double _value) { - m_value = _value; - }; + void set(double _value); /** * @brief Get the current element Value. * @return The double number registered */ - double get() const { - return m_value; - }; + double get() const; + /** + * @brief Get the current element Value. + * @param[in] _errorValue Value return if no value Exist + * @return The double number registered + */ + double get(double _errorValue) const; /** * @brief Get the current element Value. * @return The 32 bit integer number registered */ - int32_t getInt32() const { - return (int32_t)m_value; - }; + int32_t getInt32() const; /** * @brief Get the current element Value. * @return The 64 bit integer number registered */ - int64_t getInt64() const { - return (int64_t)m_value; - }; - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual ememory::SharedPtr clone() const; + int64_t getInt64() const; }; } diff --git a/ejson/Object.cpp b/ejson/Object.cpp index 9ded300..cea4562 100644 --- a/ejson/Object.cpp +++ b/ejson/Object.cpp @@ -5,504 +5,198 @@ * * @license APACHE v2.0 (see license file) */ - - #include -#include -#include -#include -#include -#include #include -#include +#include -ememory::SharedPtr ejson::Object::create() { - return ememory::SharedPtr(new ejson::Object()); -} -ememory::SharedPtr ejson::Object::create(const std::string& _data) { - ejson::Document doc; - doc.parse(_data); - return doc.cloneObj(); +ejson::Object::Object(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; + } + if (m_data->isObject() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; + } + } - -void ejson::Object::clear() { - m_value.clear(); +ejson::Object::Object(const ejson::Object& _obj) : + ejson::Value(_obj.m_data) { + } - -enum statusParsing { - parseName, - parseMiddle, - parseValue, -}; - -bool ejson::Object::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - enum statusParsing mode = parseName; - std::string currentName; - JSON_PARSE_ELEMENT("start parse : 'Object' "); - bool standalone = true; - size_t startPos = _pos+1; - if (_data[_pos] != '{' ) { // when the main node call it, it can be start with != '{' - standalone = false; - startPos = _pos; - } - for (size_t iii=startPos; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - ejson::FilePos tmpPos; - if( _data[iii] == ' ' - || _data[iii] == '\t' - || _data[iii] == '\n' - || _data[iii] == '\r') { - // white space == > nothing to do ... - } else if(_data[iii] == '#') { - // comment Line ... - for (iii++; iii<_data.size(); iii++) { - if( _data[iii] == '\n' - || _data[iii] == '\r') { - break; - } - } - } else if(_data[iii] == '}') { - // find end of value: - _pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed - return true; - } else { - if (mode == parseName) { - JSON_PARSE_ELEMENT("name START " << '"'); - if ( _data[iii] == '"' - || _data[iii] == '\'') { - char startValue=_data[iii]; - currentName = ""; - for (iii++; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - if (_data[iii] == startValue) { - mode = parseMiddle; - break; - } else { - currentName += _data[iii]; - } - } - } else if (checkString(_data[iii]) ) { - currentName += _data[iii]; - for (iii++; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - if (false == checkString(_data[iii])) { - mode = parseMiddle; - iii--; - break; - } else { - currentName += _data[iii]; - } - } - } else { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "element unknow ..."); - _pos = iii; - return false; - } - JSON_PARSE_ELEMENT("name END "); - } else if (mode == parseMiddle) { - JSON_PARSE_ELEMENT(" middle ... "); - if (_data[iii] == ':') { - mode = parseValue; - } else { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "separator is not ':'"); - return false; - } - } else if (mode == parseValue) { - if (_data[iii] == '{') { - // find an object: - JSON_PARSE_ELEMENT("find Object"); - ememory::SharedPtr tmpElement = ejson::Object::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in object"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if ( _data[iii] == '"' - || _data[iii] == '\'') { - // find a string: - JSON_PARSE_ELEMENT("find String quoted"); - ememory::SharedPtr tmpElement = ejson::String::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if (_data[iii] == '[') { - // find a list: - JSON_PARSE_ELEMENT("find List"); - ememory::SharedPtr tmpElement = ejson::Array::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Array"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if( _data[iii] == 'f' - || _data[iii] == 't' ) { - // find boolean: - JSON_PARSE_ELEMENT("find Boolean"); - ememory::SharedPtr tmpElement = ejson::Boolean::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if( _data[iii] == 'n') { - // find null: - JSON_PARSE_ELEMENT("find Null"); - ememory::SharedPtr tmpElement = ejson::Null::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if(true == checkNumber(_data[iii])) { - // find number: - JSON_PARSE_ELEMENT("find Number"); - ememory::SharedPtr tmpElement = ejson::Number::create(); - if (tmpElement == nullptr) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->iParse(_data, iii, _filePos, _doc); - add(currentName, tmpElement); - currentName = ""; - } else if(_data[iii] == ',') { - // find Separator : Restart cycle ... - mode = parseName; - currentName = ""; - } else { - // find an error .... - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, std::string("Find '") + _data[iii] + "' with no element in the element..."); - // move the curent index - _pos = iii+1; - return false; - } - } - } - } - _pos = _data.size(); - if (false == standalone) { - return true; - } - return false; -} -bool ejson::Object::iGenerate(std::string& _data, size_t _indent) const { - bool oneLine=true; - if (m_value.size()>3) { - oneLine=false; - } else if (_indent<=1) { - oneLine=false; - } else { - for (int32_t iii=0; iii tmp = m_value[iii]; - if (tmp == nullptr) { - continue; - } - if (tmp->isObject() == true) { - oneLine=false; - break; - } - if (tmp->isArray() == true) { - oneLine=false; - break; - } - if (tmp->isString() == true) { - ememory::SharedPtr tmp2 = tmp->toString(); - if (tmp2 != nullptr) { - if( tmp2->get().size()>25 - || m_value.getKey(iii).size()>25) { - oneLine=false; - break; - } - } - } - } - } - if (true == oneLine) { - _data += "{ "; - } else { - _data += "{\n"; - } - for (int32_t iii=0; iiiiGenerate(_data, _indent+1); - if (iii ejson::Object::get(const std::string& _name) { - if (false == m_value.exist(_name)) { - return ememory::SharedPtr(); - } - return m_value[_name]; +ejson::Object& ejson::Object::operator= (const ejson::Object& _obj) { + m_data = _obj.m_data; + return *this; } -const ememory::SharedPtr ejson::Object::get(const std::string& _name) const { - if (false == m_value.exist(_name)) { - return ememory::SharedPtr(); +bool ejson::Object::valueExist(const std::string& _name) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not exist (nullptr) ..."); + return false; } - return m_value[_name]; + return static_cast(m_data.get())->exist(_name); } -ememory::SharedPtr ejson::Object::getObject(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +ejson::Value ejson::Object::operator[] (const std::string& _name) { + if (m_data == nullptr) { + EJSON_ERROR("Can not operator[] (nullptr) ..."); + return ejson::Value(nullptr); } - return std::dynamic_pointer_cast(tmp); + return ejson::Value(static_cast(m_data.get())->get(_name)); } -const ememory::SharedPtr ejson::Object::getObject(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +const ejson::Value ejson::Object::operator[] (const std::string& _name) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not operator[] (nullptr) ..."); + return ejson::Value(nullptr); } - return std::dynamic_pointer_cast(tmp); + return ejson::Value(static_cast(m_data.get())->get(_name)); } -ememory::SharedPtr ejson::Object::getArray(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +std::vector ejson::Object::getKeys() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not getKeys (nullptr) ..."); + return std::vector(); } - return std::dynamic_pointer_cast(tmp); + return static_cast(m_data.get())->getKeys(); } -const ememory::SharedPtr ejson::Object::getArray(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +size_t ejson::Object::size() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not size (nullptr) ..."); + return 0; } - return std::dynamic_pointer_cast(tmp); + return static_cast(m_data.get())->size(); } -ememory::SharedPtr ejson::Object::getNull(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +ejson::Value ejson::Object::operator[] (size_t _id) { + if (m_data == nullptr) { + EJSON_ERROR("Can not operator[] (nullptr) ..."); + return ejson::Value(nullptr); } - return std::dynamic_pointer_cast(tmp); + return ejson::Value(static_cast(m_data.get())->get(_id)); } -const ememory::SharedPtr ejson::Object::getNull(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +const ejson::Value ejson::Object::operator[] (size_t _id) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not operator[] (nullptr) ..."); + return ejson::Value(nullptr); } - return std::dynamic_pointer_cast(tmp); + return ejson::Value(static_cast(m_data.get())->get(_id)); } -ememory::SharedPtr ejson::Object::getString(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); +std::string ejson::Object::getKey(size_t _id) const { + if (m_data == nullptr) { + EJSON_ERROR("Can not getKey (nullptr) ..."); + return ""; } - return std::dynamic_pointer_cast(tmp); -} - -const ememory::SharedPtr ejson::Object::getString(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); - } - return std::dynamic_pointer_cast(tmp); + return static_cast(m_data.get())->getKey(_id); } const std::string& ejson::Object::getStringValue(const std::string& _name) const { - static const std::string errorString(""); - const ememory::SharedPtr tmpp = getString(_name); - if (tmpp == nullptr) { + if (m_data == nullptr) { + static const std::string errorString = ""; + EJSON_ERROR("Can not getStringValue (nullptr) ..."); return errorString; } - return tmpp->get(); + return static_cast(m_data.get())->getStringValue(_name); } std::string ejson::Object::getStringValue(const std::string& _name, const std::string& _errorValue) const { - const ememory::SharedPtr tmpp = getString(_name); - if (tmpp == nullptr) { - return _errorValue; + if (m_data == nullptr) { + EJSON_ERROR("Can not getStringValue (nullptr) ..."); + return ""; } - return tmpp->get(); -} - -ememory::SharedPtr ejson::Object::getBoolean(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); - } - return tmp->toBoolean(); -} - -const ememory::SharedPtr ejson::Object::getBoolean(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); - } - return tmp->toBoolean(); + return static_cast(m_data.get())->getStringValue(_name, _errorValue); } bool ejson::Object::getBooleanValue(const std::string& _name, bool _errorValue) const { - const ememory::SharedPtr tmpp = getBoolean(_name); - if (tmpp == nullptr) { - return _errorValue; + if (m_data == nullptr) { + EJSON_ERROR("Can not getBooleanValue (nullptr) ..."); + return false; } - return tmpp->get(); -} - -ememory::SharedPtr ejson::Object::getNumber(const std::string& _name) { - ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); - } - return tmp->toNumber(); -} - -const ememory::SharedPtr ejson::Object::getNumber(const std::string& _name) const { - const ememory::SharedPtr tmp = get(_name); - if (tmp == nullptr) { - return ememory::SharedPtr(); - } - return tmp->toNumber(); + return static_cast(m_data.get())->getBooleanValue(_name, _errorValue); } double ejson::Object::getNumberValue(const std::string& _name, double _errorValue) const { - const ememory::SharedPtr tmpp = getNumber(_name); - if (tmpp == nullptr) { - return _errorValue; + if (m_data == nullptr) { + EJSON_ERROR("Can not getNumberValue (nullptr) ..."); + return 0.0; } - return tmpp->get(); + return static_cast(m_data.get())->getNumberValue(_name, _errorValue); } - -bool ejson::Object::add(const std::string& _name, ememory::SharedPtr _value) { - if (_value == nullptr) { +bool ejson::Object::add(const std::string& _name, const ejson::Value& _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not add (nullptr) ..."); return false; } - if (_name.size() == 0) { - return false; - } - if (m_value.exist(_name)) { - m_value[_name] = _value; - return true; - } - m_value.add(_name, _value); - return true; + return static_cast(m_data.get())->add(_name, _value.m_data); } bool ejson::Object::addString(const std::string& _name, const std::string& _value) { - return add(_name, ejson::String::create(_value)); + if (m_data == nullptr) { + EJSON_ERROR("Can not addString (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addString(_name, _value); } bool ejson::Object::addNull(const std::string& _name) { - return add(_name, ejson::Null::create()); + if (m_data == nullptr) { + EJSON_ERROR("Can not addNull (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addNull(_name); } bool ejson::Object::addBoolean(const std::string& _name, bool _value) { - return add(_name, ejson::Boolean::create(_value)); + if (m_data == nullptr) { + EJSON_ERROR("Can not addBoolean (nullptr) ..."); + return false; + } + return static_cast(m_data.get())->addBoolean(_name, _value); } bool ejson::Object::addNumber(const std::string& _name, double _value) { - return add(_name, ejson::Number::create(_value)); -} - -bool ejson::Object::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an nullptr pointer"); + if (m_data == nullptr) { + EJSON_ERROR("Can not addNumber (nullptr) ..."); return false; } - ememory::SharedPtr other = _obj->toObject(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an object"); - return false; - } - // remove destination elements - other->clear(); - // Copy to the destination - other->m_value = m_value; - // remove current: - m_value.clear(); - return true; -} - -bool ejson::Object::cloneIn(const ememory::SharedPtr& _obj) const { - if (_obj == nullptr) { - return false; - } - _obj->clear(); - for (int32_t iii=0; iiiadd(m_value.getKey(iii), m_value[iii]->clone()); - } - return true; + return static_cast(m_data.get())->addNumber(_name, _value); } -// TODO : Manage error ... -ememory::SharedPtr ejson::Object::clone() const { - return cloneObj(); +ejson::Object::iterator ejson::Object::begin() { + return ejson::Object::iterator(*this, 0); } -ememory::SharedPtr ejson::Object::cloneObj() const { - ememory::SharedPtr output = ejson::Object::create(); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); - } - for (int32_t iii=0; iii val = m_value.getValue(iii); - std::string key = m_value.getKey(iii); - if (val == nullptr) { - continue; - } - output->add(key, val->clone()); - } - return output; +ejson::Object::iterator ejson::Object::end() { + return ejson::Object::iterator(*this, size()); } + +const ejson::Object::iterator ejson::Object::begin() const { + return ejson::Object::iterator(*this, 0); +} + +const ejson::Object::iterator ejson::Object::end() const { + return ejson::Object::iterator(*this, size()); +} + +#include + +template class ejson::iterator; + diff --git a/ejson/Object.h b/ejson/Object.h index af15b5d..bb1582a 100644 --- a/ejson/Object.h +++ b/ejson/Object.h @@ -11,129 +11,74 @@ #include #include #include +#include namespace ejson { class Object : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - Object() { }; public: - static ememory::SharedPtr create(); - static ememory::SharedPtr create(const std::string& _data); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~Object() { }; - protected: - etk::Hash > m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) + Object(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Object(const ejson::Object& _obj); + /** + * @brief Constructor + */ + Object(); + /** + * @brief Constructor + * @param[in] _data string data to parse + */ + Object(const std::string& _data); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::Object& operator= (const ejson::Object& _obj); + public: /** * @brief check if an element exist. * @param[in] _name name of the object. * @return The existance of the element. */ - bool exist(const std::string& _name) const; + bool valueExist(const std::string& _name) const; /** * @brief get the sub element with his name (no cast check) * @param[in] _name name of the object * @return pointer on the element requested or nullptr if it not the corect type or does not existed */ - ememory::SharedPtr get(const std::string& _name); - //! @previous - const ememory::SharedPtr get(const std::string& _name) const; - //! @previous - ememory::SharedPtr operator[] (const std::string& _name) { - return get(_name); - } - //! @previous - const ememory::SharedPtr operator[] (const std::string& _name) const { - return get(_name); - } + ejson::Value operator[] (const std::string& _name); + const ejson::Value operator[] (const std::string& _name) const; public: /** * @brief Get all the element name (keys). * @return a vector of all name (key). */ - std::vector getKeys() const { - return m_value.getKeys(); - } + std::vector getKeys() const; /** * @brief get the number of sub element in the current one * @return the Number of stored element */ - size_t size() const { - return m_value.size(); - }; + size_t size() const; /** * @brief get the pointer on an element reference with his ID. * @param[in] _id Id of the element. * @return nullptr if the element does not exist. */ - ememory::SharedPtr get(size_t _id) { - return m_value[_id]; - }; - //! @previous - const ememory::SharedPtr get(size_t _id) const{ - return m_value[_id]; - }; - //! @previous - ememory::SharedPtr operator[] (size_t _id) { - return m_value[_id]; - } - //! @previous - const ememory::SharedPtr operator[] (size_t _id) const { - return m_value[_id]; - } + ejson::Value operator[] (size_t _id); + const ejson::Value operator[] (size_t _id) const; /** * @brief Get the element name (key). * @param[in] _id Id of the element. * @return The name (key). */ - std::string getKey(size_t _id) const { - return m_value.getKey(_id); - } - /** - * @brief get the sub element with his name (Casted as Object if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getObject(const std::string& _name); - /** - * @brief get the sub element with his name (Casted as Object if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - const ememory::SharedPtr getObject(const std::string& _name) const; - /** - * @brief get the sub element with his name (Casted as Array if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getArray(const std::string& _name); - /** - * @brief get the sub element with his name (Casted as Array if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - const ememory::SharedPtr getArray(const std::string& _name) const; - /** - * @brief get the sub element with his name (Casted as Null if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getNull(const std::string& _name); - //! @previous - const ememory::SharedPtr getNull(const std::string& _name) const; - /** - * @brief get the sub element with his name (Casted as String if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getString(const std::string& _name); - //! @previous - const ememory::SharedPtr getString(const std::string& _name) const; + std::string getKey(size_t _id) const; /** * @brief get the sub string value of the requested element * @param[in] _name name of the object @@ -147,14 +92,6 @@ namespace ejson { * @return Value of the string or an error string (empty) */ std::string getStringValue(const std::string& _name, const std::string& _errorValue) const; - /** - * @brief get the sub element with his name (Casted as Boolean if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getBoolean(const std::string& _name); - //! @previous - const ememory::SharedPtr getBoolean(const std::string& _name) const; /** * @brief get the sub boolean value of the requested element. * @param[in] _name name of the object. @@ -162,14 +99,6 @@ namespace ejson { * @return Value of the Boolean or the _errorValue; */ bool getBooleanValue(const std::string& _name, bool _errorValue=false) const; - /** - * @brief get the sub element with his name (Casted as Number if it is possible) - * @param[in] _name name of the object - * @return pointer on the element requested or nullptr if it not the corect type or does not existed - */ - ememory::SharedPtr getNumber(const std::string& _name); - //! @previous - const ememory::SharedPtr getNumber(const std::string& _name) const; /** * @brief get the sub Number value of the requested element. * @param[in] _name name of the object. @@ -184,7 +113,7 @@ namespace ejson { * @param[in] _value Element to add * @return false if an error occured */ - bool add(const std::string& _name, ememory::SharedPtr _value); + bool add(const std::string& _name, const ejson::Value& _value); /** * @brief add a string element in the Object (automatic creation) * @param[in] _name name of the object @@ -212,14 +141,12 @@ namespace ejson { * @return false if an error occured */ bool addNumber(const std::string& _name, double _value); - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual void clear(); - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual bool cloneIn(const ememory::SharedPtr& _obj) const; - virtual ememory::SharedPtr clone() const; - virtual ememory::SharedPtr cloneObj() const; + public: + using iterator = ejson::iterator; + iterator begin(); + iterator end(); + const iterator begin() const; + const iterator end() const; }; } diff --git a/ejson/String.cpp b/ejson/String.cpp index 7986b9c..f93cfbe 100644 --- a/ejson/String.cpp +++ b/ejson/String.cpp @@ -5,71 +5,49 @@ * * @license APACHE v2.0 (see license file) */ - - -#include -#include #include #include -#include +#include -ememory::SharedPtr ejson::String::create(const std::string& _value) { - return ememory::SharedPtr(new ejson::String(_value)); -} - -bool ejson::String::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'String' "); - char end = _data[_pos]; - for (size_t iii=_pos+1; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - #ifdef ENABLE_DISPLAY_PARSED_ELEMENT - drawElementParsed(_data[iii], _filePos); - #endif - ejson::FilePos tmpPos; - // TODO : manage \x - if(_data[iii] != end) { - m_value += _data[iii]; - } else { - _pos = iii; - return true; - } +ejson::String::String(ememory::SharedPtr _internalValue) : + ejson::Value(_internalValue) { + if (m_data == nullptr) { + return; } - _pos=_data.size(); - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); - return false; -} - - -bool ejson::String::iGenerate(std::string& _data, size_t _indent) const { - _data += "\"";; - _data += m_value; - _data += "\"";; - return true; -} - - -bool ejson::String::transfertIn(ememory::SharedPtr _obj) { - if (_obj == nullptr) { - JSON_ERROR("Request transfer on an nullptr pointer"); - return false; + if (m_data->isString() == false) { + // try to set wrong type inside ... ==> remove it ... + m_data = nullptr; } - ememory::SharedPtr other = _obj->toString(); - if (other == nullptr) { - JSON_ERROR("Request transfer on an element that is not an String"); - return false; - } - other->m_value = m_value; - m_value = ""; - return true; } -ememory::SharedPtr ejson::String::clone() const { - ememory::SharedPtr output = ejson::String::create(m_value); - if (output == nullptr) { - JSON_ERROR("Allocation error ..."); - return ememory::SharedPtr(); - } - return output; +ejson::String::String(const ejson::String& _obj) : + ejson::Value(_obj.m_data) { + } +ejson::String::String(const std::string& _value) : + ejson::Value() { + m_data = ejson::internal::String::create(_value); +} +ejson::String& ejson::String::operator= (const ejson::String& _obj) { + m_data = _obj.m_data; + return *this; +} + +void ejson::String::set(const std::string& _value) { + if (m_data == nullptr) { + EJSON_ERROR("Can not set (nullptr) ..."); + return; + } + static_cast(m_data.get())->set(_value); +} + +const std::string& ejson::String::get() const { + if (m_data == nullptr) { + static const std::string errorValue = ""; + EJSON_ERROR("Can not get (nullptr) ..."); + return errorValue; + } + return static_cast(m_data.get())->get(); +} diff --git a/ejson/String.h b/ejson/String.h index 5c65ccd..9dfc519 100644 --- a/ejson/String.h +++ b/ejson/String.h @@ -12,42 +12,38 @@ namespace ejson { class String : public ejson::Value { - protected: - /** - * @brief basic element of a xml structure - */ - String(const std::string& _value="") : - m_value(_value) { - - }; public: - static ememory::SharedPtr create(const std::string& _value=""); /** - * @brief destructor + * @brief Constructor + * @param[in] _internalValue Internal Value to set data */ - virtual ~String() { }; - protected: - std::string m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) + String(ememory::SharedPtr _internalValue); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + String(const ejson::String& _obj); + /** + * @brief Constructor + * @param[in] _value String value to set + */ + String(const std::string& _value=""); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + ejson::String& operator= (const ejson::String& _obj); public: /** * @brief set the value of the node. * @param[in] _value New value of the node. */ - void set(const std::string& _value) { - m_value = _value; - }; + void set(const std::string& _value); /** * @brief get the current element Value. * @return the reference of the string value. */ - const std::string& get() const { - return m_value; - }; - public: // herited function : - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - virtual bool transfertIn(ememory::SharedPtr _obj); - virtual ememory::SharedPtr clone() const; + const std::string& get() const; }; } diff --git a/ejson/Value.cpp b/ejson/Value.cpp index 504b508..f49b5ac 100644 --- a/ejson/Value.cpp +++ b/ejson/Value.cpp @@ -8,198 +8,190 @@ #include #include -#include +#include +#include -ejson::Value::~Value() { - clear(); +ejson::Value ejson::empty() { + return ejson::Value(ememory::SharedPtr(nullptr)); } -bool ejson::Value::isWhiteChar(char32_t _val) { - if( _val == ' ' - || _val == '\t' - || _val == '\n' - || _val == '\r') { - return true; + + +std::ostream& ejson::operator <<(std::ostream& _os, const ejson::Value& _obj) { + _os << "{"; + _os << "Value JSON: " << _obj.getType(); + /* + if (_obj.isObject() == true) { + _os << " <" << _obj.getValue() << ">"; + }; + */ + _os << "}"; + return _os; +} + +enum ejson::valueType ejson::Value::getType() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not get type ..."); + return ejson::valueType::unknow; } - return false; + return m_data->getType(); } -void ejson::Value::addIndent(std::string& _data, size_t _indent) const { - for (size_t iii=0; iii<_indent; iii++) { - _data+="\t"; - } -} - -void ejson::Value::drawElementParsed(char32_t _val, const ejson::FilePos& _filePos) const { - if (_val == '\n') { - JSON_DEBUG(_filePos << " parse '\\n'"); - } else if (_val == '\t') { - JSON_DEBUG(_filePos << " parse '\\t'"); - } else { - JSON_DEBUG(_filePos << " parse '" << _val << "'"); - } -} - -int32_t ejson::Value::countWhiteChar(const std::string& _data, size_t _pos, ejson::FilePos& _filePos) const { - _filePos.clear(); - size_t white=0; - for (size_t iii=_pos; iii<_data.size(); iii++) { - _filePos.check(_data[iii]); - if(true == isWhiteChar(_data[iii])) { - white++; - } else { - break; - } - } - --_filePos; - return white; -} - -bool ejson::Value::checkString(char32_t _val) const { - if( _val == '!' - || _val == '"' - || _val == '#' - || _val == '$' - || _val == '%' - || _val == '&' - || _val == '\'' // ' - || _val == '(' - || _val == ')' - || _val == '*' - || _val == '+' - || _val == ',' - || _val == '/' - || _val == ':' - || _val == ';' - || _val == '<' - || _val == '=' - || _val == '>' - || _val == '?' - || _val == '@' - || _val == '[' - || _val == '\\' - || _val == ']' - || _val == '^' - || _val == '`' - || _val == '{' - || _val == '|' - || _val == '}' - || _val == '~' - || _val == ' ' - || _val == '\n' - || _val == '\t' - || _val == '\r') { +bool ejson::Value::exist() const { + if (m_data == nullptr) { return false; } return true; } -bool ejson::Value::checkNumber(char32_t _val) const { - if( _val == '-' - || _val == '+' - || _val == 'e' - || _val == '.' - || ( _val>='0' - && _val<='9' ) ) { - return true; +/* +ejson::FilePos ejson::Value::getPos() const { + if (m_data == nullptr) { + return ejson::FilePos(0,0); } - return false; + return m_data->getPos(); +} +*/ + +ejson::Value::Value(const ememory::SharedPtr& _internalValue) : + m_data(_internalValue) { + // nothing to DO ... } -ememory::SharedPtr ejson::Value::toValue() { - return shared_from_this(); -}; -const ememory::SharedPtr ejson::Value::toValue() const { - return shared_from_this(); -}; -ememory::SharedPtr ejson::Value::toDocument() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toDocument() const { - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toArray() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toArray() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toObject() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toObject() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toString() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toString() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toNumber() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toNumber() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toBoolean() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toBoolean() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; -ememory::SharedPtr ejson::Value::toNull() { - return std::dynamic_pointer_cast(shared_from_this()); -}; -const ememory::SharedPtr ejson::Value::toNull() const{ - return std::dynamic_pointer_cast(shared_from_this()); -}; +ejson::Value::Value() : + m_data(nullptr) { + +} + +ejson::Document ejson::Value::toDocument() { + return ejson::Document(m_data); +} +const ejson::Document ejson::Value::toDocument() const { + return ejson::Document(m_data); +} + +ejson::Array ejson::Value::toArray() { + return ejson::Array(m_data); +} +const ejson::Array ejson::Value::toArray() const{ + return ejson::Array(m_data); +} + +ejson::Object ejson::Value::toObject() { + return ejson::Object(m_data); +} +const ejson::Object ejson::Value::toObject() const{ + return ejson::Object(m_data); +} + +ejson::String ejson::Value::toString() { + return ejson::String(m_data); +} +const ejson::String ejson::Value::toString() const{ + return ejson::String(m_data); +} + +ejson::Number ejson::Value::toNumber() { + return ejson::Number(m_data); +} +const ejson::Number ejson::Value::toNumber() const{ + return ejson::Number(m_data); +} + +ejson::Boolean ejson::Value::toBoolean() { + return ejson::Boolean(m_data); +} +const ejson::Boolean ejson::Value::toBoolean() const{ + return ejson::Boolean(m_data); +} + +ejson::Null ejson::Value::toNull() { + return ejson::Null(m_data); +} +const ejson::Null ejson::Value::toNull() const{ + return ejson::Null(m_data); +} void ejson::Value::display() const { - std::string tmpp; - iGenerate(tmpp, 0); - JSON_INFO("Generated JSON : \n" << tmpp); + if (m_data == nullptr) { + EJSON_ERROR("Can not Display (nullptr) ..."); + return; + } + return m_data->display(); } bool ejson::Value::isDocument() const { - return toDocument() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isDocument(); } bool ejson::Value::isArray() const { - return toArray() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isArray(); } bool ejson::Value::isObject() const { - return toObject() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isObject(); } bool ejson::Value::isString() const { - return toString() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isString(); } bool ejson::Value::isNumber() const { - return toNumber() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isNumber(); } bool ejson::Value::isBoolean() const { - return toBoolean() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isBoolean(); } bool ejson::Value::isNull() const { - return toNull() != nullptr; + if (m_data == nullptr) { + return false; + } + return m_data->isNull(); } void ejson::Value::clear() { - + if (m_data == nullptr) { + EJSON_ERROR("Can not Clean (nullptr) ..."); + return; + } + return m_data->clear(); } -bool ejson::Value::transfertIn(ememory::SharedPtr _obj) { - return false; +bool ejson::Value::transfertIn(ejson::Value& _obj) { + if (m_data == nullptr) { + EJSON_ERROR("Can not transfert In (nullptr) ..."); + return false; + } + return m_data->transfertIn(_obj.m_data); } -ememory::SharedPtr ejson::Value::clone() const { - return ememory::SharedPtr(); +ejson::Value ejson::Value::clone() const { + if (m_data == nullptr) { + EJSON_ERROR("Can not transfert In (nullptr) ..."); + return ejson::Value(m_data); + } + return ejson::Value(m_data->clone()); } diff --git a/ejson/Value.h b/ejson/Value.h index e16505b..7412e39 100644 --- a/ejson/Value.h +++ b/ejson/Value.h @@ -10,22 +10,13 @@ #include #include #include +#include +#include /** * @brief ejson namespace containing all function for JSON interpretor */ namespace ejson { - //#define ENABLE_DISPLAY_PARSED_ELEMENT - #if 1 - #define JSON_PARSE_ELEMENT JSON_VERBOSE - #else - #define JSON_PARSE_ELEMENT JSON_DEBUG - #endif - #if 1 - #define JSON_PARSE_ATTRIBUTE JSON_VERBOSE - #else - #define JSON_PARSE_ATTRIBUTE JSON_DEBUG - #endif class Document; class Array; class Object; @@ -33,152 +24,117 @@ namespace ejson { class Null; class Number; class String; + namespace internal { + class Value; + } /** * @brief Basic main object of all json elements. */ - class Value : public ememory::EnableSharedFromThis { + class Value { + friend ejson::Array; + friend ejson::Object; protected: + ememory::SharedPtr m_data; //!< internal reference on a Value + public: + /** + * @brief Get Value type + * @return Type of the object + */ + enum ejson::valueType getType() const; + public: + /** + * @brief basic element of a xml structure + * @param[in] _internalValue Internal reference of the Value. + */ + Value(const ememory::SharedPtr& _internalValue); /** * @brief basic element of a xml structure */ - Value() { }; + Value(); + public: /** * @brief Virtualize destructor */ - virtual ~Value(); + virtual ~Value() = default; public: - /** - * @brief parse the Current node [pure VIRUAL] - * @param[in] _data data string to parse. - * @param[in,out] _pos position in the string to start parse, return the position end of parsing. - * @param[in] _caseSensitive Request a parsion of element that is not case sensitive (all element is in low case) - * @param[in,out] file parsing position (line x col x) - * @return false if an error occured. - */ - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) = 0; - /** - * @brief generate a string with the tree of the xml - * @param[in,out] _data string where to add the elements - * @param[in] current indentation of the file - * @return false if an error occured. - */ - virtual bool iGenerate(std::string& _data, size_t _indent) const = 0; /** * @brief Display the Document on console */ void display() const; - protected: /** - * @brief add indentation of the string input. - * @param[in,out] _data String where the indentation is done. - * @param[in] _indent Number of tab to add at the string. + * @brief Check if the element exit */ - void addIndent(std::string& _data, size_t _indent) const; - /** - * @brief Display the cuurent element that is curently parse. - * @param[in] _val Char that is parsed. - * @param[in] _filePos Position of the char in the file. - */ - void drawElementParsed(char32_t _val, const ejson::FilePos& _filePos) const; - /** - * @brief check if an name (for object named) (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \n\t\r). - * @param[in] _val Value to check the conformity. - */ - bool checkString(char32_t _val) const; - /** - * @brief check if an number -+.0123456789e). - * @param[in] _val Value to check the conformity. - */ - bool checkNumber(char32_t _val) const; - /** - * @brief count the number of white char in the string from the specify position (stop at the first element that is not a white char) - * @param[in] _data Data to parse. - * @param[in] _pos Start position in the string. - * @param[out] _filePos new poistion of te file to add. - * @return number of white element. - */ - int32_t countWhiteChar(const std::string& _data, size_t _pos, ejson::FilePos& _filePos) const; - public: - /** - * @brief Cast the element in a Value if it is possible. - * @return pointer on the class or nullptr. - */ - ememory::SharedPtr toValue(); - /** - * @brief Cast the element in a Value if it is possible. - * @return CONST pointer on the class or nullptr. - */ - const ememory::SharedPtr toValue() const; + bool exist() const; /** * @brief Cast the element in a Document if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toDocument(); + ejson::Document toDocument(); /** * @brief Cast the element in a Document if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toDocument() const; + const ejson::Document toDocument() const; /** * @brief Cast the element in a Array if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toArray(); + ejson::Array toArray(); /** * @brief Cast the element in a Array if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toArray() const; + const ejson::Array toArray() const; /** * @brief Cast the element in a Object if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toObject(); + ejson::Object toObject(); /** * @brief Cast the element in a Object if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toObject() const; + const ejson::Object toObject() const; /** * @brief Cast the element in a String if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toString(); + ejson::String toString(); /** * @brief Cast the element in a String if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toString() const; + const ejson::String toString() const; /** * @brief Cast the element in a Number if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toNumber(); + ejson::Number toNumber(); /** * @brief Cast the element in a Number if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toNumber() const; + const ejson::Number toNumber() const; /** * @brief Cast the element in a Boolean if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toBoolean(); + ejson::Boolean toBoolean(); /** * @brief Cast the element in a Boolean if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toBoolean() const; + const ejson::Boolean toBoolean() const; /** * @brief Cast the element in a Null if it is possible. * @return pointer on the class or nullptr. */ - ememory::SharedPtr toNull(); + ejson::Null toNull(); /** * @brief Cast the element in a Null if it is possible. * @return CONST pointer on the class or nullptr. */ - const ememory::SharedPtr toNull() const; + const ejson::Null toNull() const; /** * @brief check if the node is a ejson::Document @@ -215,31 +171,31 @@ namespace ejson { * @return true if the node is a ejson::Null */ bool isNull() const; - /** * @brief clear the Node */ - virtual void clear(); + void clear(); /** * @brief Tranfert all element in the element set in parameter * @param[in,out] _obj move all parameter in the selected element * @return true if transfer is done corectly * @note all element is remove from the curent element. */ - virtual bool transfertIn(ememory::SharedPtr _obj); + bool transfertIn(ejson::Value& _obj); /** * @brief Copy the curent node and all the child in the curent one. * @return nullptr in an error occured, the pointer on the element otherwise */ - virtual ememory::SharedPtr clone() const; - protected: - /** - * @brief check if the current element is white or not : '\t' '\n' '\r' ' ' - * @return tue if it is white char - */ - static bool isWhiteChar(char32_t _val); + ejson::Value clone() const; }; -}; + //! @not_in_doc + std::ostream& operator <<(std::ostream& _os, const ejson::Value& _obj); + /** + * @brief create an empty Value (that does not exist ... + * @return empty value (not usable) + */ + ejson::Value empty(); +} #include #include @@ -248,3 +204,4 @@ namespace ejson { #include #include + diff --git a/ejson/debug.h b/ejson/debug.h index aa91af0..fc5e6dc 100644 --- a/ejson/debug.h +++ b/ejson/debug.h @@ -12,24 +12,24 @@ namespace ejson { int32_t getLogId(); }; -#define JSON_BASE(info,data) ELOG_BASE(ejson::getLogId(),info,data) +#define EJSON_BASE(info,data) ELOG_BASE(ejson::getLogId(),info,data) -#define JSON_CRITICAL(data) JSON_BASE(1, data) -#define JSON_ERROR(data) JSON_BASE(2, data) -#define JSON_WARNING(data) JSON_BASE(3, data) +#define EJSON_CRITICAL(data) EJSON_BASE(1, data) +#define EJSON_ERROR(data) EJSON_BASE(2, data) +#define EJSON_WARNING(data) EJSON_BASE(3, data) #ifdef DEBUG - #define JSON_INFO(data) JSON_BASE(4, data) - #define JSON_DEBUG(data) JSON_BASE(5, data) - #define JSON_VERBOSE(data) JSON_BASE(6, data) - #define JSON_TODO(data) JSON_BASE(4, "TODO : " << data) + #define EJSON_INFO(data) EJSON_BASE(4, data) + #define EJSON_DEBUG(data) EJSON_BASE(5, data) + #define EJSON_VERBOSE(data) EJSON_BASE(6, data) + #define EJSON_TODO(data) EJSON_BASE(4, "TODO : " << data) #else - #define JSON_INFO(data) do { } while(false) - #define JSON_DEBUG(data) do { } while(false) - #define JSON_VERBOSE(data) do { } while(false) - #define JSON_TODO(data) do { } while(false) + #define EJSON_INFO(data) do { } while(false) + #define EJSON_DEBUG(data) do { } while(false) + #define EJSON_VERBOSE(data) do { } while(false) + #define EJSON_TODO(data) do { } while(false) #endif -#define JSON_ASSERT(cond,data) \ +#define EJSON_ASSERT(cond,data) \ do { \ if (!(cond)) { \ JSON_CRITICAL(data); \ diff --git a/ejson/details/iterator.hxx b/ejson/details/iterator.hxx new file mode 100644 index 0000000..bc0194f --- /dev/null +++ b/ejson/details/iterator.hxx @@ -0,0 +1,122 @@ +/** @file + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#include + +template +ejson::iterator::iterator(EJSON_BASE_T& _obj, size_t _pos) : + m_data(_obj), + m_id(_pos) { + m_id = std::avg(size_t(0), m_id, m_data.size()); +} + +template +ejson::iterator::iterator(const EJSON_BASE_T& _obj, size_t _pos) : + m_data(const_cast(_obj)), + m_id(_pos) { + m_id = std::avg(size_t(0), m_id, m_data.size()); +} + +template +ejson::iterator::iterator(const ejson::iterator& _obj) : + m_data(_obj.m_data), + m_id(_obj.m_id) { + m_id = std::avg(size_t(0), m_id, m_data.size()); +} + +template +ejson::iterator& ejson::iterator::operator= (const ejson::iterator& _obj) { + m_data = _obj.m_data; + m_id = _obj.m_id; + m_id = std::avg(size_t(0), m_id, m_data.size()); + return *this; +} + +template +ejson::iterator& ejson::iterator::operator+= (int32_t _val) { + int64_t val = m_id; + val += _val; + m_id = std::avg(int64_t(0), val, int64_t(m_data.size())); + return *this; +} + +template +ejson::iterator ejson::iterator::operator+ (int32_t _val) const { + ejson::iterator result(*this); + result += _val; + return result; +} + +template +ejson::iterator& ejson::iterator::operator-= (int32_t _val) { + int64_t val = m_id; + val -= _val; + m_id = std::avg(int64_t(0), val, int64_t(m_data.size())); + return *this; +} + +template +ejson::iterator ejson::iterator::operator- (int32_t _val) const { + ejson::iterator result = *this; + result -= _val; + return result; +} + +template +ejson::iterator& ejson::iterator::operator++() { + int64_t val = m_id; + ++val; + m_id = std::avg(int64_t(0), val, int64_t(m_data.size())); + return *this; +} + +template +ejson::iterator ejson::iterator::operator++(int) { + ejson::iterator result = *this; + ++(*this); + return result; +} + +template +ejson::iterator& ejson::iterator::operator--() { + int64_t val = m_id; + --val; + m_id = std::avg(int64_t(0), val, int64_t(m_data.size())); + return *this; +} + +template +ejson::iterator ejson::iterator::operator--(int) { + ejson::iterator result = *this; + --(*this); + return result; +} + +template +bool ejson::iterator::operator== (const ejson::iterator& _obj) const { + //ejson_WARNING("compare : " << _obj.m_id << " == " << m_id ); + return ( _obj.m_id == m_id + && &_obj.m_data == &m_data); +} + +template +bool ejson::iterator::operator!= (const ejson::iterator& _obj) const { + //ejson_WARNING("compare : " << _obj.m_id << " != " << m_id ); + return ( _obj.m_id != m_id + || &_obj.m_data != &m_data); +} + +template +const ejson::Value ejson::iterator::operator *() const noexcept { + return m_data[m_id]; +} + +template +ejson::Value ejson::iterator::operator *() noexcept { + return m_data[m_id]; +} + diff --git a/ejson/ejson.h b/ejson/ejson.h index 29ff686..4190aab 100644 --- a/ejson/ejson.h +++ b/ejson/ejson.h @@ -7,82 +7,5 @@ */ #pragma once -#include -#include -#include -#include -#include -#include - -namespace ejson { - class Document : public ejson::Object { - public: - /** - * @brief Constructor - */ - Document(); - static ememory::SharedPtr create(); - /** - * @brief Destructor - */ - virtual ~Document(); - public: - /** - * @brief parse a string that contain an XML - * @param[in] _data Data to parse - * @return false : An error occured - * @return true : Parsing is OK - */ - bool parse(const std::string& _data); - /** - * @brief generate a string that contain the created XML - * @param[out] _data Data where the xml is stored - * @return false : An error occured - * @return true : Parsing is OK - */ - bool generate(std::string& _data); - /** - * @brief Load the file that might contain the xml - * @param[in] _file Filename of the xml (compatible with etk FSNode naming) - * @return false : An error occured - * @return true : Parsing is OK - */ - bool load(const std::string& _file); - /** - * @brief Store the Xml in the file - * @param[in] _file Filename of the xml (compatible with etk FSNode naming) - * @return false : An error occured - * @return true : Parsing is OK - */ - bool store(const std::string& _file); - private: - bool m_writeErrorWhenDetexted; - std::string m_comment; - std::string m_Line; - ejson::FilePos m_filePos; - public: - void displayErrorWhenDetected() { - m_writeErrorWhenDetexted=true; - }; - void notDisplayErrorWhenDetected() { - m_writeErrorWhenDetexted=false; - }; - - void createError(const std::string& _data, size_t _pos, const ejson::FilePos& _filePos, const std::string& _comment); - void displayError(); - public: // herited function: - virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc); - virtual bool iGenerate(std::string& _data, size_t _indent) const; - }; -}; - -#define EJSON_CREATE_ERROR(doc,data,pos,filePos,comment) \ - do { \ - JSON_ERROR(comment); \ - (doc).createError((data),(pos),(filePos),(comment)); \ - } while (0) - -//__LINE__, __class__, __func__ - - +#include diff --git a/ejson/internal/Array.cpp b/ejson/internal/Array.cpp new file mode 100644 index 0000000..fa87bcb --- /dev/null +++ b/ejson/internal/Array.cpp @@ -0,0 +1,391 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +ememory::SharedPtr ejson::internal::Array::create() { + return ememory::SharedPtr(new ejson::internal::Array()); +} + +void ejson::internal::Array::clear() { + m_value.clear(); +} + +bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'Object' "); + for (size_t iii=_pos+1; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + ejson::FilePos tmpPos; + if( _data[iii] == ' ' + || _data[iii] == '\t' + || _data[iii] == '\n' + || _data[iii] == '\r') { + // white space == > nothing to do ... + } else if(_data[iii] == '#') { + // comment Line ... + for (iii++; iii<_data.size(); iii++) { + if( _data[iii] == '\n' + || _data[iii] == '\r') { + break; + } + } + } else if(_data[iii] == ']') { + // find end of value: + _pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed + return true; + } else if (_data[iii] == '{') { + // find an object: + EJSON_PARSE_ELEMENT("find Object"); + ememory::SharedPtr tmpElement = ejson::internal::Object::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in object"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if ( _data[iii] == '"' + || _data[iii] == '\'') { + // find a string: + EJSON_PARSE_ELEMENT("find String quoted"); + ememory::SharedPtr tmpElement = ejson::internal::String::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if (_data[iii] == '[') { + // find a list: + EJSON_PARSE_ELEMENT("find List"); + ememory::SharedPtr tmpElement = ejson::internal::Array::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Array"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if( _data[iii] == 'f' + || _data[iii] == 't' ) { + // find boolean: + EJSON_PARSE_ELEMENT("find Boolean"); + ememory::SharedPtr tmpElement = ejson::internal::Boolean::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if( _data[iii] == 'n') { + // find null: + EJSON_PARSE_ELEMENT("find Null"); + ememory::SharedPtr tmpElement = ejson::internal::Null::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if(true == checkNumber(_data[iii])) { + // find number: + EJSON_PARSE_ELEMENT("find Number"); + ememory::SharedPtr tmpElement = ejson::internal::Number::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + m_value.push_back(tmpElement); + } else if(_data[iii] == ',') { + // find Separator : Restart cycle ... + // TODO : check if element are separated with ',' + } else { + // find an error .... + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Find '?' with no element in the element..."); + // move the curent index + _pos = iii+1; + return false; + } + } + _pos = _data.size(); + return false; +} + + +bool ejson::internal::Array::iGenerate(std::string& _data, size_t _indent) const { + bool oneLine=true; + if (m_value.size()>3) { + oneLine=false; + } else { + for (size_t iii=0; iii tmp = m_value[iii]; + if (tmp == nullptr) { + continue; + } + if (true == tmp->isObject()) { + oneLine=false; + break; + } + if (true == tmp->isArray()) { + oneLine=false; + break; + } + if (true == tmp->isString()) { + ememory::SharedPtr tmp2 = tmp->toString(); + if (tmp2 != nullptr) { + if(tmp2->get().size()>40) { + oneLine=false; + break; + } + } + } + } + } + if (true == oneLine) { + _data += "[ "; + } else { + _data += "[\n"; + } + for (size_t iii=0; iiiiGenerate(_data, _indent+1); + if (iii _element) { + if (_element == nullptr) { + EJSON_ERROR("Request add on an nullptr pointer"); + return false; + } + m_value.push_back(_element); + return true; +} + +bool ejson::internal::Array::addString(const std::string& _value) { + return add(ejson::internal::String::create(_value)); +} + +bool ejson::internal::Array::addNull() { + return add(ejson::internal::Null::create()); +} + +bool ejson::internal::Array::addBoolean(bool _value) { + return add(ejson::internal::Boolean::create(_value)); +} + +bool ejson::internal::Array::addNumber(double _value) { + return add(ejson::internal::Number::create(_value)); +} + + +bool ejson::internal::Array::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an nullptr pointer"); + return false; + } + ememory::SharedPtr other = _obj->toArray(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an array"); + return false; + } + // remove destination elements + other->clear(); + // Copy to the destination + other->m_value = m_value; + // remove current: + m_value.clear(); + return true; +} + +// TODO : Manage error ... +ememory::SharedPtr ejson::internal::Array::clone() const { + ememory::SharedPtr output = ejson::internal::Array::create(); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + for (size_t iii=0; iii val = m_value[iii]; + if (val == nullptr) { + continue; + } + output->add(val->clone()); + } + return output; +} + +ememory::SharedPtr ejson::internal::Array::getObject(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toObject(); +} +const ememory::SharedPtr ejson::internal::Array::getObject(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toObject(); +} + +ememory::SharedPtr ejson::internal::Array::getString(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toString(); +} + +const ememory::SharedPtr ejson::internal::Array::getString(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toString(); +} + +ememory::SharedPtr ejson::internal::Array::getArray(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toArray(); +} + +const ememory::SharedPtr ejson::internal::Array::getArray(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toArray(); +} + +ememory::SharedPtr ejson::internal::Array::getNull(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toNull(); +} + +const ememory::SharedPtr ejson::internal::Array::getNull(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toNull(); +} + +ememory::SharedPtr ejson::internal::Array::getNumber(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toNumber(); +} + +const ememory::SharedPtr ejson::internal::Array::getNumber(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toNumber(); +} + +ememory::SharedPtr ejson::internal::Array::getBoolean(size_t _id) { + ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toBoolean(); +} + +const ememory::SharedPtr ejson::internal::Array::getBoolean(size_t _id) const { + const ememory::SharedPtr tmpElement = m_value[_id]; + if (tmpElement == nullptr) { + return ememory::SharedPtr(); + } + return tmpElement->toBoolean(); +} + +std::string ejson::internal::Array::getStringValue(size_t _id) { + ememory::SharedPtr tmpElement = getString(_id); + if (tmpElement == nullptr) { + return ""; + } + return tmpElement->get(); +} + +const std::string& ejson::internal::Array::getStringValue(size_t _id) const { + static const std::string errorValue(""); + const ememory::SharedPtr tmpElement = getString(_id); + if (tmpElement == nullptr) { + return errorValue; + } + return tmpElement->get(); +} + +std::string ejson::internal::Array::getStringValue(size_t _id, const std::string& _errorValue) const { + const ememory::SharedPtr tmpElement = getString(_id); + if (tmpElement == nullptr) { + return _errorValue; + } + return tmpElement->get(); +} + +double ejson::internal::Array::getNumberValue(size_t _id, double _errorValue) const { + const ememory::SharedPtr tmpElement = getNumber(_id); + if (tmpElement == nullptr) { + return _errorValue; + } + return tmpElement->get(); +} + +bool ejson::internal::Array::getBooleanValue(size_t _id, bool _errorValue) const { + const ememory::SharedPtr tmpElement = getBoolean(_id); + if (tmpElement == nullptr) { + return _errorValue; + } + return tmpElement->get(); +} + + diff --git a/ejson/internal/Array.h b/ejson/internal/Array.h new file mode 100644 index 0000000..321e1cc --- /dev/null +++ b/ejson/internal/Array.h @@ -0,0 +1,175 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + namespace internal { + class Array : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + Array() { + m_type = ejson::valueType::array; + }; + public: + static ememory::SharedPtr create(); + /** + * @brief destructor + */ + virtual ~Array() { }; + private: + std::vector > m_value; //!< vector of sub elements + public: + /** + * @brief get the number of sub element in the current one + * @return the Number of stored element + */ + size_t size() const { + return m_value.size(); + }; + /** + * @brief get the pointer on an element reference with his ID. + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr get(size_t _id) { + return m_value[_id]; + }; + //! @previous + const ememory::SharedPtr get(size_t _id) const{ + return m_value[_id]; + }; + //! @previous + ememory::SharedPtr operator[] (size_t _id) { + return m_value[_id]; + } + //! @previous + const ememory::SharedPtr operator[] (size_t _id) const { + return m_value[_id]; + } + /** + * @brief get the pointer on an element reference with his ID (casted in Object if it is an object). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getObject(size_t _id); + //! @previous + const ememory::SharedPtr getObject(size_t _id) const; + /** + * @brief get the pointer on an element reference with his ID (casted in String if it is an String). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getString(size_t _id); + //! @previous + const ememory::SharedPtr getString(size_t _id) const; + /** + * @brief get the value of the string element (if not a string return "") + * @param[in] _id Id of the element. + * @return value of the element. + */ + std::string getStringValue(size_t _id); + //! @previous + const std::string& getStringValue(size_t _id) const; + /** + * @brief get the value of the string element + * @param[in] _id Id of the element. + * @param[in] _errorValue The return value if an error occured. + * @return value of the element, or the _errorValue. + */ + std::string getStringValue(size_t _id, const std::string& _errorValue) const; + /** + * @brief get the pointer on an element reference with his ID (casted in Array if it is an Array). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getArray(size_t _id); + //! @previous + const ememory::SharedPtr getArray(size_t _id) const; + /** + * @brief get the pointer on an element reference with his ID (casted in Null if it is an Null). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getNull(size_t _id); + //! @previous + const ememory::SharedPtr getNull(size_t _id) const; + /** + * @brief get the pointer on an element reference with his ID (casted in Number if it is an Number). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getNumber(size_t _id); + //! @previous + const ememory::SharedPtr getNumber(size_t _id) const; + /** + * @brief get the value of the Number element + * @param[in] _id Id of the element. + * @param[in] _errorValue The return value if an error occured. + * @return value of the element, or the _errorValue. + */ + double getNumberValue(size_t _id, double _errorValue) const; + /** + * @brief get the pointer on an element reference with his ID (casted in Boolean if it is an Boolean). + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr getBoolean(size_t _id); + //! @previous + const ememory::SharedPtr getBoolean(size_t _id) const; + /** + * @brief get the value of the Boolean element + * @param[in] _id Id of the element. + * @param[in] _errorValue The return value if an error occured. + * @return value of the element, or the _errorValue. + */ + bool getBooleanValue(size_t _id, bool _errorValue) const; + /** + * @brief add an element on the array. + * @param[in] _element element to add. + * @return false if an error occured. + */ + bool add(ememory::SharedPtr _element); + /** + * @brief add a string element in the Object (automatic creation) + * @param[in] _value string value to add + * @return false if an error occured + */ + bool addString(const std::string& _value); + /** + * @brief add a "null" element in the Object (automatic creation) + * @return false if an error occured + */ + bool addNull(); + /** + * @brief add a boolean element in the Object (automatic creation) + * @param[in] _value boolean value to add + * @return false if an error occured + */ + bool addBoolean(bool _value); + /** + * @brief add a double element in the Object (automatic creation) + * @param[in] _value double value to add + * @return false if an error occured + */ + bool addNumber(double _value); + + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual void clear(); + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual ememory::SharedPtr clone() const; + }; + } +} + diff --git a/ejson/internal/Boolean.cpp b/ejson/internal/Boolean.cpp new file mode 100644 index 0000000..b1fa4b8 --- /dev/null +++ b/ejson/internal/Boolean.cpp @@ -0,0 +1,82 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include + +ememory::SharedPtr ejson::internal::Boolean::create(bool _value) { + return ememory::SharedPtr(new ejson::internal::Boolean(_value)); +} + + +bool ejson::internal::Boolean::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'Boolean' "); + m_value=false; + if( _data[_pos] == 't' + && _pos+3 < _data.size() + && _data[_pos+1] == 'r' + && _data[_pos+2] == 'u' + && _data[_pos+3] == 'e'){ + m_value=true; + _pos+=3; + _filePos+=3; + return true; + } + if( _data[_pos] == 'f' + && _pos+4 < _data.size() + && _data[_pos+1] == 'a' + && _data[_pos+2] == 'l' + && _data[_pos+3] == 's' + && _data[_pos+4] == 'e'){ + m_value=false; + _pos+=4; + _filePos+=4; + return true; + } + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "boolean parsing error ..."); + return false; +} + + +bool ejson::internal::Boolean::iGenerate(std::string& _data, size_t _indent) const { + if (true == m_value) { + _data += "true"; + } else { + _data += "false"; + } + return true; +} + + +bool ejson::internal::Boolean::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ememory::SharedPtr other = _obj->toBoolean(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an Boolean"); + return false; + } + // remove destination elements + other->m_value = m_value; + m_value = false; + return true; +} + +ememory::SharedPtr ejson::internal::Boolean::clone() const { + ememory::SharedPtr output = ejson::internal::Boolean::create(m_value); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + return output; +} + + diff --git a/ejson/internal/Boolean.h b/ejson/internal/Boolean.h new file mode 100644 index 0000000..fc41122 --- /dev/null +++ b/ejson/internal/Boolean.h @@ -0,0 +1,57 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + namespace internal { + class Boolean : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + Boolean(bool _value=false) : + m_value(_value) { + m_type = ejson::valueType::boolean; + }; + public: + static ememory::SharedPtr create(bool _value=false); + /** + * @brief destructor + */ + virtual ~Boolean() { + + }; + protected: + bool m_value; //!< value of the node + public: + /** + * @brief set the value of the node. + * @param[in] _value New value of the node. + */ + void set(bool _value) { + m_value = _value; + }; + /** + * @brief get the current element Value. + * @return the reference of the string value. + */ + bool get() const { + return m_value; + }; + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual ememory::SharedPtr clone() const; + }; + } +} + diff --git a/ejson/ejson.cpp b/ejson/internal/Document.cpp similarity index 61% rename from ejson/ejson.cpp rename to ejson/internal/Document.cpp index 4dc1aec..3685b37 100644 --- a/ejson/ejson.cpp +++ b/ejson/internal/Document.cpp @@ -6,68 +6,68 @@ * @license APACHE v2.0 (see license file) */ -#include +#include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -ememory::SharedPtr ejson::Document::create() { - return ememory::SharedPtr(new ejson::Document()); +ememory::SharedPtr ejson::internal::Document::create() { + return ememory::SharedPtr(new ejson::internal::Document()); } -ejson::Document::Document() : - m_writeErrorWhenDetexted(true), - m_comment(""), - m_Line(""), - m_filePos(0,0) { +ejson::internal::Document::Document() : + m_writeErrorWhenDetexted(true), + m_comment(""), + m_Line(""), + m_filePos(0,0) { + m_type = ejson::valueType::document; +} + +ejson::internal::Document::~Document() { } -ejson::Document::~Document() { - -} - -bool ejson::Document::iGenerate(std::string& _data, size_t _indent) const { - ejson::Object::iGenerate(_data, _indent+1); +bool ejson::internal::Document::iGenerate(std::string& _data, size_t _indent) const { + ejson::internal::Object::iGenerate(_data, _indent+1); _data += "\n"; return true; } -bool ejson::Document::parse(const std::string& _data) { - JSON_VERBOSE("Start parsing document (type: string) size=" << _data.size()); +bool ejson::internal::Document::parse(const std::string& _data) { + EJSON_VERBOSE("Start parsing document (type: string) size=" << _data.size()); clear(); ejson::FilePos filePos(1,0); size_t parsePos = 0; return iParse(_data, parsePos, filePos, *this); } -bool ejson::Document::generate(std::string& _data) { +bool ejson::internal::Document::generate(std::string& _data) { _data = ""; return iGenerate(_data,0); } -bool ejson::Document::load(const std::string& _file) { +bool ejson::internal::Document::load(const std::string& _file) { // Start loading the XML : - JSON_VERBOSE("open file (xml) \"" << _file << "\""); + EJSON_VERBOSE("open file (xml) \"" << _file << "\""); clear(); etk::FSNode tmpFile(_file); if (false == tmpFile.exist()) { - JSON_ERROR("File Does not exist : " << _file); + EJSON_ERROR("File Does not exist : " << _file); return false; } int64_t fileSize = tmpFile.fileSize(); if (0 == fileSize) { - JSON_ERROR("This file is empty : " << _file); + EJSON_ERROR("This file is empty : " << _file); return false; } if (false == tmpFile.fileOpenRead()) { - JSON_ERROR("Can not open (r) the file : " << _file); + EJSON_ERROR("Can not open (r) the file : " << _file); return false; } // allocate data @@ -85,19 +85,19 @@ bool ejson::Document::load(const std::string& _file) { return ret; } -bool ejson::Document::store(const std::string& _file) { +bool ejson::internal::Document::store(const std::string& _file) { std::string createData; if (false == generate(createData)) { - JSON_ERROR("Error while creating the XML : " << _file); + EJSON_ERROR("Error while creating the XML : " << _file); return false; } etk::FSNode tmpFile(_file); if (false == tmpFile.fileOpenWrite()) { - JSON_ERROR("Can not open (w) the file : " << _file); + EJSON_ERROR("Can not open (w) the file : " << _file); return false; } if (tmpFile.fileWrite((char*)createData.c_str(), sizeof(char), createData.size()) != (int32_t)createData.size()) { - JSON_ERROR("Error while writing output XML file : " << _file); + EJSON_ERROR("Error while writing output XML file : " << _file); tmpFile.fileClose(); return false; } @@ -123,20 +123,20 @@ static std::string createPosPointer(const std::string& _line, size_t _pos) { return out; } -void ejson::Document::displayError() { +void ejson::internal::Document::displayError() { if (m_comment.size() == 0) { - JSON_ERROR("No error detected ???"); + EJSON_ERROR("No error detected ???"); return; } - JSON_ERROR(m_filePos << " " << m_comment << "\n" + EJSON_ERROR(m_filePos << " " << m_comment << "\n" << m_Line << "\n" << createPosPointer(m_Line, m_filePos.getCol()) ); #ifdef ENABLE_CRITICAL_WHEN_ERROR - JSON_CRITICAL("detect error"); + EJSON_CRITICAL("detect error"); #endif } -void ejson::Document::createError(const std::string& _data, size_t _pos, const ejson::FilePos& _filePos, const std::string& _comment) { +void ejson::internal::Document::createError(const std::string& _data, size_t _pos, const ejson::FilePos& _filePos, const std::string& _comment) { m_comment = _comment; m_Line = etk::extract_line(_data, _pos); m_filePos = _filePos; @@ -145,8 +145,8 @@ void ejson::Document::createError(const std::string& _data, size_t _pos, const e } } -bool ejson::Document::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Document' "); +bool ejson::internal::Document::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'Document' "); bool haveMainNode=false; bool nodeParsed=false; for (size_t iii=_pos; iii<_data.size(); iii++) { @@ -170,7 +170,7 @@ bool ejson::Document::iParse(const std::string& _data, size_t& _pos, ejson::File iii++; haveMainNode=true; nodeParsed=true; - ejson::Object::iParse(_data, iii, _filePos, _doc); + ejson::internal::Object::iParse(_data, iii, _filePos, _doc); } else if(_data[iii] == '}') { _pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed if (haveMainNode == true) { @@ -188,7 +188,7 @@ bool ejson::Document::iParse(const std::string& _data, size_t& _pos, ejson::File } nodeParsed=true; // this might not have the '{' start element !!! - if (false == ejson::Object::iParse(_data, iii, _filePos, _doc)) { + if (false == ejson::internal::Object::iParse(_data, iii, _filePos, _doc)) { EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Object sub parsing in error"); _pos = iii; return false; diff --git a/ejson/internal/Document.h b/ejson/internal/Document.h new file mode 100644 index 0000000..9673d59 --- /dev/null +++ b/ejson/internal/Document.h @@ -0,0 +1,89 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace ejson { + namespace internal { + class Document : public ejson::internal::Object { + public: + /** + * @brief Constructor + */ + Document(); + static ememory::SharedPtr create(); + /** + * @brief Destructor + */ + virtual ~Document(); + public: + /** + * @brief parse a string that contain an XML + * @param[in] _data Data to parse + * @return false : An error occured + * @return true : Parsing is OK + */ + bool parse(const std::string& _data); + /** + * @brief generate a string that contain the created XML + * @param[out] _data Data where the xml is stored + * @return false : An error occured + * @return true : Parsing is OK + */ + bool generate(std::string& _data); + /** + * @brief Load the file that might contain the xml + * @param[in] _file Filename of the xml (compatible with etk FSNode naming) + * @return false : An error occured + * @return true : Parsing is OK + */ + bool load(const std::string& _file); + /** + * @brief Store the Xml in the file + * @param[in] _file Filename of the xml (compatible with etk FSNode naming) + * @return false : An error occured + * @return true : Parsing is OK + */ + bool store(const std::string& _file); + private: + bool m_writeErrorWhenDetexted; + std::string m_comment; + std::string m_Line; + ejson::FilePos m_filePos; + public: + void displayErrorWhenDetected() { + m_writeErrorWhenDetexted=true; + }; + void notDisplayErrorWhenDetected() { + m_writeErrorWhenDetexted=false; + }; + + void createError(const std::string& _data, size_t _pos, const ejson::FilePos& _filePos, const std::string& _comment); + void displayError(); + public: // herited function: + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + }; + } +} + +#define EJSON_CREATE_ERROR(doc,data,pos,filePos,comment) \ + do { \ + EJSON_ERROR(comment); \ + (doc).createError((data),(pos),(filePos),(comment)); \ + } while (0) + + + + diff --git a/ejson/internal/Null.cpp b/ejson/internal/Null.cpp new file mode 100644 index 0000000..8120a70 --- /dev/null +++ b/ejson/internal/Null.cpp @@ -0,0 +1,65 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include + +ememory::SharedPtr ejson::internal::Null::create() { + return ememory::SharedPtr(new ejson::internal::Null()); +} + + +bool ejson::internal::Null::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'Null' "); + if (_pos+3 >= _data.size()){ + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "can not parse null !!! "); + return false; + } + if( _data[_pos] != 'n' + || _data[_pos+1] != 'u' + || _data[_pos+2] != 'l' + || _data[_pos+3] != 'l' ) { + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "Not a corect 'null' element"); + return false; + } + _pos+=4; + _filePos+=4; + return true; +} + + +bool ejson::internal::Null::iGenerate(std::string& _data, size_t _indent) const { + _data += "null"; + return true; +} + + +bool ejson::internal::Null::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an nullptr pointer"); + return false; + } + ememory::SharedPtr other = _obj->toNull(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an Null"); + return false; + } + return true; +} + +ememory::SharedPtr ejson::internal::Null::clone() const { + ememory::SharedPtr output = ejson::internal::Null::create(); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + return output; +} + + diff --git a/ejson/internal/Null.h b/ejson/internal/Null.h new file mode 100644 index 0000000..aefadf5 --- /dev/null +++ b/ejson/internal/Null.h @@ -0,0 +1,39 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + namespace internal { + class Null : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + Null() { + m_type = ejson::valueType::null; + }; + public: + static ememory::SharedPtr create(); + /** + * @brief destructor + */ + virtual ~Null() { }; + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual ememory::SharedPtr clone() const; + }; + } +} + + + diff --git a/ejson/internal/Number.cpp b/ejson/internal/Number.cpp new file mode 100644 index 0000000..2f06fe8 --- /dev/null +++ b/ejson/internal/Number.cpp @@ -0,0 +1,78 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + + +#include +#include +#include + +ememory::SharedPtr ejson::internal::Number::create(double _value) { + return ememory::SharedPtr(new ejson::internal::Number(_value)); +} + +bool ejson::internal::Number::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'Number' "); + std::string tmpVal; + for (size_t iii=_pos; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + if(true == checkNumber(_data[iii])) { + tmpVal+=_data[iii]; + } else { + _pos = iii-1; + m_value = etk::string_to_double(tmpVal); + EJSON_PARSE_ELEMENT("end parse : 'Number' " << tmpVal << " >> " << m_value); + return true; + } + } + _pos=_data.size(); + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); + return false; +} + + +bool ejson::internal::Number::iGenerate(std::string& _data, size_t _indent) const { + // special thing to remove .000000 at the end of perfect number ... + int64_t tmpVal = m_value; + if ((double)tmpVal == m_value) { + _data += etk::to_string(tmpVal); + } else { + _data += etk::to_string(m_value); + } + return true; +} + + +bool ejson::internal::Number::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an nullptr pointer"); + return false; + } + ememory::SharedPtr other = _obj->toNumber(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an Number"); + return false; + } + // remove destination elements + other->m_value = m_value; + m_value = 0; + return true; +} + +ememory::SharedPtr ejson::internal::Number::clone() const { + ememory::SharedPtr output = ejson::internal::Number::create(m_value); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + return output; +} + + diff --git a/ejson/internal/Number.h b/ejson/internal/Number.h new file mode 100644 index 0000000..2a26f53 --- /dev/null +++ b/ejson/internal/Number.h @@ -0,0 +1,70 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + namespace internal { + class Number : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + Number(double _value=0.0) : + m_value(_value) { + m_type = ejson::valueType::number; + }; + public: + static ememory::SharedPtr create(double _value=0.0); + /** + * @brief destructor + */ + virtual ~Number() { }; + protected: + double m_value; //!< value of the node + public: + /** + * @brief set the value of the node. + * @param[in] _value New value of the node. + */ + void set(double _value) { + m_value = _value; + }; + /** + * @brief Get the current element Value. + * @return The double number registered + */ + double get() const { + return m_value; + }; + /** + * @brief Get the current element Value. + * @return The 32 bit integer number registered + */ + int32_t getInt32() const { + return (int32_t)m_value; + }; + /** + * @brief Get the current element Value. + * @return The 64 bit integer number registered + */ + int64_t getInt64() const { + return (int64_t)m_value; + }; + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual ememory::SharedPtr clone() const; + }; + } +} + + diff --git a/ejson/internal/Object.cpp b/ejson/internal/Object.cpp new file mode 100644 index 0000000..61d5532 --- /dev/null +++ b/ejson/internal/Object.cpp @@ -0,0 +1,508 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +ememory::SharedPtr ejson::internal::Object::create() { + return ememory::SharedPtr(new ejson::internal::Object()); +} +ememory::SharedPtr ejson::internal::Object::create(const std::string& _data) { + ejson::internal::Document doc; + doc.parse(_data); + return doc.cloneObj(); +} + + +void ejson::internal::Object::clear() { + m_value.clear(); +} + + +enum statusParsing { + parseName, + parseMiddle, + parseValue, +}; + +bool ejson::internal::Object::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + enum statusParsing mode = parseName; + std::string currentName; + EJSON_PARSE_ELEMENT("start parse : 'Object' "); + bool standalone = true; + size_t startPos = _pos+1; + if (_data[_pos] != '{' ) { // when the main node call it, it can be start with != '{' + standalone = false; + startPos = _pos; + } + for (size_t iii=startPos; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + ejson::FilePos tmpPos; + if( _data[iii] == ' ' + || _data[iii] == '\t' + || _data[iii] == '\n' + || _data[iii] == '\r') { + // white space == > nothing to do ... + } else if(_data[iii] == '#') { + // comment Line ... + for (iii++; iii<_data.size(); iii++) { + if( _data[iii] == '\n' + || _data[iii] == '\r') { + break; + } + } + } else if(_data[iii] == '}') { + // find end of value: + _pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed + return true; + } else { + if (mode == parseName) { + EJSON_PARSE_ELEMENT("name START " << '"'); + if ( _data[iii] == '"' + || _data[iii] == '\'') { + char startValue=_data[iii]; + currentName = ""; + for (iii++; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + if (_data[iii] == startValue) { + mode = parseMiddle; + break; + } else { + currentName += _data[iii]; + } + } + } else if (checkString(_data[iii]) ) { + currentName += _data[iii]; + for (iii++; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + if (false == checkString(_data[iii])) { + mode = parseMiddle; + iii--; + break; + } else { + currentName += _data[iii]; + } + } + } else { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "element unknow ..."); + _pos = iii; + return false; + } + EJSON_PARSE_ELEMENT("name END "); + } else if (mode == parseMiddle) { + EJSON_PARSE_ELEMENT(" middle ... "); + if (_data[iii] == ':') { + mode = parseValue; + } else { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "separator is not ':'"); + return false; + } + } else if (mode == parseValue) { + if (_data[iii] == '{') { + // find an object: + EJSON_PARSE_ELEMENT("find Object"); + ememory::SharedPtr tmpElement = ejson::internal::Object::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in object"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if ( _data[iii] == '"' + || _data[iii] == '\'') { + // find a string: + EJSON_PARSE_ELEMENT("find String quoted"); + ememory::SharedPtr tmpElement = ejson::internal::String::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if (_data[iii] == '[') { + // find a list: + EJSON_PARSE_ELEMENT("find List"); + ememory::SharedPtr tmpElement = ejson::internal::Array::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Array"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if( _data[iii] == 'f' + || _data[iii] == 't' ) { + // find boolean: + EJSON_PARSE_ELEMENT("find Boolean"); + ememory::SharedPtr tmpElement = ejson::internal::Boolean::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if( _data[iii] == 'n') { + // find null: + EJSON_PARSE_ELEMENT("find Null"); + ememory::SharedPtr tmpElement = ejson::internal::Null::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if(true == checkNumber(_data[iii])) { + // find number: + EJSON_PARSE_ELEMENT("find Number"); + ememory::SharedPtr tmpElement = ejson::internal::Number::create(); + if (tmpElement == nullptr) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->iParse(_data, iii, _filePos, _doc); + add(currentName, tmpElement); + currentName = ""; + } else if(_data[iii] == ',') { + // find Separator : Restart cycle ... + mode = parseName; + currentName = ""; + } else { + // find an error .... + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, std::string("Find '") + _data[iii] + "' with no element in the element..."); + // move the curent index + _pos = iii+1; + return false; + } + } + } + } + _pos = _data.size(); + if (false == standalone) { + return true; + } + return false; +} +bool ejson::internal::Object::iGenerate(std::string& _data, size_t _indent) const { + bool oneLine=true; + if (m_value.size()>3) { + oneLine=false; + } else if (_indent<=1) { + oneLine=false; + } else { + for (int32_t iii=0; iii tmp = m_value[iii]; + if (tmp == nullptr) { + continue; + } + if (tmp->isObject() == true) { + oneLine=false; + break; + } + if (tmp->isArray() == true) { + oneLine=false; + break; + } + if (tmp->isString() == true) { + ememory::SharedPtr tmp2 = tmp->toString(); + if (tmp2 != nullptr) { + if( tmp2->get().size()>25 + || m_value.getKey(iii).size()>25) { + oneLine=false; + break; + } + } + } + } + } + if (true == oneLine) { + _data += "{ "; + } else { + _data += "{\n"; + } + for (int32_t iii=0; iiiiGenerate(_data, _indent+1); + if (iii ejson::internal::Object::get(const std::string& _name) { + if (false == m_value.exist(_name)) { + return ememory::SharedPtr(); + } + return m_value[_name]; +} + +const ememory::SharedPtr ejson::internal::Object::get(const std::string& _name) const { + if (false == m_value.exist(_name)) { + return ememory::SharedPtr(); + } + return m_value[_name]; +} + +ememory::SharedPtr ejson::internal::Object::getObject(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +const ememory::SharedPtr ejson::internal::Object::getObject(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +ememory::SharedPtr ejson::internal::Object::getArray(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +const ememory::SharedPtr ejson::internal::Object::getArray(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +ememory::SharedPtr ejson::internal::Object::getNull(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +const ememory::SharedPtr ejson::internal::Object::getNull(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +ememory::SharedPtr ejson::internal::Object::getString(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +const ememory::SharedPtr ejson::internal::Object::getString(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return std::dynamic_pointer_cast(tmp); +} + +const std::string& ejson::internal::Object::getStringValue(const std::string& _name) const { + static const std::string errorString(""); + const ememory::SharedPtr tmpp = getString(_name); + if (tmpp == nullptr) { + return errorString; + } + return tmpp->get(); +} + +std::string ejson::internal::Object::getStringValue(const std::string& _name, const std::string& _errorValue) const { + const ememory::SharedPtr tmpp = getString(_name); + if (tmpp == nullptr) { + return _errorValue; + } + return tmpp->get(); +} + +ememory::SharedPtr ejson::internal::Object::getBoolean(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return tmp->toBoolean(); +} + +const ememory::SharedPtr ejson::internal::Object::getBoolean(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return tmp->toBoolean(); +} + +bool ejson::internal::Object::getBooleanValue(const std::string& _name, bool _errorValue) const { + const ememory::SharedPtr tmpp = getBoolean(_name); + if (tmpp == nullptr) { + return _errorValue; + } + return tmpp->get(); +} + +ememory::SharedPtr ejson::internal::Object::getNumber(const std::string& _name) { + ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return tmp->toNumber(); +} + +const ememory::SharedPtr ejson::internal::Object::getNumber(const std::string& _name) const { + const ememory::SharedPtr tmp = get(_name); + if (tmp == nullptr) { + return ememory::SharedPtr(); + } + return tmp->toNumber(); +} + +double ejson::internal::Object::getNumberValue(const std::string& _name, double _errorValue) const { + const ememory::SharedPtr tmpp = getNumber(_name); + if (tmpp == nullptr) { + return _errorValue; + } + return tmpp->get(); +} + + +bool ejson::internal::Object::add(const std::string& _name, ememory::SharedPtr _value) { + if (_value == nullptr) { + return false; + } + if (_name.size() == 0) { + return false; + } + if (m_value.exist(_name)) { + m_value[_name] = _value; + return true; + } + m_value.add(_name, _value); + return true; +} + +bool ejson::internal::Object::addString(const std::string& _name, const std::string& _value) { + return add(_name, ejson::internal::String::create(_value)); +} + +bool ejson::internal::Object::addNull(const std::string& _name) { + return add(_name, ejson::internal::Null::create()); +} + +bool ejson::internal::Object::addBoolean(const std::string& _name, bool _value) { + return add(_name, ejson::internal::Boolean::create(_value)); +} + +bool ejson::internal::Object::addNumber(const std::string& _name, double _value) { + return add(_name, ejson::internal::Number::create(_value)); +} + +bool ejson::internal::Object::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an nullptr pointer"); + return false; + } + ememory::SharedPtr other = _obj->toObject(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an object"); + return false; + } + // remove destination elements + other->clear(); + // Copy to the destination + other->m_value = m_value; + // remove current: + m_value.clear(); + return true; +} + +bool ejson::internal::Object::cloneIn(const ememory::SharedPtr& _obj) const { + if (_obj == nullptr) { + return false; + } + _obj->clear(); + for (int32_t iii=0; iiiadd(m_value.getKey(iii), m_value[iii]->clone()); + } + return true; +} + + +// TODO : Manage error ... +ememory::SharedPtr ejson::internal::Object::clone() const { + return cloneObj(); +} + +ememory::SharedPtr ejson::internal::Object::cloneObj() const { + ememory::SharedPtr output = ejson::internal::Object::create(); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + for (int32_t iii=0; iii val = m_value.getValue(iii); + std::string key = m_value.getKey(iii); + if (val == nullptr) { + continue; + } + output->add(key, val->clone()); + } + return output; +} diff --git a/ejson/internal/Object.h b/ejson/internal/Object.h new file mode 100644 index 0000000..55d9d9b --- /dev/null +++ b/ejson/internal/Object.h @@ -0,0 +1,229 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include +#include + +namespace ejson { + namespace internal { + class Object : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + Object() { + m_type = ejson::valueType::object; + }; + public: + static ememory::SharedPtr create(); + static ememory::SharedPtr create(const std::string& _data); + /** + * @brief destructor + */ + virtual ~Object() { }; + protected: + etk::Hash > m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) + public: + /** + * @brief check if an element exist. + * @param[in] _name name of the object. + * @return The existance of the element. + */ + bool exist(const std::string& _name) const; + /** + * @brief get the sub element with his name (no cast check) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr get(const std::string& _name); + //! @previous + const ememory::SharedPtr get(const std::string& _name) const; + //! @previous + ememory::SharedPtr operator[] (const std::string& _name) { + return get(_name); + } + //! @previous + const ememory::SharedPtr operator[] (const std::string& _name) const { + return get(_name); + } + public: + /** + * @brief Get all the element name (keys). + * @return a vector of all name (key). + */ + std::vector getKeys() const { + return m_value.getKeys(); + } + /** + * @brief get the number of sub element in the current one + * @return the Number of stored element + */ + size_t size() const { + return m_value.size(); + }; + /** + * @brief get the pointer on an element reference with his ID. + * @param[in] _id Id of the element. + * @return nullptr if the element does not exist. + */ + ememory::SharedPtr get(size_t _id) { + return m_value[_id]; + }; + //! @previous + const ememory::SharedPtr get(size_t _id) const{ + return m_value[_id]; + }; + //! @previous + ememory::SharedPtr operator[] (size_t _id) { + return m_value[_id]; + } + //! @previous + const ememory::SharedPtr operator[] (size_t _id) const { + return m_value[_id]; + } + /** + * @brief Get the element name (key). + * @param[in] _id Id of the element. + * @return The name (key). + */ + std::string getKey(size_t _id) const { + return m_value.getKey(_id); + } + /** + * @brief get the sub element with his name (Casted as Object if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getObject(const std::string& _name); + /** + * @brief get the sub element with his name (Casted as Object if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + const ememory::SharedPtr getObject(const std::string& _name) const; + /** + * @brief get the sub element with his name (Casted as Array if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getArray(const std::string& _name); + /** + * @brief get the sub element with his name (Casted as Array if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + const ememory::SharedPtr getArray(const std::string& _name) const; + /** + * @brief get the sub element with his name (Casted as Null if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getNull(const std::string& _name); + //! @previous + const ememory::SharedPtr getNull(const std::string& _name) const; + /** + * @brief get the sub element with his name (Casted as String if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getString(const std::string& _name); + //! @previous + const ememory::SharedPtr getString(const std::string& _name) const; + /** + * @brief get the sub string value of the requested element + * @param[in] _name name of the object + * @return Value of the string or an error string (empty) + */ + const std::string& getStringValue(const std::string& _name) const; + /** + * @brief get the sub string value of the requested element (with error return value) + * @param[in] _name name of the object + * @param[in] _errorValue The return value if the element does not exist. + * @return Value of the string or an error string (empty) + */ + std::string getStringValue(const std::string& _name, const std::string& _errorValue) const; + /** + * @brief get the sub element with his name (Casted as Boolean if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getBoolean(const std::string& _name); + //! @previous + const ememory::SharedPtr getBoolean(const std::string& _name) const; + /** + * @brief get the sub boolean value of the requested element. + * @param[in] _name name of the object. + * @param[in] _errorValue The return value if the element does not exist. + * @return Value of the Boolean or the _errorValue; + */ + bool getBooleanValue(const std::string& _name, bool _errorValue=false) const; + /** + * @brief get the sub element with his name (Casted as Number if it is possible) + * @param[in] _name name of the object + * @return pointer on the element requested or nullptr if it not the corect type or does not existed + */ + ememory::SharedPtr getNumber(const std::string& _name); + //! @previous + const ememory::SharedPtr getNumber(const std::string& _name) const; + /** + * @brief get the sub Number value of the requested element. + * @param[in] _name name of the object. + * @param[in] _errorValue The return value if the element does not exist. + * @return Value of the Number or the _errorValue; + */ + double getNumberValue(const std::string& _name, double _errorValue=0.0) const; + public: + /** + * @brief add an element in the Object + * @param[in] _name name of the object + * @param[in] _value Element to add + * @return false if an error occured + */ + bool add(const std::string& _name, ememory::SharedPtr _value); + /** + * @brief add a string element in the Object (automatic creation) + * @param[in] _name name of the object + * @param[in] _value string value to add + * @return false if an error occured + */ + bool addString(const std::string& _name, const std::string& _value); + /** + * @brief add a "null" element in the Object (automatic creation) + * @param[in] _name name of the object + * @return false if an error occured + */ + bool addNull(const std::string& _name); + /** + * @brief add a boolean element in the Object (automatic creation) + * @param[in] _name name of the object + * @param[in] _value boolean value to add + * @return false if an error occured + */ + bool addBoolean(const std::string& _name, bool _value); + /** + * @brief add a double element in the Object (automatic creation) + * @param[in] _name name of the object + * @param[in] _value double value to add + * @return false if an error occured + */ + bool addNumber(const std::string& _name, double _value); + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual void clear(); + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual bool cloneIn(const ememory::SharedPtr& _obj) const; + virtual ememory::SharedPtr clone() const; + virtual ememory::SharedPtr cloneObj() const; + }; + } +} + diff --git a/ejson/internal/String.cpp b/ejson/internal/String.cpp new file mode 100644 index 0000000..82bb9bf --- /dev/null +++ b/ejson/internal/String.cpp @@ -0,0 +1,75 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + + +#include +#include +#include +#include +#include + +ememory::SharedPtr ejson::internal::String::create(const std::string& _value) { + return ememory::SharedPtr(new ejson::internal::String(_value)); +} + +bool ejson::internal::String::iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) { + EJSON_PARSE_ELEMENT("start parse : 'String' "); + char end = _data[_pos]; + for (size_t iii=_pos+1; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + #ifdef ENABLE_DISPLAY_PARSED_ELEMENT + drawElementParsed(_data[iii], _filePos); + #endif + ejson::FilePos tmpPos; + // TODO : manage \x + if(_data[iii] != end) { + m_value += _data[iii]; + } else { + _pos = iii; + return true; + } + } + _pos=_data.size(); + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); + return false; +} + + +bool ejson::internal::String::iGenerate(std::string& _data, size_t _indent) const { + _data += "\"";; + _data += m_value; + _data += "\"";; + return true; +} + + +bool ejson::internal::String::transfertIn(ememory::SharedPtr _obj) { + if (_obj == nullptr) { + EJSON_ERROR("Request transfer on an nullptr pointer"); + return false; + } + ememory::SharedPtr other = _obj->toString(); + if (other == nullptr) { + EJSON_ERROR("Request transfer on an element that is not an String"); + return false; + } + other->m_value = m_value; + m_value = ""; + return true; +} + +ememory::SharedPtr ejson::internal::String::clone() const { + ememory::SharedPtr output = ejson::internal::String::create(m_value); + if (output == nullptr) { + EJSON_ERROR("Allocation error ..."); + return ememory::SharedPtr(); + } + return output; +} + + diff --git a/ejson/internal/String.h b/ejson/internal/String.h new file mode 100644 index 0000000..bbf5274 --- /dev/null +++ b/ejson/internal/String.h @@ -0,0 +1,55 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + namespace internal { + class String : public ejson::internal::Value { + protected: + /** + * @brief basic element of a xml structure + */ + String(const std::string& _value="") : + m_value(_value) { + m_type = ejson::valueType::string; + }; + public: + static ememory::SharedPtr create(const std::string& _value=""); + /** + * @brief destructor + */ + virtual ~String() { }; + protected: + std::string m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) + public: + /** + * @brief set the value of the node. + * @param[in] _value New value of the node. + */ + void set(const std::string& _value) { + m_value = _value; + }; + /** + * @brief get the current element Value. + * @return the reference of the string value. + */ + const std::string& get() const { + return m_value; + }; + public: // herited function : + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc); + virtual bool iGenerate(std::string& _data, size_t _indent) const; + virtual bool transfertIn(ememory::SharedPtr _obj); + virtual ememory::SharedPtr clone() const; + }; + } +} + diff --git a/ejson/internal/Value.cpp b/ejson/internal/Value.cpp new file mode 100644 index 0000000..719b302 --- /dev/null +++ b/ejson/internal/Value.cpp @@ -0,0 +1,210 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include + + +enum ejson::valueType ejson::internal::Value::getType() const { + return m_type; +} + +ejson::internal::Value::~Value() { + clear(); +} + +bool ejson::internal::Value::isWhiteChar(char32_t _val) { + if( _val == ' ' + || _val == '\t' + || _val == '\n' + || _val == '\r') { + return true; + } + return false; +} + +void ejson::internal::Value::addIndent(std::string& _data, size_t _indent) const { + for (size_t iii=0; iii<_indent; iii++) { + _data+="\t"; + } +} + +void ejson::internal::Value::drawElementParsed(char32_t _val, const ejson::FilePos& _filePos) const { + if (_val == '\n') { + EJSON_DEBUG(_filePos << " parse '\\n'"); + } else if (_val == '\t') { + EJSON_DEBUG(_filePos << " parse '\\t'"); + } else { + EJSON_DEBUG(_filePos << " parse '" << _val << "'"); + } +} + +int32_t ejson::internal::Value::countWhiteChar(const std::string& _data, size_t _pos, ejson::FilePos& _filePos) const { + _filePos.clear(); + size_t white=0; + for (size_t iii=_pos; iii<_data.size(); iii++) { + _filePos.check(_data[iii]); + if(true == isWhiteChar(_data[iii])) { + white++; + } else { + break; + } + } + --_filePos; + return white; +} + +bool ejson::internal::Value::checkString(char32_t _val) const { + if( _val == '!' + || _val == '"' + || _val == '#' + || _val == '$' + || _val == '%' + || _val == '&' + || _val == '\'' // ' + || _val == '(' + || _val == ')' + || _val == '*' + || _val == '+' + || _val == ',' + || _val == '/' + || _val == ':' + || _val == ';' + || _val == '<' + || _val == '=' + || _val == '>' + || _val == '?' + || _val == '@' + || _val == '[' + || _val == '\\' + || _val == ']' + || _val == '^' + || _val == '`' + || _val == '{' + || _val == '|' + || _val == '}' + || _val == '~' + || _val == ' ' + || _val == '\n' + || _val == '\t' + || _val == '\r') { + return false; + } + return true; +} + +bool ejson::internal::Value::checkNumber(char32_t _val) const { + if( _val == '-' + || _val == '+' + || _val == 'e' + || _val == '.' + || ( _val>='0' + && _val<='9' ) ) { + return true; + } + return false; +} + +ememory::SharedPtr ejson::internal::Value::toValue() { + return shared_from_this(); +}; +const ememory::SharedPtr ejson::internal::Value::toValue() const { + return shared_from_this(); +}; +ememory::SharedPtr ejson::internal::Value::toDocument() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toDocument() const { + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toArray() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toArray() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toObject() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toObject() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toString() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toString() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toNumber() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toNumber() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toBoolean() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toBoolean() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; +ememory::SharedPtr ejson::internal::Value::toNull() { + return std::dynamic_pointer_cast(shared_from_this()); +}; +const ememory::SharedPtr ejson::internal::Value::toNull() const{ + return std::dynamic_pointer_cast(shared_from_this()); +}; + +void ejson::internal::Value::display() const { + std::string tmpp; + iGenerate(tmpp, 0); + EJSON_INFO("Generated JSON : \n" << tmpp); +} + + +bool ejson::internal::Value::isDocument() const { + return toDocument() != nullptr; +} + +bool ejson::internal::Value::isArray() const { + return toArray() != nullptr; +} + +bool ejson::internal::Value::isObject() const { + return toObject() != nullptr; +} + +bool ejson::internal::Value::isString() const { + return toString() != nullptr; +} + +bool ejson::internal::Value::isNumber() const { + return toNumber() != nullptr; +} + +bool ejson::internal::Value::isBoolean() const { + return toBoolean() != nullptr; +} + +bool ejson::internal::Value::isNull() const { + return toNull() != nullptr; +} + + +void ejson::internal::Value::clear() { + +} + +bool ejson::internal::Value::transfertIn(ememory::SharedPtr _obj) { + return false; +} + +ememory::SharedPtr ejson::internal::Value::clone() const { + return ememory::SharedPtr(); +} + diff --git a/ejson/internal/Value.h b/ejson/internal/Value.h new file mode 100644 index 0000000..efbe869 --- /dev/null +++ b/ejson/internal/Value.h @@ -0,0 +1,265 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include +#include + +/** + * @brief ejson namespace containing all function for JSON interpretor + */ +namespace ejson { + //#define ENABLE_DISPLAY_PARSED_ELEMENT + #if 1 + #define EJSON_PARSE_ELEMENT EJSON_VERBOSE + #else + #define EJSON_PARSE_ELEMENT EJSON_DEBUG + #endif + #if 1 + #define EJSON_PARSE_ATTRIBUTE EJSON_VERBOSE + #else + #define EJSON_PARSE_ATTRIBUTE EJSON_DEBUG + #endif + namespace internal { + class Document; + class Array; + class Object; + class Boolean; + class Null; + class Number; + class String; + /** + * @brief Basic main object of all json elements. + */ + class Value : public ememory::EnableSharedFromThis { + protected: + enum ejson::valueType m_type; //!< Type of the element + public: + /** + * @brief Get Value type + * @return Type of the object + */ + enum ejson::valueType getType() const; + protected: + /** + * @brief basic element of a xml structure + */ + Value() : + m_type(ejson::valueType::unknow) { + m_type = ejson::valueType::value; + }; + /** + * @brief Virtualize destructor + */ + virtual ~Value(); + public: + /** + * @brief parse the Current node [pure VIRUAL] + * @param[in] _data data string to parse. + * @param[in,out] _pos position in the string to start parse, return the position end of parsing. + * @param[in] _caseSensitive Request a parsion of element that is not case sensitive (all element is in low case) + * @param[in,out] file parsing position (line x col x) + * @return false if an error occured. + */ + virtual bool iParse(const std::string& _data, size_t& _pos, ejson::FilePos& _filePos, ejson::internal::Document& _doc) = 0; + /** + * @brief generate a string with the tree of the xml + * @param[in,out] _data string where to add the elements + * @param[in] current indentation of the file + * @return false if an error occured. + */ + virtual bool iGenerate(std::string& _data, size_t _indent) const = 0; + /** + * @brief Display the Document on console + */ + void display() const; + protected: + /** + * @brief add indentation of the string input. + * @param[in,out] _data String where the indentation is done. + * @param[in] _indent Number of tab to add at the string. + */ + void addIndent(std::string& _data, size_t _indent) const; + /** + * @brief Display the cuurent element that is curently parse. + * @param[in] _val Char that is parsed. + * @param[in] _filePos Position of the char in the file. + */ + void drawElementParsed(char32_t _val, const ejson::FilePos& _filePos) const; + /** + * @brief check if an name (for object named) (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \n\t\r). + * @param[in] _val Value to check the conformity. + */ + bool checkString(char32_t _val) const; + /** + * @brief check if an number -+.0123456789e). + * @param[in] _val Value to check the conformity. + */ + bool checkNumber(char32_t _val) const; + /** + * @brief count the number of white char in the string from the specify position (stop at the first element that is not a white char) + * @param[in] _data Data to parse. + * @param[in] _pos Start position in the string. + * @param[out] _filePos new poistion of te file to add. + * @return number of white element. + */ + int32_t countWhiteChar(const std::string& _data, size_t _pos, ejson::FilePos& _filePos) const; + public: + /** + * @brief Cast the element in a Value if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toValue(); + /** + * @brief Cast the element in a Value if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toValue() const; + /** + * @brief Cast the element in a Document if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toDocument(); + /** + * @brief Cast the element in a Document if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toDocument() const; + /** + * @brief Cast the element in a Array if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toArray(); + /** + * @brief Cast the element in a Array if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toArray() const; + /** + * @brief Cast the element in a Object if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toObject(); + /** + * @brief Cast the element in a Object if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toObject() const; + /** + * @brief Cast the element in a String if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toString(); + /** + * @brief Cast the element in a String if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toString() const; + /** + * @brief Cast the element in a Number if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toNumber(); + /** + * @brief Cast the element in a Number if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toNumber() const; + /** + * @brief Cast the element in a Boolean if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toBoolean(); + /** + * @brief Cast the element in a Boolean if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toBoolean() const; + /** + * @brief Cast the element in a Null if it is possible. + * @return pointer on the class or nullptr. + */ + ememory::SharedPtr toNull(); + /** + * @brief Cast the element in a Null if it is possible. + * @return CONST pointer on the class or nullptr. + */ + const ememory::SharedPtr toNull() const; + + /** + * @brief check if the node is a ejson::internal::Document + * @return true if the node is a ejson::internal::Document + */ + bool isDocument() const; + /** + * @brief check if the node is a ejson::internal::Array + * @return true if the node is a ejson::internal::Array + */ + bool isArray() const; + /** + * @brief check if the node is a ejson::internal::Object + * @return true if the node is a ejson::internal::Object + */ + bool isObject() const; + /** + * @brief check if the node is a ejson::internal::String + * @return true if the node is a ejson::internal::String + */ + bool isString() const; + /** + * @brief check if the node is a ejson::internal::Number + * @return true if the node is a ejson::internal::Number + */ + bool isNumber() const; + /** + * @brief check if the node is a ejson::internal::Boolean + * @return true if the node is a ejson::internal::Boolean + */ + bool isBoolean() const; + /** + * @brief check if the node is a ejson::internal::Null + * @return true if the node is a ejson::internal::Null + */ + bool isNull() const; + + /** + * @brief clear the Node + */ + virtual void clear(); + /** + * @brief Tranfert all element in the element set in parameter + * @param[in,out] _obj move all parameter in the selected element + * @return true if transfer is done corectly + * @note all element is remove from the curent element. + */ + virtual bool transfertIn(ememory::SharedPtr _obj); + /** + * @brief Copy the curent node and all the child in the curent one. + * @return nullptr in an error occured, the pointer on the element otherwise + */ + virtual ememory::SharedPtr clone() const; + protected: + /** + * @brief check if the current element is white or not : '\t' '\n' '\r' ' ' + * @return tue if it is white char + */ + static bool isWhiteChar(char32_t _val); + }; + } +} + +#include +#include +#include +#include +#include +#include +#include + diff --git a/ejson/iterator.h b/ejson/iterator.h new file mode 100644 index 0000000..97a3546 --- /dev/null +++ b/ejson/iterator.h @@ -0,0 +1,101 @@ +/** @file + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace ejson { + /** + * iterator on elements. + */ + template + class iterator { + private: + EJSON_BASE_T& m_data; //!< Reference on the ejson::Element + size_t m_id; //!< Id of the element that we are parsing + public: + iterator(EJSON_BASE_T& _obj, size_t _pos); + iterator(const EJSON_BASE_T& _obj, size_t _pos); + iterator(const iterator& _obj); + /** + * @brief Operator+= Addition value + * @param[in] _val Value to addition + * @return Local reference of the iterator additionned + */ + iterator& operator= (const iterator& _obj); + /** + * @brief Operator+= Addition value + * @param[in] _val Value to addition + * @return Local reference of the iterator additionned + */ + iterator& operator+= (int32_t _val); + /** + * @brief Operator+ Addition a value + * @param[in] _val Value to addition + * @return New iterator containing the value + */ + iterator operator+ (int32_t _val) const; + /** + * @brief Operator-= Decrement a value + * @param[in] _val Value to addition + * @return Local reference of the iterator decremented + */ + iterator& operator-= (int32_t _val); + /** + * @brief Operator- Decrement a value + * @param[in] _val Value to addition + * @return New iterator containing the value + */ + iterator operator- (int32_t _val) const; + /** + * @brief Operator++ Pre-incrementation of this iterator + * @return Local reference of the iterator incremented + */ + iterator& operator++(); + /** + * @brief Operator++ Post-incrementation of this iterator + * @return New iterator containing the last value + */ + iterator operator++(int); + /** + * @brief Operator++ Pre-decrementation of this iterator + * @return Local reference of the iterator incremented + */ + iterator& operator--(); + /** + * @brief Operator++ Post-decrementation of this iterator + * @return New iterator containing the last value + */ + iterator operator--(int); + /** + * @brief Equality compare operator with an other iterator. + * @param[in] _obj Reference on the comparing iterator + * @return true The iterators are identical + * @return false The iterators are NOT identical + */ + bool operator== (const iterator& _obj) const; + /** + * @brief In-Equality compare operator with an other iterator. + * @param[in] _obj Reference on the comparing iterator + * @return true The iterators are NOT identical + * @return false The iterators are identical + */ + bool operator!= (const iterator& _obj) const; + /** + * @brief Get the property Value + * @return Const reference on the value. + */ + const ejson::Value operator *() const noexcept; + /** + * @brief Get the property Value + * @return Const reference on the value. + */ + ejson::Value operator *() noexcept; + }; +} diff --git a/ejson/valueType.cpp b/ejson/valueType.cpp new file mode 100644 index 0000000..4f4a2ba --- /dev/null +++ b/ejson/valueType.cpp @@ -0,0 +1,46 @@ +/** @file + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include + + + +std::ostream& ejson::operator <<(std::ostream& _os, enum ejson::valueType _obj) { + switch (_obj) { + case ejson::valueType::unknow: + _os << "exml::valueType::unknow"; + break; + case ejson::valueType::value: + _os << "exml::valueType::value"; + break; + case ejson::valueType::document: + _os << "exml::valueType::document"; + break; + case ejson::valueType::array: + _os << "exml::valueType::array"; + break; + case ejson::valueType::object: + _os << "exml::valueType::object"; + break; + case ejson::valueType::string: + _os << "exml::valueType::string"; + break; + case ejson::valueType::number: + _os << "exml::valueType::number"; + break; + case ejson::valueType::null: + _os << "exml::valueType::null"; + break; + case ejson::valueType::boolean: + _os << "exml::valueType::boolean"; + break; + } + return _os; +} + diff --git a/ejson/valueType.h b/ejson/valueType.h new file mode 100644 index 0000000..38b4f67 --- /dev/null +++ b/ejson/valueType.h @@ -0,0 +1,30 @@ +/** @file + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace ejson { + /** + * @brief Type of the JSON elements. + */ + enum class valueType { + unknow, //!< might be an error ... + value, //!< might be an error ... + document, //!< all the file main access + array, //!< te element [ ... ] + object, //!< the element { ... } + string, //!< the element "..." + number, //!< The element 1111.2222 + null, //!< the element null + boolean, //!< the element true or false + }; + //! @not_in_doc + std::ostream& operator <<(std::ostream& _os, enum valueType _obj); +} + diff --git a/lutin_ejson.py b/lutin_ejson.py index 457dc9a..447e472 100644 --- a/lutin_ejson.py +++ b/lutin_ejson.py @@ -31,25 +31,46 @@ def create(target, module_name): my_module.add_src_file([ 'ejson/debug.cpp', 'ejson/FilePos.cpp', - 'ejson/ejson.cpp', + 'ejson/valueType.cpp', + 'ejson/Document.cpp', 'ejson/Array.cpp', 'ejson/Boolean.cpp', 'ejson/Null.cpp', 'ejson/Number.cpp', 'ejson/String.cpp', 'ejson/Object.cpp', - 'ejson/Value.cpp' + 'ejson/Value.cpp', + 'ejson/internal/Document.cpp', + 'ejson/internal/Array.cpp', + 'ejson/internal/Boolean.cpp', + 'ejson/internal/Null.cpp', + 'ejson/internal/Number.cpp', + 'ejson/internal/String.cpp', + 'ejson/internal/Object.cpp', + 'ejson/internal/Value.cpp' ]) my_module.add_header_file([ 'ejson/FilePos.h', 'ejson/ejson.h', + 'ejson/valueType.h', + 'ejson/Document.h', 'ejson/Array.h', 'ejson/Boolean.h', 'ejson/Null.h', 'ejson/Number.h', 'ejson/String.h', 'ejson/Object.h', - 'ejson/Value.h' + 'ejson/Value.h', + 'ejson/iterator.h', + 'ejson/details/iterator.hxx', + 'ejson/internal/Document.h', + 'ejson/internal/Array.h', + 'ejson/internal/Boolean.h', + 'ejson/internal/Null.h', + 'ejson/internal/Number.h', + 'ejson/internal/String.h', + 'ejson/internal/Object.h', + 'ejson/internal/Value.h' ]) my_module.add_path(tools.get_current_path(__file__)) return my_module