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:
Charl Wentzel
2017-04-03 21:48:29 +02:00
parent 2e2ba113f1
commit 66fc4bc123
3 changed files with 97 additions and 14 deletions

View File

@@ -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 {

View File

@@ -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 :

View File

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