[DEV] rework json to have a full complient json parser

This commit is contained in:
Edouard DUPIN 2013-08-22 21:38:20 +02:00
parent 7ee1c7b524
commit b68b4f7b82
15 changed files with 551 additions and 110 deletions

View File

@ -10,6 +10,9 @@
#include <ejson/Object.h> #include <ejson/Object.h>
#include <ejson/Array.h> #include <ejson/Array.h>
#include <ejson/String.h> #include <ejson/String.h>
#include <ejson/Null.h>
#include <ejson/Number.h>
#include <ejson/Boolean.h>
#include <ejson/debug.h> #include <ejson/debug.h>
#include <ejson/ejson.h> #include <ejson/ejson.h>
@ -61,7 +64,7 @@ bool ejson::Array::IParse(const etk::UString& _data, int32_t& _pos, ejson::fileP
} else if (_data[iii]=='"') { } else if (_data[iii]=='"') {
// find a string: // find a string:
JSON_PARSE_ELEMENT("find String quoted"); JSON_PARSE_ELEMENT("find String quoted");
ejson::String * tmpElement = new ejson::String(true); ejson::String * tmpElement = new ejson::String();
if (NULL==tmpElement) { if (NULL==tmpElement) {
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String");
_pos=iii; _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); tmpElement->IParse(_data, iii, _filePos, _doc);
m_value.PushBack(tmpElement); m_value.PushBack(tmpElement);
} else if( CheckAvaillable(_data[iii]) ) { } else if( _data[iii] == 'f'
// find a string without "" ==> special hook for the etk-json parser || _data[iii] == 't' ) {
JSON_PARSE_ELEMENT("find String"); // find boolean:
ejson::String * tmpElement = new ejson::String(false); JSON_PARSE_ELEMENT("find Boolean");
ejson::Boolean * tmpElement = new ejson::Boolean();
if (NULL==tmpElement) { 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; _pos=iii;
return false; return false;
} }
tmpElement->IParse(_data, iii, _filePos, _doc); tmpElement->IParse(_data, iii, _filePos, _doc);
JSON_PARSE_ELEMENT("find String (end)");
m_value.PushBack(tmpElement); m_value.PushBack(tmpElement);
} else if(_data[iii]==',') { } else if(_data[iii]==',') {
// find Separator : Restart cycle ... // find Separator : Restart cycle ...

83
ejson/Boolean.cpp Normal file
View File

@ -0,0 +1,83 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ejson/Boolean.h>
#include <ejson/debug.h>
#include <ejson/ejson.h>
#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;
}

55
ejson/Boolean.h Normal file
View File

@ -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 <etk/types.h>
#include <etk/UString.h>
#include <etk/math/Vector2D.h>
#include <ejson/Value.h>
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

68
ejson/Null.cpp Normal file
View File

@ -0,0 +1,68 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ejson/Null.h>
#include <ejson/debug.h>
#include <ejson/ejson.h>
#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;
}

42
ejson/Null.h Normal file
View File

@ -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 <etk/types.h>
#include <etk/UString.h>
#include <etk/math/Vector2D.h>
#include <ejson/Value.h>
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

74
ejson/Number.cpp Normal file
View File

@ -0,0 +1,74 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ejson/Number.h>
#include <ejson/debug.h>
#include <ejson/ejson.h>
#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;
}

55
ejson/Number.h Normal file
View File

@ -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 <etk/types.h>
#include <etk/UString.h>
#include <etk/math/Vector2D.h>
#include <ejson/Value.h>
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

View File

