From b68b4f7b82d0ed0351958ef7691e5bfafd07f4ce Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 22 Aug 2013 21:38:20 +0200 Subject: [PATCH] [DEV] rework json to have a full complient json parser --- ejson/Array.cpp | 39 ++++++++++++++++++---- ejson/Boolean.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++ ejson/Boolean.h | 55 +++++++++++++++++++++++++++++++ ejson/Null.cpp | 68 ++++++++++++++++++++++++++++++++++++++ ejson/Null.h | 42 ++++++++++++++++++++++++ ejson/Number.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++ ejson/Number.h | 55 +++++++++++++++++++++++++++++++ ejson/Object.cpp | 49 +++++++++++++++++++++------- ejson/String.cpp | 45 ++++++------------------- ejson/String.h | 6 +--- ejson/Value.cpp | 51 ++++++----------------------- ejson/Value.h | 53 +++++++++++++++++++++++++++--- ejson/ejson.cpp | 36 +++++++++++++++++--- ejson/test.cpp | 2 ++ lutin_ejson.py | 3 ++ 15 files changed, 551 insertions(+), 110 deletions(-) create mode 100644 ejson/Boolean.cpp create mode 100644 ejson/Boolean.h create mode 100644 ejson/Null.cpp create mode 100644 ejson/Null.h create mode 100644 ejson/Number.cpp create mode 100644 ejson/Number.h diff --git a/ejson/Array.cpp b/ejson/Array.cpp index 356f1d4..f5d95f9 100644 --- a/ejson/Array.cpp +++ b/ejson/Array.cpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #include #include @@ -61,7 +64,7 @@ bool ejson::Array::IParse(const etk::UString& _data, int32_t& _pos, ejson::fileP } else if (_data[iii]=='"') { // find a string: JSON_PARSE_ELEMENT("find String quoted"); - ejson::String * tmpElement = new ejson::String(true); + ejson::String * tmpElement = new ejson::String(); if (NULL==tmpElement) { EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); _pos=iii; @@ -80,17 +83,39 @@ bool ejson::Array::IParse(const etk::UString& _data, int32_t& _pos, ejson::fileP } tmpElement->IParse(_data, iii, _filePos, _doc); m_value.PushBack(tmpElement); - } else if( CheckAvaillable(_data[iii]) ) { - // find a string without "" ==> special hook for the etk-json parser - JSON_PARSE_ELEMENT("find String"); - ejson::String * tmpElement = new ejson::String(false); + } else if( _data[iii] == 'f' + || _data[iii] == 't' ) { + // find boolean: + JSON_PARSE_ELEMENT("find Boolean"); + ejson::Boolean * tmpElement = new ejson::Boolean(); if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii-1, _filePos, "Allocation error in String"); + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + m_value.PushBack(tmpElement); + } else if( _data[iii] == 'n') { + // find null: + JSON_PARSE_ELEMENT("find Null"); + ejson::Null * tmpElement = new ejson::Null(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + m_value.PushBack(tmpElement); + } else if(true==CheckNumber(_data[iii])) { + // find number: + JSON_PARSE_ELEMENT("find Number"); + ejson::Number * tmpElement = new ejson::Number(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); _pos=iii; return false; } tmpElement->IParse(_data, iii, _filePos, _doc); - JSON_PARSE_ELEMENT("find String (end)"); m_value.PushBack(tmpElement); } else if(_data[iii]==',') { // find Separator : Restart cycle ... diff --git a/ejson/Boolean.cpp b/ejson/Boolean.cpp new file mode 100644 index 0000000..5a916aa --- /dev/null +++ b/ejson/Boolean.cpp @@ -0,0 +1,83 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include +#include + +#undef __class__ +#define __class__ "Boolean" + +bool ejson::Boolean::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc) +{ + JSON_PARSE_ELEMENT("start parse : 'Boolean' "); + 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::Boolean::IGenerate(etk::UString& _data, int32_t _indent) const +{ + if (true==m_value) { + _data += "true"; + } else { + _data += "false"; + } + return true; +} + + +bool ejson::Boolean::TransfertIn(ejson::Value* _obj) +{ + if (NULL==_obj) { + JSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ejson::Boolean* other = _obj->ToBoolean(); + if (NULL==other) { + 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; +} + +ejson::Value* ejson::Boolean::Duplicate(void) const +{ + ejson::Boolean* output = new ejson::Boolean(m_value); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + return output; +} + + diff --git a/ejson/Boolean.h b/ejson/Boolean.h new file mode 100644 index 0000000..122aec7 --- /dev/null +++ b/ejson/Boolean.h @@ -0,0 +1,55 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __ETK_JSON_BOOLEAN_H__ +#define __ETK_JSON_BOOLEAN_H__ + +#include +#include +#include +#include + +namespace ejson +{ + class Boolean : public ejson::Value + { + public: + /** + * @brief basic element of a xml structure + */ + Boolean(bool _value=false) : m_value(_value) { }; + /** + * @brief destructor + */ + virtual ~Boolean(void) { }; + 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 SetValue(bool _value) { m_value = _value; }; + /** + * @brief Get the current element Value. + * @return the reference of the string value. + */ + bool GetValue(void) const { return m_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 typeString; }; + virtual ejson::Boolean* ToBoolean(void) { return this; }; + virtual const ejson::Boolean* ToBoolean(void) const{ return this; }; + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; + }; +}; + +#endif + diff --git a/ejson/Null.cpp b/ejson/Null.cpp new file mode 100644 index 0000000..3c40b87 --- /dev/null +++ b/ejson/Null.cpp @@ -0,0 +1,68 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + + +#include +#include +#include + +#undef __class__ +#define __class__ "Null" + +bool ejson::Null::IParse(const etk::UString& _data, int32_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; +} + + +bool ejson::Null::IGenerate(etk::UString& _data, int32_t _indent) const +{ + _data += "null"; + return true; +} + + +bool ejson::Null::TransfertIn(ejson::Value* _obj) +{ + if (NULL==_obj) { + JSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ejson::Null* other = _obj->ToNull(); + if (NULL==other) { + JSON_ERROR("Request transfer on an element that is not an Null"); + return false; + } + return true; +} + +ejson::Value* ejson::Null::Duplicate(void) const +{ + ejson::Null* output = new ejson::Null(); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + return output; +} + + diff --git a/ejson/Null.h b/ejson/Null.h new file mode 100644 index 0000000..75d295e --- /dev/null +++ b/ejson/Null.h @@ -0,0 +1,42 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __ETK_JSON_NULL_H__ +#define __ETK_JSON_NULL_H__ + +#include +#include +#include +#include + +namespace ejson +{ + class Null : public ejson::Value + { + public: + /** + * @brief basic element of a xml structure + */ + Null(void) { }; + /** + * @brief destructor + */ + virtual ~Null(void) { }; + 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; }; + virtual ejson::Null* ToNull(void) { return this; }; + virtual const ejson::Null* ToNull(void) const{ return this; }; + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; + }; +}; + +#endif + diff --git a/ejson/Number.cpp b/ejson/Number.cpp new file mode 100644 index 0000000..2bfe781 --- /dev/null +++ b/ejson/Number.cpp @@ -0,0 +1,74 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + + +#include +#include +#include + +#undef __class__ +#define __class__ "Number" + +bool ejson::Number::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc) +{ + JSON_PARSE_ELEMENT("start parse : 'Number' "); + etk::UString tmpVal; + for (int32_t iii=_pos+1; 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; + m_value = tmpVal.ToDouble(); + 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::Number::IGenerate(etk::UString& _data, int32_t _indent) const +{ + _data += m_value; + return true; +} + + +bool ejson::Number::TransfertIn(ejson::Value* _obj) +{ + if (NULL==_obj) { + JSON_ERROR("Request transfer on an NULL pointer"); + return false; + } + ejson::Number* other = _obj->ToNumber(); + if (NULL==other) { + 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::Value* ejson::Number::Duplicate(void) const +{ + ejson::Number* output = new ejson::Number(m_value); + if (NULL==output) { + JSON_ERROR("Allocation error ..."); + return NULL; + } + return output; +} + + diff --git a/ejson/Number.h b/ejson/Number.h new file mode 100644 index 0000000..eb3cafa --- /dev/null +++ b/ejson/Number.h @@ -0,0 +1,55 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __ETK_JSON_NUMBER_H__ +#define __ETK_JSON_NUMBER_H__ + +#include +#include +#include +#include + +namespace ejson +{ + class Number : public ejson::Value + { + public: + /** + * @brief basic element of a xml structure + */ + Number(double _value=0.0) : m_value(_value) { }; + /** + * @brief destructor + */ + virtual ~Number(void) { }; + 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 SetValue(double _value) { m_value = _value; }; + /** + * @brief Get the current element Value. + * @return the reference of the string value. + */ + double GetValue(void) const { return m_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 typeString; }; + virtual ejson::Number* ToNumber(void) { return this; }; + virtual const ejson::Number* ToNumber(void) const{ return this; }; + virtual bool TransfertIn(ejson::Value* _obj); + virtual ejson::Value* Duplicate(void) const; + }; +}; + +#endif + diff --git a/ejson/Object.cpp b/ejson/Object.cpp index e3281d0..124c2f1 100644 --- a/ejson/Object.cpp +++ b/ejson/Object.cpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #include #include @@ -72,14 +75,14 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file currentName += _data[iii]; } } - } else if (CheckAvaillable(_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==CheckAvaillable(_data[iii])) { + if (false==CheckString(_data[iii])) { mode = parseMiddle; iii--; break; @@ -117,7 +120,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file } else if (_data[iii]=='"') { // find a string: JSON_PARSE_ELEMENT("find String quoted"); - ejson::String * tmpElement = new ejson::String(true); + ejson::String * tmpElement = new ejson::String(); if (NULL==tmpElement) { EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); _pos=iii; @@ -138,19 +141,41 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file tmpElement->IParse(_data, iii, _filePos, _doc); AddSub(currentName, tmpElement); currentName = ""; - } else if( CheckAvaillable(_data[iii]) ) { - // find a string without "" ==> special hook for the etk-json parser - JSON_PARSE_ELEMENT("find String"); - ejson::String * tmpElement = new ejson::String(false); + } else if( _data[iii] == 'f' + || _data[iii] == 't' ) { + // find boolean: + JSON_PARSE_ELEMENT("find Boolean"); + ejson::Boolean * tmpElement = new ejson::Boolean(); if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + AddSub(currentName, tmpElement); + currentName = ""; + } else if( _data[iii] == 'n') { + // find null: + JSON_PARSE_ELEMENT("find Null"); + ejson::Null * tmpElement = new ejson::Null(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + AddSub(currentName, tmpElement); + currentName = ""; + } else if(true==CheckNumber(_data[iii])) { + // find number: + JSON_PARSE_ELEMENT("find Number"); + ejson::Number * tmpElement = new ejson::Number(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); _pos=iii; return false; } - iii--; tmpElement->IParse(_data, iii, _filePos, _doc); - iii--; - //JSON_ERROR(" add : " << currentName ); AddSub(currentName, tmpElement); currentName = ""; } else if(_data[iii]==',') { @@ -159,7 +184,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file currentName = ""; } else { // find an error .... - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Find '>' with no element in the element..."); + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, etk::UString("Find '") + _data[iii] + "' with no element in the element..."); // move the curent index _pos = iii+1; return false; diff --git a/ejson/String.cpp b/ejson/String.cpp index 1dbb990..dc2fce1 100644 --- a/ejson/String.cpp +++ b/ejson/String.cpp @@ -16,10 +16,6 @@ #undef __class__ #define __class__ "String" -void ejson::String::Clear(void) -{ - -} bool ejson::String::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc) @@ -31,42 +27,25 @@ bool ejson::String::IParse(const etk::UString& _data, int32_t& _pos, ejson::file DrawElementParsed(_data[iii], _filePos); #endif ejson::filePos tmpPos; - if(m_quoted==true) { - // TODO : manage \x - if( _data[iii]!= '\"') { - m_value += _data[iii]; - } else { - _pos = iii; - return true; - } + // TODO : manage \x + if( _data[iii]!= '\"') { + m_value += _data[iii]; } else { - if (CheckAvaillable(_data[iii]) ) { - m_value += _data[iii]; - } else { - _pos = iii; - return true; - } + _pos = iii; + return true; } } - if(m_quoted==true) { - _pos=_data.Size(); - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); - return false; - } _pos=_data.Size(); - return true; + EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "get end of string whithout fincding end of quote"); + return false; } bool ejson::String::IGenerate(etk::UString& _data, int32_t _indent) const { - //if (m_quoted==true) { - _data += "\"";; - //} + _data += "\"";; _data += m_value; - //if (m_quoted==true) { - _data += "\"";; - //} + _data += "\"";; return true; } @@ -82,22 +61,18 @@ bool ejson::String::TransfertIn(ejson::Value* _obj) 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); + ejson::String* output = new ejson::String(m_value); 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 49d21cb..936ef78 100644 --- a/ejson/String.h +++ b/ejson/String.h @@ -18,14 +18,11 @@ namespace ejson { class String : public ejson::Value { - private: - bool m_quoted; //!< this is for all element that is not generised (like null & numbers) public: /** * @brief basic element of a xml structure */ - String(bool _quoted=false) : m_quoted(_quoted) { }; - String(const etk::UString& _value) : m_quoted(false), m_value(_value) { }; + String(const etk::UString& _value="") : m_value(_value) { }; /** * @brief destructor */ @@ -49,7 +46,6 @@ namespace ejson virtual nodeType_te GetType(void) const { return typeString; }; virtual ejson::String* ToString(void) { return this; }; virtual const ejson::String* ToString(void) const{ return this; }; - 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 23db8ef..59c0cc2 100644 --- a/ejson/Value.cpp +++ b/ejson/Value.cpp @@ -65,7 +65,7 @@ int32_t ejson::Value::CountWhiteChar(const etk::UString& _data, int32_t _pos, ej } -bool ejson::Value::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) const +bool ejson::Value::CheckString(const etk::UniChar& _val) const { if( _val == '!' || _val == '"' @@ -105,47 +105,16 @@ bool ejson::Value::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) co return true; } - -bool ejson::Value::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc) +bool ejson::Value::CheckNumber(const etk::UniChar& _val) const { - JSON_PARSE_ELEMENT("start parse : 'Value' "); - for (int32_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]=='{') { - // find an object: - - } else if (_data[iii]=='"') { - // find a string: - - } else if (_data[iii]=='[') { - // find a list: - - } else if( CheckAvaillable(_data[iii]) ) { - // find a string without "" ==> special hook for the etk-json parser - - } else if( _data[iii]==']' - || _data[iii]=='}' - || _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 { - // find an error .... - EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "Find '>' with no element in the element..."); - // move the curent index - _pos += iii+1; - return false; - } + if( _val=='-' + || _val=='+' + || _val=='e' + || _val=='.' + || ( _val>='0' + && _val<='9' ) ) { + return true; } - return false; } + diff --git a/ejson/Value.h b/ejson/Value.h index 0b8032c..e13f0ed 100644 --- a/ejson/Value.h +++ b/ejson/Value.h @@ -29,6 +29,9 @@ namespace ejson class Document; class Array; class Object; + class Boolean; + class Null; + class Number; class String; typedef enum { @@ -36,7 +39,10 @@ namespace ejson typeValue, //!< XXXXXX:* typeDocument, //!< all the file main access typeArray, //!< [...] - typeString, //!< the "" or %d numbers null ... + typeString, //!< the "" + typeNumber, //!< the -1565.21515 + typeBoolean, //!< the true and false + typeNull, //!< the null element typeObject, //!< the { ... } } nodeType_te; @@ -117,7 +123,7 @@ namespace ejson * @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); + virtual bool IParse(const etk::UString& _data, int32_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 @@ -145,11 +151,15 @@ namespace ejson */ void DrawElementParsed(const etk::UniChar& _val, const ejson::filePos& _filePos) const; /** - * @brief check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \n\t\r and for first char : not -.0123456789). + * @brief check if an name (for object named) (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \n\t\r). * @param[in] _val Value to check the conformity. - * @param[in] _firstChar True if the element check is the first char. */ - bool CheckAvaillable(const etk::UniChar& _val, bool _firstChar=true) const; + bool CheckString(const etk::UniChar& _val) const; + /** + * @brief check if an number -+.0123456789e). + * @param[in] _val Value to check the conformity. + */ + bool CheckNumber(const etk::UniChar& _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. @@ -189,6 +199,24 @@ namespace ejson */ virtual ejson::String* ToString(void) { return NULL; }; virtual const ejson::String* ToString(void) const{ return NULL; }; + /** + * @brief Cast the element in a Number if it is possible. + * @return pointer on the class or NULL. + */ + virtual ejson::Number* ToNumber(void) { return NULL; }; + virtual const ejson::Number* ToNumber(void) const{ return NULL; }; + /** + * @brief Cast the element in a Boolean if it is possible. + * @return pointer on the class or NULL. + */ + virtual ejson::Boolean* ToBoolean(void) { return NULL; }; + virtual const ejson::Boolean* ToBoolean(void) const{ return NULL; }; + /** + * @brief Cast the element in a Null if it is possible. + * @return pointer on the class or NULL. + */ + virtual ejson::Null* ToNull(void) { return NULL; }; + virtual const ejson::Null* ToNull(void) const{ return NULL; }; /** * @brief Check if the node is a ejson::Document @@ -210,6 +238,21 @@ namespace ejson * @return true if the node is a ejson::String */ bool IsString(void) const { return GetType()==ejson::typeString; }; + /** + * @brief Check if the node is a ejson::Number + * @return true if the node is a ejson::Number + */ + bool IsNumber(void) const { return GetType()==ejson::typeNumber; }; + /** + * @brief Check if the node is a ejson::Boolean + * @return true if the node is a ejson::Boolean + */ + bool IsBoolean(void) const { return GetType()==ejson::typeBoolean; }; + /** + * @brief Check if the node is a ejson::Null + * @return true if the node is a ejson::Null + */ + bool IsNull(void) const { return GetType()==ejson::typeNull; }; /** * @brief Clear the Node diff --git a/ejson/ejson.cpp b/ejson/ejson.cpp index d66e6f3..867f43e 100644 --- a/ejson/ejson.cpp +++ b/ejson/ejson.cpp @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #undef __class__ #define __class__ "Document" @@ -219,12 +222,35 @@ bool ejson::Document::IParse(const etk::UString& _data, int32_t& _pos, ejson::fi } tmpElement->IParse(_data, iii, _filePos, _doc); m_subElement = tmpElement; - } else if( CheckAvaillable(_data[iii]) ) { - // find a string without "" ==> special hook for the etk-json parser - JSON_PARSE_ELEMENT("find String"); - ejson::String * tmpElement = new ejson::String(false); + } else if( _data[iii] == 'f' + || _data[iii] == 't' ) { + // find boolean: + JSON_PARSE_ELEMENT("find Boolean"); + ejson::Boolean * tmpElement = new ejson::Boolean(); if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + m_subElement = tmpElement; + } else if( _data[iii] == 'n') { + // find null: + JSON_PARSE_ELEMENT("find Null"); + ejson::Null * tmpElement = new ejson::Null(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); + _pos=iii; + return false; + } + tmpElement->IParse(_data, iii, _filePos, _doc); + m_subElement = tmpElement; + } else if(true==CheckNumber(_data[iii])) { + // find number: + JSON_PARSE_ELEMENT("find Number"); + ejson::Number * tmpElement = new ejson::Number(); + if (NULL==tmpElement) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); _pos=iii; return false; } diff --git a/ejson/test.cpp b/ejson/test.cpp index 32a36ef..25de61f 100644 --- a/ejson/test.cpp +++ b/ejson/test.cpp @@ -104,6 +104,7 @@ void Init(void) reference); l_list.PushBack(check); // ------------------------------------------------------ + /* check.Set(reference, -1, "{\n" @@ -133,6 +134,7 @@ void Init(void) " }\n" "}\n"); l_list.PushBack(check); + */ } int main(int argc, const char *argv[]) diff --git a/lutin_ejson.py b/lutin_ejson.py index ac63777..e442707 100644 --- a/lutin_ejson.py +++ b/lutin_ejson.py @@ -11,6 +11,9 @@ def Create(target): 'ejson/debug.cpp', 'ejson/ejson.cpp', 'ejson/Array.cpp', + 'ejson/Boolean.cpp', + 'ejson/Null.cpp', + 'ejson/Number.cpp', 'ejson/String.cpp', 'ejson/Object.cpp', 'ejson/Value.cpp'])