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:
@@ -807,6 +807,9 @@ int CShiftBuffer::ReadFromFD( int Handle, int MaxRead )
|
||||
DataRemain -= BytesRead;
|
||||
TotalRead += BytesRead;
|
||||
BufLen += BytesRead;
|
||||
|
||||
// Zero terminate
|
||||
Buffer[BufLen] = 0;
|
||||
}
|
||||
return TotalRead;
|
||||
}
|
||||
|
||||
@@ -239,6 +239,9 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
||||
Member = *Child;
|
||||
}
|
||||
|
||||
// Destroy temp path
|
||||
free( WorkPath );
|
||||
|
||||
return Child;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -258,16 +261,26 @@ 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
|
||||
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;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CDataTree::DeleteAll()
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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"); };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user