@ -10,6 +10,9 @@
#include <ejson/Object.h> #include <ejson/Object.h>
#include <ejson/Array.h> #include <ejson/Array.h>
#include <ejson/String.h> #include <ejson/String.h>
#include <ejson/Null.h>
#include <ejson/Number.h>
#include <ejson/Boolean.h>
#include <ejson/debug.h> #include <ejson/debug.h>
#include <ejson/ejson.h> #include <ejson/ejson.h>
@ -72,14 +75,14 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file
currentName += _data[iii]; currentName += _data[iii];
} }
} }
} else if (CheckAvaillable(_data[iii]) ) { } else if (CheckString(_data[iii]) ) {
currentName += _data[iii]; currentName += _data[iii];
for (iii++; iii<_data.Size(); iii++) { for (iii++; iii<_data.Size(); iii++) {
_filePos.Check(_data[iii]); _filePos.Check(_data[iii]);
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT #ifdef ENABLE_DISPLAY_PARSED_ELEMENT
DrawElementParsed(_data[iii], _filePos); DrawElementParsed(_data[iii], _filePos);
#endif #endif
if (false==CheckAvaillable(_data[iii])) { if (false==CheckString(_data[iii])) {
mode = parseMiddle; mode = parseMiddle;
iii--; iii--;
break; break;
@ -117,7 +120,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file
} else if (_data[iii]=='"') { } else if (_data[iii]=='"') {
// find a string: // find a string:
JSON_PARSE_ELEMENT("find String quoted"); JSON_PARSE_ELEMENT("find String quoted");
ejson::String * tmpElement = new ejson::String(true); ejson::String * tmpElement = new ejson::String();
if (NULL==tmpElement) { if (NULL==tmpElement) {
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String");
_pos=iii; _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); tmpElement->IParse(_data, iii, _filePos, _doc);
AddSub(currentName, tmpElement); AddSub(currentName, tmpElement);
currentName = ""; currentName = "";
} else if( CheckAvaillable(_data[iii]) ) { } else if( _data[iii] == 'f'
// find a string without "" ==> special hook for the etk-json parser || _data[iii] == 't' ) {
JSON_PARSE_ELEMENT("find String"); // find boolean:
ejson::String * tmpElement = new ejson::String(false); JSON_PARSE_ELEMENT("find Boolean");
ejson::Boolean * tmpElement = new ejson::Boolean();
if (NULL==tmpElement) { 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; _pos=iii;
return false; return false;
} }
iii--;
tmpElement->IParse(_data, iii, _filePos, _doc); tmpElement->IParse(_data, iii, _filePos, _doc);
iii--;
//JSON_ERROR(" add : " << currentName );
AddSub(currentName, tmpElement); AddSub(currentName, tmpElement);
currentName = ""; currentName = "";
} else if(_data[iii]==',') { } else if(_data[iii]==',') {
@ -159,7 +184,7 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file
currentName = ""; currentName = "";
} else { } else {
// find an error .... // 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 // move the curent index
_pos = iii+1; _pos = iii+1;
return false; return false;

View File

@ -16,10 +16,6 @@
#undef __class__ #undef __class__
#define __class__ "String" #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) 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); DrawElementParsed(_data[iii], _filePos);
#endif #endif
ejson::filePos tmpPos; ejson::filePos tmpPos;
if(m_quoted==true) { // TODO : manage \x
// TODO : manage \x if( _data[iii]!= '\"') {
if( _data[iii]!= '\"') { m_value += _data[iii];
m_value += _data[iii];
} else {
_pos = iii;
return true;
}
} else { } else {
if (CheckAvaillable(_data[iii]) ) { _pos = iii;
m_value += _data[iii]; return true;
} else {
_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(); _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 bool ejson::String::IGenerate(etk::UString& _data, int32_t _indent) const
{ {
//if (m_quoted==true) { _data += "\"";;
_data += "\"";;
//}
_data += m_value; _data += m_value;
//if (m_quoted==true) { _data += "\"";;
_data += "\"";;
//}
return true; 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"); JSON_ERROR("Request transfer on an element that is not an String");
return false; return false;
} }
// remove destination elements
other->m_quoted = m_quoted;
other->m_value = m_value; other->m_value = m_value;
m_quoted = true;
m_value = ""; m_value = "";
return true; return true;
} }
ejson::Value* ejson::String::Duplicate(void) const 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) { if (NULL==output) {
JSON_ERROR("Allocation error ..."); JSON_ERROR("Allocation error ...");
return NULL; return NULL;
} }
output->SetValue(m_value);
return output; return output;
} }

View File

@ -18,14 +18,11 @@ namespace ejson
{ {
class String : public ejson::Value class String : public ejson::Value
{ {
private:
bool m_quoted; //!< this is for all element that is not generised (like null & numbers)
public: public:
/** /**
* @brief basic element of a xml structure * @brief basic element of a xml structure
*/ */
String(bool _quoted=false) : m_quoted(_quoted) { }; String(const etk::UString& _value="") : m_value(_value) { };
String(const etk::UString& _value) : m_quoted(false), m_value(_value) { };
/** /**
* @brief destructor * @brief destructor
*/ */
@ -49,7 +46,6 @@ namespace ejson
virtual nodeType_te GetType(void) const { return typeString; }; virtual nodeType_te GetType(void) const { return typeString; };
virtual ejson::String* ToString(void) { return this; }; virtual ejson::String* ToString(void) { return this; };
virtual const ejson::String* ToString(void) const{ return this; }; virtual const ejson::String* ToString(void) const{ return this; };
virtual void Clear(void);
virtual bool TransfertIn(ejson::Value* _obj); virtual bool TransfertIn(ejson::Value* _obj);
virtual ejson::Value* Duplicate(void) const; virtual ejson::Value* Duplicate(void) const;
}; };

View File

@ -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 == '!' if( _val == '!'
|| _val == '"' || _val == '"'
@ -105,47 +105,16 @@ bool ejson::Value::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) co
return true; return true;
} }
bool ejson::Value::CheckNumber(const etk::UniChar& _val) const
bool ejson::Value::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc)
{ {
JSON_PARSE_ELEMENT("start parse : 'Value' "); if( _val=='-'
for (int32_t iii=_pos+1; iii<_data.Size(); iii++) { || _val=='+'
_filePos.Check(_data[iii]); || _val=='e'
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT || _val=='.'
DrawElementParsed(_data[iii], _filePos); || ( _val>='0'
#endif && _val<='9' ) ) {
ejson::filePos tmpPos; return true;
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;
}
} }
return false; return false;
} }

View File

@ -29,6 +29,9 @@ namespace ejson
class Document; class Document;
class Array; class Array;
class Object; class Object;
class Boolean;
class Null;
class Number;
class String; class String;
typedef enum { typedef enum {
@ -36,7 +39,10 @@ namespace ejson
typeValue, //!< XXXXXX:* typeValue, //!< XXXXXX:*
typeDocument, //!< all the file main access typeDocument, //!< all the file main access
typeArray, //!< [...] typeArray, //!< [...]
typeString, //!< the "" or %d numbers null ... typeString, //!< the ""
typeNumber, //!< the -1565.21515
typeBoolean, //!< the true and false
typeNull, //!< the null element
typeObject, //!< the { ... } typeObject, //!< the { ... }
} nodeType_te; } nodeType_te;
@ -117,7 +123,7 @@ namespace ejson
* @param[in,out] file parsing position (line x col x) * @param[in,out] file parsing position (line x col x)
* @return false if an error occured. * @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 * @brief Generate a string with the tree of the xml
* @param[in,out] _data string where to add the elements * @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; 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] _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) * @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] _data Data to parse.
@ -189,6 +199,24 @@ namespace ejson
*/ */
virtual ejson::String* ToString(void) { return NULL; }; virtual ejson::String* ToString(void) { return NULL; };
virtual const ejson::String* ToString(void) const{ 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 * @brief Check if the node is a ejson::Document
@ -210,6 +238,21 @@ namespace ejson
* @return true if the node is a ejson::String * @return true if the node is a ejson::String
*/ */
bool IsString(void) const { return GetType()==ejson::typeString; }; 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 * @brief Clear the Node

View File

@ -13,6 +13,9 @@
#include <ejson/Object.h> #include <ejson/Object.h>
#include <ejson/Array.h> #include <ejson/Array.h>
#include <ejson/String.h> #include <ejson/String.h>
#include <ejson/Null.h>
#include <ejson/Number.h>
#include <ejson/Boolean.h>
#undef __class__ #undef __class__
#define __class__ "Document" #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); tmpElement->IParse(_data, iii, _filePos, _doc);
m_subElement = tmpElement; m_subElement = tmpElement;
} else if( CheckAvaillable(_data[iii]) ) { } else if( _data[iii] == 'f'
// find a string without "" ==> special hook for the etk-json parser || _data[iii] == 't' ) {
JSON_PARSE_ELEMENT("find String"); // find boolean:
ejson::String * tmpElement = new ejson::String(false); JSON_PARSE_ELEMENT("find Boolean");
ejson::Boolean * tmpElement = new ejson::Boolean();
if (NULL==tmpElement) { 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; _pos=iii;
return false; return false;
} }

View File

@ -104,6 +104,7 @@ void Init(void)
reference); reference);
l_list.PushBack(check); l_list.PushBack(check);
// ------------------------------------------------------ // ------------------------------------------------------
/*
check.Set(reference, check.Set(reference,
-1, -1,
"{\n" "{\n"
@ -133,6 +134,7 @@ void Init(void)
" }\n" " }\n"
"}\n"); "}\n");
l_list.PushBack(check); l_list.PushBack(check);
*/
} }
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])

View File

@ -11,6 +11,9 @@ def Create(target):
'ejson/debug.cpp', 'ejson/debug.cpp',
'ejson/ejson.cpp', 'ejson/ejson.cpp',
'ejson/Array.cpp', 'ejson/Array.cpp',
'ejson/Boolean.cpp',
'ejson/Null.cpp',
'ejson/Number.cpp',
'ejson/String.cpp', 'ejson/String.cpp',
'ejson/Object.cpp', 'ejson/Object.cpp',
'ejson/Value.cpp']) 'ejson/Value.cpp'])