From e7723856e4504b2a6e37554d8dc202c152487300 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Wed, 21 Aug 2013 21:11:12 +0200 Subject: [PATCH] [DEV] add multiple access , and memory leek corection --- ejson/Array.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++- ejson/Array.h | 65 +++++++++++++++++++++---------------- ejson/Object.cpp | 81 +++++++++++++++++++++++++++++++++++++++------- ejson/Object.h | 67 +++++++++++++++++++------------------- ejson/String.cpp | 29 +++++++++++++++++ ejson/String.h | 35 +++----------------- ejson/Value.cpp | 5 +++ ejson/Value.h | 14 +++++++- 8 files changed, 275 insertions(+), 104 deletions(-) diff --git a/ejson/Array.cpp b/ejson/Array.cpp index 71ef39f..356f1d4 100644 --- a/ejson/Array.cpp +++ b/ejson/Array.cpp @@ -19,7 +19,14 @@ void ejson::Array::Clear(void) { - + for (esize_t iii=0; iiiToArray(); + if (NULL==other) { + 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; +} + +// TODO : Manage error ... +ejson::Value* ejson::Array::Duplicate(void) const +{ + ejson::Array* output = new ejson::Array(); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + for (esize_t iii=0; iiiAdd(val->Duplicate()); + } + return output; +} + +ejson::Object* ejson::Array::GetObject(esize_t _id) +{ + ejson::Value* tmpElement = m_value[_id]; + if (NULL == tmpElement) { + return NULL; + } + return tmpElement->ToObject(); +} + +ejson::String* ejson::Array::GetString(esize_t _id) +{ + ejson::Value* tmpElement = m_value[_id]; + if (NULL == tmpElement) { + return NULL; + } + return tmpElement->ToString(); +} + +ejson::Array* ejson::Array::GetArray(esize_t _id) +{ + ejson::Value* tmpElement = m_value[_id]; + if (NULL == tmpElement) { + return NULL; + } + return tmpElement->ToArray(); +} + diff --git a/ejson/Array.h b/ejson/Array.h index 82ec2a0..e278ba9 100644 --- a/ejson/Array.h +++ b/ejson/Array.h @@ -27,45 +27,54 @@ namespace ejson * @brief destructor */ virtual ~Array(void) { }; - 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 etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); - /** - * @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(etk::UString& _data, int32_t _indent) const; private: etk::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 + */ esize_t Size(void) { return m_value.Size(); }; + /** + * @brief Get the pointer on an element reference with his ID. + * @param[in] _id Id of the element. + * @return NULL if the element does not exist. + */ ejson::Value* Get(esize_t _id) { return m_value[_id]; }; - public: /** - * @brief Get the node type. - * @return the type of the Node. + * @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 NULL if the element does not exist. */ + ejson::Object* GetObject(esize_t _id); + /** + * @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 NULL if the element does not exist. + */ + ejson::String* GetString(esize_t _id); + /** + * @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 NULL if the element does not exist. + */ + ejson::Array* GetArray(esize_t _id); + /** + * @brief Add an element on the array. + * @param[in] _element element to add. + * @return false if an error occured. + */ + bool Add(ejson::Value* _element); + + public: // herited function : + virtual bool IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); + virtual bool IGenerate(etk::UString& _data, int32_t _indent) const; virtual nodeType_te GetType(void) const { return typeArray; }; - public: - /** - * @brief Cast the element in a Array if it is possible. - * @return pointer on the class or NULL. - */ virtual ejson::Array* ToArray(void) { return this; }; virtual const ejson::Array* ToArray(void) const{ return this; }; - /** - * @brief Clear the Node - */ virtual void Clear(void); + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; }; }; diff --git a/ejson/Object.cpp b/ejson/Object.cpp index 0b9a7e5..e3281d0 100644 --- a/ejson/Object.cpp +++ b/ejson/Object.cpp @@ -18,8 +18,17 @@ void ejson::Object::Clear(void) { - + for (esize_t iii=0; iiiIParse(_data, iii, _filePos, _doc); - m_value.Add(currentName, tmpElement); + AddSub(currentName, tmpElement); currentName = ""; } else if (_data[iii]=='"') { // find a string: @@ -115,7 +124,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file return false; } tmpElement->IParse(_data, iii, _filePos, _doc); - m_value.Add(currentName, tmpElement); + AddSub(currentName, tmpElement); currentName = ""; } else if (_data[iii]=='[') { // find a list: @@ -127,7 +136,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file return false; } tmpElement->IParse(_data, iii, _filePos, _doc); - m_value.Add(currentName, tmpElement); + AddSub(currentName, tmpElement); currentName = ""; } else if( CheckAvaillable(_data[iii]) ) { // find a string without "" ==> special hook for the etk-json parser @@ -142,7 +151,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file tmpElement->IParse(_data, iii, _filePos, _doc); iii--; //JSON_ERROR(" add : " << currentName ); - m_value.Add(currentName, tmpElement); + AddSub(currentName, tmpElement); currentName = ""; } else if(_data[iii]==',') { // find Separator : Restart cycle ... @@ -183,12 +192,15 @@ bool ejson::Object::IGenerate(etk::UString& _data, int32_t _indent) const ejson::Value* ejson::Object::GetSub(const etk::UString& _named) const { + if (false==m_value.Exist(_named)) { + return NULL; + } return m_value[_named]; } ejson::Object* ejson::Object::GetSubObject(const etk::UString& _named) const { - ejson::Value* tmp = m_value[_named]; + ejson::Value* tmp = GetSub(_named); if (NULL == tmp) { return NULL; } @@ -197,7 +209,7 @@ ejson::Object* ejson::Object::GetSubObject(const etk::UString& _named) const ejson::String* ejson::Object::GetSubString(const etk::UString& _named) const { - ejson::Value* tmp = m_value[_named]; + ejson::Value* tmp = GetSub(_named); if (NULL == tmp) { return NULL; } @@ -206,7 +218,7 @@ ejson::String* ejson::Object::GetSubString(const etk::UString& _named) const ejson::Array* ejson::Object::GetSubArray(const etk::UString& _named) const { - ejson::Value* tmp = m_value[_named]; + ejson::Value* tmp = GetSub(_named); if (NULL == tmp) { return NULL; } @@ -214,14 +226,61 @@ ejson::Array* ejson::Object::GetSubArray(const etk::UString& _named) const } -void ejson::Object::AddSub(const etk::UString& _name, ejson::Value* _value) +bool ejson::Object::AddSub(const etk::UString& _name, ejson::Value* _value) { if (NULL == _value) { - return; + return false; } if (_name.Size()==0) { - return; + return false; + } + if (m_value.Exist(_name)) { + ejson::Value* tmp = m_value[_name]; + delete(tmp); + m_value[_name] = _value; + return true; } m_value.Add(_name, _value); + return true; } + + +bool ejson::Object::TransfertIn(ejson::Value* _obj) +{ + if (NULL==_obj) { + JSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ejson::Object* other = _obj->ToObject(); + if (NULL==other) { + 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; +} + +// TODO : Manage error ... +ejson::Value* ejson::Object::Duplicate(void) const +{ + ejson::Object* output = new ejson::Object(); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + for (esize_t iii=0; iiiAddSub(key, val->Duplicate()); + } + return output; +} diff --git a/ejson/Object.h b/ejson/Object.h index fc20483..dd65353 100644 --- a/ejson/Object.h +++ b/ejson/Object.h @@ -28,49 +28,50 @@ namespace ejson * @brief destructor */ virtual ~Object(void) { }; - 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 etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); - /** - * @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(etk::UString& _data, int32_t _indent) const; protected: etk::Hash m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) public: - ejson::Value* GetSub(const etk::UString& _named) const; - ejson::Object* GetSubObject(const etk::UString& _named) const; - ejson::String* GetSubString(const etk::UString& _named) const; - ejson::Array* GetSubArray(const etk::UString& _named) const; - public: - void AddSub(const etk::UString& _name, ejson::Value* _value); + /** + * @brief Get tht sub element with his name (no cast check) + * @param[in] _name name of the object + * @return pointer on the element requested or NULL if it not the corect type or does not existed + */ + ejson::Value* GetSub(const etk::UString& _name) const; + /** + * @brief Get tht 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 NULL if it not the corect type or does not existed + */ + ejson::Object* GetSubObject(const etk::UString& _name) const; + /** + * @brief Get tht 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 NULL if it not the corect type or does not existed + */ + ejson::String* GetSubString(const etk::UString& _name) const; + /** + * @brief Get tht 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 NULL if it not the corect type or does not existed + */ + ejson::Array* GetSubArray(const etk::UString& _name) const; public: /** - * @brief Get the node type. - * @return the type of the Node. + * @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 AddSub(const etk::UString& _name, ejson::Value* _value); + public: // herited function : + virtual bool IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); + virtual bool IGenerate(etk::UString& _data, int32_t _indent) const; virtual nodeType_te GetType(void) const { return typeObject; }; - public: - /** - * @brief Cast the element in a Object if it is possible. - * @return pointer on the class or NULL. - */ virtual ejson::Object* ToObject(void) { return this; }; virtual const ejson::Object* ToObject(void) const{ return this; }; - /** - * @brief Clear the Node - */ virtual void Clear(void); + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; }; }; diff --git a/ejson/String.cpp b/ejson/String.cpp index ad5b0d8..1dbb990 100644 --- a/ejson/String.cpp +++ b/ejson/String.cpp @@ -71,5 +71,34 @@ bool ejson::String::IGenerate(etk::UString& _data, int32_t _indent) const } +bool ejson::String::TransfertIn(ejson::Value* _obj) +{ + if (NULL==_obj) { + JSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ejson::String* other = _obj->ToString(); + if (NULL==other) { + JSON_ERROR("Request transfer on an element that is not an String"); + return false; + } + // remove destination elements + other->m_quoted = m_quoted; + other->m_value = m_value; + m_quoted = true; + m_value = ""; + return true; +} + +ejson::Value* ejson::String::Duplicate(void) const +{ + ejson::String* output = new ejson::String(m_quoted); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + output->SetValue(m_value); + return output; +} diff --git a/ejson/String.h b/ejson/String.h index 2767198..49d21cb 100644 --- a/ejson/String.h +++ b/ejson/String.h @@ -30,23 +30,6 @@ namespace ejson * @brief destructor */ virtual ~String(void) { }; - 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 etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); - /** - * @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(etk::UString& _data, int32_t _indent) const; protected: etk::UString m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) public: @@ -60,23 +43,15 @@ namespace ejson * @return the reference of the string value. */ const etk::UString& GetValue(void) const { return m_value; }; - public: - /** - * @brief Get the node type. - * @return the type of the Node. - */ + public: // herited function : + virtual bool IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); + virtual bool IGenerate(etk::UString& _data, int32_t _indent) const; virtual nodeType_te GetType(void) const { return typeString; }; - public: - /** - * @brief Cast the element in a Object if it is possible. - * @return pointer on the class or NULL. - */ virtual ejson::String* ToString(void) { return this; }; virtual const ejson::String* ToString(void) const{ return this; }; - /** - * @brief Clear the Node - */ virtual void Clear(void); + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; }; }; diff --git a/ejson/Value.cpp b/ejson/Value.cpp index 386ade0..23db8ef 100644 --- a/ejson/Value.cpp +++ b/ejson/Value.cpp @@ -14,6 +14,11 @@ #define __class__ "Value" +ejson::Value::~Value(void) +{ + Clear(); +} + etk::CCout& ejson::operator <<(etk::CCout& _os, const ejson::filePos& _obj) { _os << "(l="; diff --git a/ejson/Value.h b/ejson/Value.h index e6cc3a9..0b8032c 100644 --- a/ejson/Value.h +++ b/ejson/Value.h @@ -107,7 +107,7 @@ namespace ejson /** * @brief destructor */ - virtual ~Value(void) { }; + virtual ~Value(void); public: /** * @brief Parse the Current node [pure VIRUAL] @@ -215,6 +215,18 @@ namespace ejson * @brief Clear the Node */ virtual void Clear(void) {}; + /** + * @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(ejson::Value* _obj) { return false; }; + /** + * @brief Copy the curent node and all the child in the curent one. + * @return NULL in an error occured, the pointer on the element otherwise + */ + virtual ejson::Value* Duplicate(void) const { return NULL; }; }; };