Important Update:
- Bug fix: incorrect memory allocation in SetValue() - Implement conversion of escaped chars during parsing - Implement escaping chars during printing
This commit is contained in:
@@ -325,7 +325,7 @@ bool CDataTree::SetValue( TDataMember * Member, EDataType Type, const char * Va
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create copy of value
|
// Create copy of value
|
||||||
NewValue = (char *)malloc( sizeof(Len+1) );
|
NewValue = (char *)malloc( Len+1 );
|
||||||
if (Value) {
|
if (Value) {
|
||||||
memcpy( NewValue, Value, Len );
|
memcpy( NewValue, Value, Len );
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -360,6 +360,8 @@ void CJSONparse::SkipWhiteSpace()
|
|||||||
bool CJSONparse::ParseString( char ** Value, int &Len )
|
bool CJSONparse::ParseString( char ** Value, int &Len )
|
||||||
{
|
{
|
||||||
char * EndMark;
|
char * EndMark;
|
||||||
|
char * ValuePos = NULL;
|
||||||
|
char HexVal[5] = "";
|
||||||
|
|
||||||
// Check for opening quote
|
// Check for opening quote
|
||||||
if (*BufPos != '"') {
|
if (*BufPos != '"') {
|
||||||
@@ -402,7 +404,7 @@ bool CJSONparse::ParseString( char ** Value, int &Len )
|
|||||||
}
|
}
|
||||||
if (*(BufPos+1) == 'u') {
|
if (*(BufPos+1) == 'u') {
|
||||||
for (EndMark = BufPos+2; EndMark < BufPos+6; EndMark++) {
|
for (EndMark = BufPos+2; EndMark < BufPos+6; EndMark++) {
|
||||||
if (!*BufPos && RefillBuffer) {
|
if (!*EndMark && RefillBuffer) {
|
||||||
FillBuffer();
|
FillBuffer();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -414,9 +416,11 @@ bool CJSONparse::ParseString( char ** Value, int &Len )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BufPos += 6;
|
BufPos += 6;
|
||||||
|
Len -= 5;
|
||||||
}
|
}
|
||||||
else if (strchr( "bfnrt/\\\"", *(BufPos+1) )) {
|
else if (strchr( "bfnrt/\\\"", *(BufPos+1) )) {
|
||||||
BufPos += 2;
|
BufPos += 2;
|
||||||
|
Len -= 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Error = true;
|
Error = true;
|
||||||
@@ -433,13 +437,48 @@ bool CJSONparse::ParseString( char ** Value, int &Len )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get size of name
|
|
||||||
Len = BufPos-Mark-2;
|
|
||||||
|
|
||||||
// Create Return value pointer
|
// Create Return value pointer
|
||||||
|
Len += BufPos-Mark-2;
|
||||||
*Value = (char*)malloc( Len+1 );
|
*Value = (char*)malloc( Len+1 );
|
||||||
memcpy( *Value, Mark+1, Len );
|
ValuePos = *Value;
|
||||||
(*Value)[Len] = 0;
|
|
||||||
|
// Convert value
|
||||||
|
BufPos = Mark+1;
|
||||||
|
while ((EndMark = strpbrk( BufPos, "\"\\" )))
|
||||||
|
{
|
||||||
|
// Copy portion
|
||||||
|
memcpy( ValuePos, BufPos, (EndMark-BufPos) );
|
||||||
|
ValuePos += (EndMark-BufPos);
|
||||||
|
BufPos = EndMark;
|
||||||
|
|
||||||
|
if (*BufPos == '"') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (*BufPos== '\\') {
|
||||||
|
if (*(BufPos+1) == 'u') {
|
||||||
|
strncpy( HexVal, BufPos+2, 4 );
|
||||||
|
*ValuePos = (char)strtol( HexVal, NULL, 16 );
|
||||||
|
ValuePos++;
|
||||||
|
BufPos += 6;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (*(BufPos+1)) {
|
||||||
|
case 'b': *ValuePos = '\b'; break;
|
||||||
|
case 'f': *ValuePos = '\f'; break;
|
||||||
|
case 'n': *ValuePos = '\n'; break;
|
||||||
|
case 'r': *ValuePos = '\r'; break;
|
||||||
|
case 't': *ValuePos = '\t'; break;
|
||||||
|
case '/': *ValuePos = '/'; break;
|
||||||
|
case '\\': *ValuePos = '\\'; break;
|
||||||
|
case '"': *ValuePos = '"'; break;
|
||||||
|
}
|
||||||
|
ValuePos++;
|
||||||
|
BufPos +=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ValuePos = 0;
|
||||||
|
BufPos++;
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
return true;
|
return true;
|
||||||
@@ -678,6 +717,52 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CJSONparse::PrintString( char * String, int Len )
|
||||||
|
{
|
||||||
|
// Start quote
|
||||||
|
write( OutputHandle, "\"", 1 );
|
||||||
|
|
||||||
|
// Content
|
||||||
|
BufPos = String;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Scan for special chars
|
||||||
|
Mark = BufPos;
|
||||||
|
while ((*BufPos >= 32) && (*BufPos <= 126) && (*BufPos != '\\') && (*BufPos != '/') && (*BufPos != '"'))
|
||||||
|
BufPos++;
|
||||||
|
|
||||||
|
// Print Portion
|
||||||
|
write( OutputHandle, Mark, (BufPos-Mark) );
|
||||||
|
|
||||||
|
// Handle special chars
|
||||||
|
if (!*BufPos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (*BufPos) {
|
||||||
|
case '\b': write( OutputHandle, "\\b", 2 ); break;
|
||||||
|
case '\f': write( OutputHandle, "\\f", 2 ); break;
|
||||||
|
case '\n': write( OutputHandle, "\\n", 2 ); break;
|
||||||
|
case '\r': write( OutputHandle, "\\r", 2 ); break;
|
||||||
|
case '\t': write( OutputHandle, "\\t", 2 ); break;
|
||||||
|
case '/': write( OutputHandle, "\\/", 2 ); break;
|
||||||
|
case '\\': write( OutputHandle, "\\\\", 2 ); break;
|
||||||
|
case '"': write( OutputHandle, "\\\"", 2 ); break;
|
||||||
|
default:
|
||||||
|
dprintf( OutputHandle, "\\u%04d", *BufPos );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
BufPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Quote
|
||||||
|
write( OutputHandle, "\"", 1 );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
||||||
{
|
{
|
||||||
TDataMember * Member;
|
TDataMember * Member;
|
||||||
@@ -716,12 +801,11 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print key name
|
// Print key name
|
||||||
write( OutputHandle, "\"", 1 );
|
PrintString( Member->Name, strlen(Member->Name) );
|
||||||
write( OutputHandle, Member->Name, strlen(Member->Name) );
|
|
||||||
if (Indent) {
|
if (Indent) {
|
||||||
write( OutputHandle,"\" : ", 4 );
|
write( OutputHandle," : ", 3 );
|
||||||
} else {
|
} else {
|
||||||
write( OutputHandle, "\":", 2 );
|
write( OutputHandle, ":", 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print value
|
// Print value
|
||||||
@@ -739,9 +823,7 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case jtString :
|
case jtString :
|
||||||
write( OutputHandle, "\"", 1 );
|
PrintString( Member->Value, Member->Len );
|
||||||
write( OutputHandle, Member->Value, Member->Len );
|
|
||||||
write( OutputHandle, "\"", 1 );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case jtArray :
|
case jtArray :
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ private:
|
|||||||
bool ParseString( TDataMember * Member );
|
bool ParseString( TDataMember * Member );
|
||||||
bool ParsePrimitive( TDataMember * Member );
|
bool ParsePrimitive( TDataMember * Member );
|
||||||
|
|
||||||
|
bool PrintString( char * String, int Len );
|
||||||
bool PrintObject( TDataMember * Object, const int Indent );
|
bool PrintObject( TDataMember * Object, const int Indent );
|
||||||
bool PrintArray( TDataMember * Object, const int Indent );
|
bool PrintArray( TDataMember * Object, const int Indent );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user