Important update:

- Buffer:
  - fix undefined value: zero terminate buffer when loading from FD
- DataTree:
  - fix memory leak: destroy temporary search path
  - improve delete(): delete all children for member if no path given
  - bug fix: initiate object with 0 length (not -1)
- JSONparse:
  - Remove level parameter
  - Add path to load/save/print methods (print only portion of tree)
  - fix memory leak: destroy temporary object name
This commit is contained in:
Charl Wentzel
2017-03-29 21:27:28 +02:00
parent 5691b22df9
commit 8f39adb0f3
4 changed files with 131 additions and 70 deletions

View File

@@ -807,6 +807,9 @@ int CShiftBuffer::ReadFromFD( int Handle, int MaxRead )
DataRemain -= BytesRead;
TotalRead += BytesRead;
BufLen += BytesRead;
// Zero terminate
Buffer[BufLen] = 0;
}
return TotalRead;
}

View File

@@ -239,6 +239,9 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
Member = *Child;
}
// Destroy temp path
free( WorkPath );
return Child;
}
//---------------------------------------------------------------------------
@@ -258,15 +261,25 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
TDataMember * Parent;
TDataMember ** Member;
// Check if exists
if (!(Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
// Validate
if (!BaseMember && (!Path || !*Path)) {
return false;
}
// Destroy
DestroyMember( Member );
Parent->Len--;
return true;
if (!Path || !*Path) {
// No path - destroy value
DestroyValue( BaseMember );
return true;
}
else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
// If valid path, destroy member
DestroyMember( Member );
Parent->Len--;
return true;
}
else {
return false;
}
}
//---------------------------------------------------------------------------
@@ -323,7 +336,7 @@ bool CDataTree::SetValue( TDataMember * Member, EDataType Type, const char * Va
}
else {
// Set null value
SetValuePtr( Member, Type, NULL, -1 );
SetValuePtr( Member, Type, NULL, 0 );
}
return true;
}

View File

@@ -28,7 +28,6 @@ CJSONparse::CJSONparse( CDataTree * pDataTree )
Buffer = NULL;
BufEnd = NULL;
Level = 0;
// Parsing operation
BufPos = NULL;
@@ -54,10 +53,100 @@ CJSONparse::~CJSONparse()
}
//---------------------------------------------------------------------------
bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen )
bool CJSONparse::PrintToScreen( const char * RootPath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!DataTree) {
return false;
}
// Set to StdOut
OutputHandle = 1;
// Get Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Print key name
if (RootObject->Name) {
write( OutputHandle, "\"", 1 );
write( OutputHandle, RootObject->Name, strlen(RootObject->Name) );
write( OutputHandle, "\" : ", 4 );
}
// Print to screen
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return true;
}
//---------------------------------------------------------------------------
bool CJSONparse::SaveToFile( const char * RootPath, const char * FilePath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!DataTree) {
return false;
}
// Clear Error
Error = false;
// Validate
if (!FilePath || !FilePath[0]) {
Error = true;
sprintf( ErrorText, "No File path specified" );
return false;
}
// Open file
if (!(OutputHandle = open( FilePath, O_CREAT|O_WRONLY|O_TRUNC ))) {
Error = true;
sprintf( ErrorText, "Could not open file" );
return false;
}
// Get Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Print to file
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return true;
}
//---------------------------------------------------------------------------
bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int pBufLen )
{
TDataMember * RootObject = NULL;
// Validate
if (!DataTree) {
return false;
}
// Clear Error
Error = false;
@@ -84,14 +173,19 @@ bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen )
return false;
}
// Get/Create Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath, true ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Reset values
LineNo = 1;
Error = false;
// Create Root object
DataTree->DeleteAll();
RootObject = DataTree->GetRootMember();
Level = 0;
DataTree->Delete( RootObject, NULL );
// Parse Root Object
SkipWhiteSpace();
@@ -256,7 +350,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
BufPos++;
// Set Type
Level++;
DataTree->SetValue( Object, jtObject );
while (true)
@@ -305,6 +398,9 @@ bool CJSONparse::ParseObject( TDataMember * Object )
return false;
}
// Free Name
free( MemberName );
// Check if more parameters to follow
SkipWhiteSpace();
if (*BufPos != ',') {
@@ -321,7 +417,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
return false;
}
BufPos++;
Level--;
// success
return true;
@@ -339,7 +434,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
BufPos++;
// Set Type
Level++;
DataTree->SetValue( Array, jtArray );
while (true)
@@ -386,7 +480,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
return false;
}
BufPos++;
Level--;
// success
return true;
@@ -474,49 +567,6 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
}
//---------------------------------------------------------------------------
bool CJSONparse::PrintToScreen( const int Indent )
{
TDataMember * RootObject;
// Set to StdOut
OutputHandle = 1;
// Save Root object
Level = 0;
RootObject = DataTree->GetRootMember();
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return false;
}
//---------------------------------------------------------------------------
bool CJSONparse::SaveToFile( const char * FilePath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!FilePath || !FilePath[0])
return false;
// Open file
if (!(OutputHandle = open( FilePath, O_WRONLY )))
return false;
// Save Root object
Level = 0;
RootObject = DataTree->GetRootMember();
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return false;
}
//---------------------------------------------------------------------------
bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
{
TDataMember * Member;
@@ -526,7 +576,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
// Opening brace
write( OutputHandle, "{", 1 );
Level++;
// Extend spacer
memset( &Spacer[SpacerLen], ' ', 2 );
@@ -595,7 +644,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
Spacer[SpacerLen] = 0;
// Closing brace
Level--;
if (Object->Len) {
write( OutputHandle, Spacer, SpacerLen );
}
@@ -613,7 +661,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
// Opening brace
write( OutputHandle, "[", 1 );
Level++;
// Extend spacer
memset( &Spacer[SpacerLen], ' ', 2 );
@@ -668,7 +715,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
Spacer[SpacerLen] = 0;
// Closing brace
Level--;
if (Array->Len) {
write( OutputHandle, Spacer, SpacerLen );
}

View File

@@ -36,7 +36,6 @@ private:
char * BufPos;
char * LineMark;
int LineNo;
int Level;
// Printing Operation
char Spacer[100];
@@ -74,10 +73,10 @@ public:
CJSONparse( CDataTree * pDataTree );
~CJSONparse();
bool PrintToScreen( const int Indent );
bool PrintToScreen( const char * Path, const int Indent );
bool LoadFromFile( const char * FilePath, int pBufLen = 500 );
bool SaveToFile( const char * FilePath, const int Indent = 2 );
bool LoadFromFile( const char * Path, const char * FilePath, int pBufLen = 500 );
bool SaveToFile( const char * Path, const char * FilePath, const int Indent = 2 );
const char * GetError() { return ((Error)? ErrorText : "Success"); };
};