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;
|
DataRemain -= BytesRead;
|
||||||
TotalRead += BytesRead;
|
TotalRead += BytesRead;
|
||||||
BufLen += BytesRead;
|
BufLen += BytesRead;
|
||||||
|
|
||||||
|
// Zero terminate
|
||||||
|
Buffer[BufLen] = 0;
|
||||||
}
|
}
|
||||||
return TotalRead;
|
return TotalRead;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
|||||||
Member = *Child;
|
Member = *Child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destroy temp path
|
||||||
|
free( WorkPath );
|
||||||
|
|
||||||
return Child;
|
return Child;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -258,15 +261,25 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
|
|||||||
TDataMember * Parent;
|
TDataMember * Parent;
|
||||||
TDataMember ** Member;
|
TDataMember ** Member;
|
||||||
|
|
||||||
// Check if exists
|
// Validate
|
||||||
if (!(Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
|
if (!BaseMember && (!Path || !*Path)) {
|
||||||
return false;
|
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 );
|
DestroyMember( Member );
|
||||||
Parent->Len--;
|
Parent->Len--;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -323,7 +336,7 @@ bool CDataTree::SetValue( TDataMember * Member, EDataType Type, const char * Va
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Set null value
|
// Set null value
|
||||||
SetValuePtr( Member, Type, NULL, -1 );
|
SetValuePtr( Member, Type, NULL, 0 );
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ CJSONparse::CJSONparse( CDataTree * pDataTree )
|
|||||||
|
|
||||||
Buffer = NULL;
|
Buffer = NULL;
|
||||||
BufEnd = NULL;
|
BufEnd = NULL;
|
||||||
Level = 0;
|
|
||||||
|
|
||||||
// Parsing operation
|
// Parsing operation
|
||||||
BufPos = NULL;
|
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;
|
TDataMember * RootObject = NULL;
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
if (!DataTree) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear Error
|
// Clear Error
|
||||||
Error = false;
|
Error = false;
|
||||||
|
|
||||||
@@ -84,14 +173,19 @@ bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen )
|
|||||||
return false;
|
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
|
// Reset values
|
||||||
LineNo = 1;
|
LineNo = 1;
|
||||||
Error = false;
|
DataTree->Delete( RootObject, NULL );
|
||||||
|
|
||||||
// Create Root object
|
|
||||||
DataTree->DeleteAll();
|
|
||||||
RootObject = DataTree->GetRootMember();
|
|
||||||
Level = 0;
|
|
||||||
|
|
||||||
// Parse Root Object
|
// Parse Root Object
|
||||||
SkipWhiteSpace();
|
SkipWhiteSpace();
|
||||||
@@ -256,7 +350,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
|||||||
BufPos++;
|
BufPos++;
|
||||||
|
|
||||||
// Set Type
|
// Set Type
|
||||||
Level++;
|
|
||||||
DataTree->SetValue( Object, jtObject );
|
DataTree->SetValue( Object, jtObject );
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -305,6 +398,9 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free Name
|
||||||
|
free( MemberName );
|
||||||
|
|
||||||
// Check if more parameters to follow
|
// Check if more parameters to follow
|
||||||
SkipWhiteSpace();
|
SkipWhiteSpace();
|
||||||
if (*BufPos != ',') {
|
if (*BufPos != ',') {
|
||||||
@@ -321,7 +417,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BufPos++;
|
BufPos++;
|
||||||
Level--;
|
|
||||||
|
|
||||||
// success
|
// success
|
||||||
return true;
|
return true;
|
||||||
@@ -339,7 +434,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
|||||||
BufPos++;
|
BufPos++;
|
||||||
|
|
||||||
// Set Type
|
// Set Type
|
||||||
Level++;
|
|
||||||
DataTree->SetValue( Array, jtArray );
|
DataTree->SetValue( Array, jtArray );
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -386,7 +480,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BufPos++;
|
BufPos++;
|
||||||
Level--;
|
|
||||||
|
|
||||||
// success
|
// success
|
||||||
return true;
|
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 )
|
bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
||||||
{
|
{
|
||||||
TDataMember * Member;
|
TDataMember * Member;
|
||||||
@@ -526,7 +576,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
|||||||
|
|
||||||
// Opening brace
|
// Opening brace
|
||||||
write( OutputHandle, "{", 1 );
|
write( OutputHandle, "{", 1 );
|
||||||
Level++;
|
|
||||||
|
|
||||||
// Extend spacer
|
// Extend spacer
|
||||||
memset( &Spacer[SpacerLen], ' ', 2 );
|
memset( &Spacer[SpacerLen], ' ', 2 );
|
||||||
@@ -595,7 +644,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
|||||||
Spacer[SpacerLen] = 0;
|
Spacer[SpacerLen] = 0;
|
||||||
|
|
||||||
// Closing brace
|
// Closing brace
|
||||||
Level--;
|
|
||||||
if (Object->Len) {
|
if (Object->Len) {
|
||||||
write( OutputHandle, Spacer, SpacerLen );
|
write( OutputHandle, Spacer, SpacerLen );
|
||||||
}
|
}
|
||||||
@@ -613,7 +661,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
|
|||||||
|
|
||||||
// Opening brace
|
// Opening brace
|
||||||
write( OutputHandle, "[", 1 );
|
write( OutputHandle, "[", 1 );
|
||||||
Level++;
|
|
||||||
|
|
||||||
// Extend spacer
|
// Extend spacer
|
||||||
memset( &Spacer[SpacerLen], ' ', 2 );
|
memset( &Spacer[SpacerLen], ' ', 2 );
|
||||||
@@ -668,7 +715,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
|
|||||||
Spacer[SpacerLen] = 0;
|
Spacer[SpacerLen] = 0;
|
||||||
|
|
||||||
// Closing brace
|
// Closing brace
|
||||||
Level--;
|
|
||||||
if (Array->Len) {
|
if (Array->Len) {
|
||||||
write( OutputHandle, Spacer, SpacerLen );
|
write( OutputHandle, Spacer, SpacerLen );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ private:
|
|||||||
char * BufPos;
|
char * BufPos;
|
||||||
char * LineMark;
|
char * LineMark;
|
||||||
int LineNo;
|
int LineNo;
|
||||||
int Level;
|
|
||||||
|
|
||||||
// Printing Operation
|
// Printing Operation
|
||||||
char Spacer[100];
|
char Spacer[100];
|
||||||
@@ -74,10 +73,10 @@ public:
|
|||||||
CJSONparse( CDataTree * pDataTree );
|
CJSONparse( CDataTree * pDataTree );
|
||||||
~CJSONparse();
|
~CJSONparse();
|
||||||
|
|
||||||
bool PrintToScreen( const int Indent );
|
bool PrintToScreen( const char * Path, const int Indent );
|
||||||
|
|
||||||
bool LoadFromFile( const char * FilePath, int pBufLen = 500 );
|
bool LoadFromFile( const char * Path, const char * FilePath, int pBufLen = 500 );
|
||||||
bool SaveToFile( const char * FilePath, const int Indent = 2 );
|
bool SaveToFile( const char * Path, const char * FilePath, const int Indent = 2 );
|
||||||
|
|
||||||
const char * GetError() { return ((Error)? ErrorText : "Success"); };
|
const char * GetError() { return ((Error)? ErrorText : "Success"); };
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user