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