[DEV] add multiple access , and memory leek corection

This commit is contained in:
Edouard DUPIN 2013-08-21 21:11:12 +02:00
parent 3c102ab263
commit e7723856e4
8 changed files with 275 additions and 104 deletions

View File

@ -19,7 +19,14 @@
void ejson::Array::Clear(void)
{
for (esize_t iii=0; iii<m_value.Size(); ++iii) {
if (NULL == m_value[iii]) {
continue;
}
delete(m_value[iii]);
m_value[iii] = NULL;
}
m_value.Clear();
}
bool ejson::Array::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc)
@ -119,6 +126,80 @@ bool ejson::Array::IGenerate(etk::UString& _data, int32_t _indent) const
return true;
}
bool ejson::Array::Add(ejson::Value* _element)
{
if (NULL==_element) {
JSON_ERROR("Request add on an NULL pointer");
return false;
}
m_value.PushBack(_element);
return true;
}
bool ejson::Array::TransfertIn(ejson::Value* _obj)
{
if (NULL==_obj) {
JSON_ERROR("Request transfer on an NULL pointer");
return false;
}
ejson::Array* other = _obj->ToArray();
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; iii<m_value.Size(); ++iii) {
ejson::Value* val = m_value[iii];
if (NULL == val) {
continue;
}
output->Add(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();
}

View File

@ -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<ejson::Value*> 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;
};
};

View File

@ -18,8 +18,17 @@
void ejson::Object::Clear(void)
{
for (esize_t iii=0; iii<m_value.Size(); ++iii) {
if (NULL == m_value[iii]) {
continue;
}
delete(m_value[iii]);
m_value[iii] = NULL;
}
m_value.Clear();
}
typedef enum {
parseName,
parseMiddle,
@ -103,7 +112,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 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; iii<m_value.Size(); ++iii) {
ejson::Value* val = m_value.GetValue(iii);
etk::UString key = m_value.GetKey(iii);
if (NULL == val) {
continue;
}
output->AddSub(key, val->Duplicate());
}
return output;
}

View File

@ -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<ejson::Value*> 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;
};
};

View File

@ -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;
}

View File

@ -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;
};
};

View File

@ -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=";

View File

@ -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; };
};
};