Important Update:
- DataTreeCore:
- Add Parent & Prev Child links to DataMembers
- Update CreateMember() to set Parent/Sibling reference
& increase Parent->Len
- Remove AddMember()
- Update DestroyMember() to decrease Parent->Len
- JSONparseCore:
- Update ParseArray() for above changes made to DataTreeCore
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
CDataTree::CDataTree()
|
||||
{
|
||||
// Create Root member of tree
|
||||
RootMember = CreateMember( NULL );
|
||||
RootMember = CreateMember( NULL, NULL, NULL );
|
||||
RootMember->Type = jtObject;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -30,7 +30,7 @@ CDataTree::~CDataTree()
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
TDataMember * CDataTree::CreateMember( const char * Name, const int Len )
|
||||
TDataMember * CDataTree::CreateMember( TDataMember * Parent, TDataMember * PrevChild, const char * Name, const int Len )
|
||||
{
|
||||
TDataMember * Member;
|
||||
|
||||
@@ -45,43 +45,38 @@ TDataMember * CDataTree::CreateMember( const char * Name, const int Len )
|
||||
memcpy( Member->Name, Name, Member->NameLen );
|
||||
Member->Name[ Member->NameLen ] = 0;
|
||||
}
|
||||
|
||||
// Update Parent
|
||||
if (Parent) {
|
||||
Member->Parent = Parent;
|
||||
Parent->Len++;
|
||||
}
|
||||
|
||||
// Set Sibling links
|
||||
Member->Prev = PrevChild;
|
||||
Member->Next = NULL;
|
||||
|
||||
return Member;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CDataTree::AddMember( TDataMember * Parent, TDataMember * Member )
|
||||
{
|
||||
TDataMember ** Child;
|
||||
|
||||
// Validate
|
||||
if (!Parent || !Member) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get end of list
|
||||
Child = &(Parent->FirstChild);
|
||||
while (*Child) {
|
||||
Child = &((*Child)->Next);
|
||||
}
|
||||
|
||||
// Add member
|
||||
*Child = Member;
|
||||
Parent->Len++;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CDataTree::DestroyMember( TDataMember ** Member )
|
||||
{
|
||||
TDataMember * NextMember;
|
||||
|
||||
// Valdate
|
||||
// Validate
|
||||
if (!Member || !*Member)
|
||||
return false;
|
||||
|
||||
// Get next param in list
|
||||
NextMember = (*Member)->Next;
|
||||
|
||||
// Update Parent
|
||||
if ((*Member)->Parent)
|
||||
(*Member)->Parent->Len--;
|
||||
|
||||
// Destroy
|
||||
if ((*Member)->Name)
|
||||
free( (*Member)->Name );
|
||||
@@ -102,7 +97,7 @@ bool CDataTree::DestroyMember( TDataMember ** Member )
|
||||
|
||||
bool CDataTree::DestroyValue( TDataMember * Member )
|
||||
{
|
||||
// Valdate
|
||||
// Validate
|
||||
if (!Member)
|
||||
return false;
|
||||
|
||||
@@ -111,10 +106,12 @@ bool CDataTree::DestroyValue( TDataMember * Member )
|
||||
free( Member->Value );
|
||||
Member->Value = NULL;
|
||||
}
|
||||
|
||||
// Destroy Children
|
||||
while (Member->FirstChild) {
|
||||
DestroyMember( &(Member->FirstChild) );
|
||||
}
|
||||
Member->Len = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -122,7 +119,8 @@ bool CDataTree::DestroyValue( TDataMember * Member )
|
||||
TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Path, bool Create, TDataMember ** Parent )
|
||||
{
|
||||
TDataMember * Member;
|
||||
TDataMember ** Child = NULL;
|
||||
TDataMember ** Child;
|
||||
TDataMember * PrevChild;
|
||||
char * Pos;
|
||||
char * EndPos;
|
||||
char * Key;
|
||||
@@ -182,10 +180,13 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
||||
Index = -1;
|
||||
|
||||
// find end of list
|
||||
PrevChild = NULL;
|
||||
Child = &(Member->FirstChild);
|
||||
while (*Child)
|
||||
while (*Child) {
|
||||
PrevChild = *Child;
|
||||
Child = &((*Child)->Next);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Get requested index
|
||||
Index = (int)strtoul( Key, &EndPos, 10 );
|
||||
@@ -193,9 +194,11 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
||||
break;
|
||||
|
||||
// Find element at requested index
|
||||
PrevChild = NULL;
|
||||
Child = &(Member->FirstChild);
|
||||
Count = 0;
|
||||
while (*Child && (Count < Index)) {
|
||||
PrevChild = *Child;
|
||||
Child = &((*Child)->Next);
|
||||
Count++;
|
||||
}
|
||||
@@ -204,8 +207,7 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
||||
// Create element if needed
|
||||
if (!*Child && Create) {
|
||||
if ((Index == -1) || (Index = Count + 1)) {
|
||||
*Child = CreateMember( NULL );
|
||||
Member->Len++;
|
||||
*Child = CreateMember( Member, PrevChild, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,13 +240,14 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
|
||||
}
|
||||
|
||||
// Find next parent
|
||||
PrevChild = NULL;
|
||||
Child = &(Member->FirstChild);
|
||||
while (*Child && (((*Child)->NameLen != KeyLen) || strncasecmp( (*Child)->Name, Key, KeyLen ))) {
|
||||
PrevChild = *Child;
|
||||
Child = &((*Child)->Next);
|
||||
}
|
||||
if (!*Child && Create) {
|
||||
*Child = CreateMember( Key, KeyLen );
|
||||
Member->Len++;
|
||||
*Child = CreateMember( Member, PrevChild, Key, KeyLen );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +327,6 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
|
||||
else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
|
||||
// If valid path, destroy member
|
||||
DestroyMember( Member );
|
||||
Parent->Len--;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -34,6 +34,8 @@ struct SDataMember
|
||||
char * Value;
|
||||
unsigned short Len;
|
||||
|
||||
TDataMember * Parent;
|
||||
TDataMember * Prev;
|
||||
TDataMember * Next;
|
||||
};
|
||||
|
||||
@@ -45,8 +47,7 @@ private:
|
||||
TDataMember * RootMember;
|
||||
|
||||
// Manage Members
|
||||
TDataMember * CreateMember( const char * Name, const int Len = -1 );
|
||||
bool AddMember( TDataMember * Parent, TDataMember * Member );
|
||||
TDataMember * CreateMember( TDataMember * Parent, TDataMember * PrevChild, const char * Name, const int Len = -1 );
|
||||
bool DestroyMember( TDataMember ** Member );
|
||||
bool DestroyValue( TDataMember * Member );
|
||||
|
||||
@@ -68,8 +69,10 @@ public:
|
||||
TDataMember * GetIndexChild( TDataMember * Parent, const int Index );
|
||||
TDataMember * GetFirstChild( TDataMember * Parent, const char * Path, bool Create = false );
|
||||
|
||||
inline TDataMember * GetParent( TDataMember * Child ) { return ((Child)? Child->Parent : NULL); };
|
||||
inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); };
|
||||
inline TDataMember * GetNextChild( TDataMember * PrevChild ) { return ((PrevChild)? PrevChild->Next : NULL); };
|
||||
inline TDataMember * GetPrevChild( TDataMember * Child ) { return ((Child)? Child->Prev : NULL); };
|
||||
inline TDataMember * GetNextChild( TDataMember * Child ) { return ((Child)? Child->Next : NULL); };
|
||||
|
||||
const char * GetStr( TDataMember * BaseMember, const char * Path, const char * Default = NULL, bool Create = false );
|
||||
const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, const char * Default = NULL, bool Create = false );
|
||||
|
||||
@@ -598,7 +598,8 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
||||
|
||||
bool CJSONparse::ParseArray( TDataMember * Array )
|
||||
{
|
||||
TDataMember * Member = NULL;
|
||||
TDataMember ** Member;
|
||||
TDataMember * PrevMember;
|
||||
|
||||
// Check for start of Object
|
||||
if (*BufPos != '[') {
|
||||
@@ -608,7 +609,8 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
||||
|
||||
// Set Type
|
||||
DataTree->SetValue( Array, jtArray );
|
||||
|
||||
Member = &(Array->FirstChild);
|
||||
PrevMember = NULL;
|
||||
while (true)
|
||||
{
|
||||
// Look for Member Name
|
||||
@@ -618,17 +620,18 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
||||
}
|
||||
|
||||
// Add new element
|
||||
Member = DataTree->CreateMember( NULL );
|
||||
*Member = DataTree->CreateMember( Array, PrevMember, NULL );
|
||||
|
||||
// Get Value
|
||||
SkipWhiteSpace();
|
||||
if (!ParseObject( Member ) && !Error && !ParseArray( Member ) && !Error && !ParseString( Member ) && !Error && !ParsePrimitive( Member ) ) {}
|
||||
if (!ParseObject( *Member ) && !Error && !ParseArray( *Member ) && !Error && !ParseString( *Member ) && !Error && !ParsePrimitive( *Member ) ) {}
|
||||
if (Error) {
|
||||
DataTree->DestroyMember( &Member );
|
||||
DataTree->DestroyMember( Member );
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
DataTree->AddMember( Array, Member );
|
||||
PrevMember = *Member;
|
||||
Member = &((*Member)->Next);
|
||||
}
|
||||
|
||||
// Check if more parameters to follow
|
||||
|
||||
Reference in New Issue
Block a user