📄 xml.cpp
字号:
unsigned long N = 0;
for(int z = (y - 1) ; z >= 0 ; z--)
{
N += dig[z] * XMLHelper :: pow(16,(y - 1) - z);
}
// Convert result to UTF-8
char d1[100] = {0};
#ifdef _WIN32
wchar_t d2[100] = {0};
swprintf(d2,L"%c",(wchar_t)N);
WideCharToMultiByte(CP_UTF8,0,d2,-1,d1,100,0,0);
#endif
strcat(trg + x,d1);
x += strlen(d1);
i++;
continue;
}
if (src[i] == '&' && src[i + 1] == '#')
{
i += 2;
int dig[10] = {0};
int y = 0;
while (src[i] >= 0x30 && src[i] <= 0x39)
{
dig[y] = src[i] - 0x30;
y++;
i++;
}
unsigned long N = 0;
for(int z = (y - 1) ; z >= 0 ; z--)
{
N += dig[z] * XMLHelper :: pow(10,(y - 1) - z);
}
// Convert result to UTF-8
char d1[100] = {0};
#ifdef _WIN32
wchar_t d2[100] = {0};
swprintf(d2,L"%c",(wchar_t)N);
WideCharToMultiByte(CP_UTF8,0,d2,-1,d1,100,0,0);
#endif
strcat(trg + x,d1);
x += strlen(d1);
i++;
continue;
}
if (src[i] == '&')
{
if (strncmp(src + i + 1,"amp;",4) == 0)
{
i += 5;
trg[x] = '&';
x++;
}
else
if (strncmp(src + i + 1,"quot;",5) == 0)
{
i += 6;
trg[x] = '\"';
x++;
}
else
if (strncmp(src + i + 1,"apos;",5) == 0)
{
i += 6;
trg[x] = '\'';
x++;
}
else
if (strncmp(src + i + 1,"lt;",3) == 0)
{
i += 4;
trg[x] = '<';
x++;
}
else
if (strncmp(src + i + 1,"gt;",3) == 0)
{
i += 4;
trg[x] = '>';
x++;
}
else
x++; // ignore invalid symbol
continue;
}
trg[x] = src[i];
i++;
x++;
}
trg[x] = 0;
return strlen(trg);
}
size_t XML :: XMLGetValue(const char* section2,const char* attr2,char* put2,size_t maxlen)
{
size_t y1 = XMLEncode(section2,0);
size_t y2 = XMLEncode(attr2,0);
Z<char> section(y1 + 10);
Z<char> attr(y2 + 10);
XMLEncode(section2,section);
XMLEncode(attr2,attr);
if (y1 == 0) // root
{
int k = root->FindVariable(attr);
if (k == -1)
return 0;
XMLVariable* v = root->GetVariables()[k];
size_t Sug = v->GetValue(0);
Z<char> value(Sug + 10);
v->GetValue(value);
size_t Y = strlen(value);
if (Y > maxlen)
return Y;
strcpy(put2,value);
return Y;
}
// section is a\b\c\d...
XMLElement* r = root;
char* a2 = section.operator char *();
for( ; ; )
{
char* a1 = strchr(a2,'\\');
if (a1)
*a1 = 0;
int y = r->FindElement(a2);
if (y == -1)
{
if (a1)
*a1 = '\\';
return 0;
}
r = r->GetChildren()[y];
if (!a1) // was last
break;
*a1 = '\\';
a2 = a1 + 1;
}
// element with this variable is found !
int k = r->FindVariable(attr);
if (k == -1)
return 0;
XMLVariable* v = r->GetVariables()[k];
size_t Sug = v->GetValue(0);
Z<char> value(Sug + 10);
v->GetValue(value);
size_t Y = strlen(value);
if (Y > maxlen)
return Y;
strcpy(put2,value);
return Y;
}
void XML :: XMLSetValue(const char* section2,const char* attr,char* put)
{
// section is a\b\c\d...
XMLElement* r = root;
XMLElement* rr = root;
Z<char> section(strlen(section2) + 10);
strcpy(section,section2);
char* a2 = section.operator char *();
// Also set to delete values
// if put is NULL, delete the specified attribute
// if attr is NULL, delete the specified section (and all subsections!)
if (!section || strlen(section) == 0)
{
int k = root->FindVariable(attr);
if (k == -1)
{
XMLVariable* x = new XMLVariable(attr,"",0);
root->AddVariable(x);
k = root->FindVariable(attr);
}
if (put == 0)
{
// Delete this attribute
root->RemoveVariable(k);
}
else
{
root->GetVariables()[k]->SetValue(put);
}
return;
}
int y = 0;
for( ; ; )
{
char* a1 = strchr(a2,'\\');
if (a1)
*a1 = 0;
y = r->FindElement(a2);
if (y == -1)
{
// Create this element
XMLElement* n = new XMLElement(r,a2);
r->AddElement(n);
y = r->FindElement(n);
}
rr = r;
r = rr->GetChildren()[y];
if (!a1) // was last
break;
*a1 = '\\';
a2 = a1 + 1;
}
// element with this variable is found/created!
if (attr == 0)
{
// DELETE this element AND all sub-elements!!
rr->RemoveElement(y);
return;
}
int k = r->FindVariable(attr);
if (k == -1)
{
XMLVariable* x = new XMLVariable(attr,"",0);
r->AddVariable(x);
k = r->FindVariable(attr);
}
if (put == 0)
{
// Delete this attribute
r->RemoveVariable(k);
}
else
{
r->GetVariables()[k]->SetValue(put);
}
}
char* XMLHelper :: FindXMLClose(char* s)
{
// For Each <!-- we must find a -->
// For Each <? we must find a ?>
// For each <> , we must find a </>
// For each <![CDATA[ we mst find a ]]>
// For each < /> , its all ok :)
int d = 0;
char* a2 = s;
bool IsComment = false;
bool IsCData = false;
for(;;)
{
char* a1 = strchr(a2,'<');
if (!a1) // duh
return 0;
if (*(a1 + 1) == '/')
{
a2 = strchr(a1,'>');
if (!a2) // duh
return 0;
a2++;
d--;
if (!d)
return a2;
continue;
}
if ((*(a1 + 1) == '!' && strlen(a1) > 2 && *(a1 + 2) == '-' && *(a1 + 3) == '-') || *(a1 + 1) == '?')
IsComment = true;
if (*(a1 + 1) == '!' && strlen(a1) > 8 && strncmp(a1 + 1,"![CDATA[",8) == 0)
IsCData = true;
bool Nest = 0;
for(;;)
{
// Bugfix
if (IsCData && (*(a1) != ']' || *(a1 + 1) != ']' || *(a1 + 2) != '>'))
{
a1++;
continue;
}
if (IsCData)
{
a1 += 2;
break;
}
if (*a1 != '/' && *a1 != '>')
{
if (*a1 == '\"')
Nest = !Nest;
a1++;
continue;
}
if (*a1 == '/' && Nest)
{
a1++;
continue;
}
// Also continue if / and no comment/no cdata
if (*a1 == '/' && (IsComment || IsCData))
{
a1++;
continue;
}
// Also continue if > and cdata with no ]]
if (*a1 == '>' && IsCData && (*(a1 - 1) != ']' || *(a1 - 2) != ']'))
{
a1++;
continue;
}
// Also continue if > and comment with no --
if (*a1 == '>' && IsComment && (*(a1 - 1) != '-' || *(a1 - 2) != '-'))
{
a1++;
continue;
}
break;
}
d++;
if ((*a1 == '/' || IsComment) && !IsCData) // nice, it closes
{
IsComment = false;
a2 = a1 + 1;
d--;
if (d == 0)
return a2; // finish !
continue;
}
if (*a1 == '>' && IsCData && *(a1 - 1) == ']' && *(a1 - 2) == ']')
{
IsCData = false;
a2 = a1 + 1;
d--;
if (d == 0)
return a2; // finish !
continue;
}
a2 = a1 + 1;
}
}
void XMLHelper :: AddBlankVariable(XMLElement* parent,char *a2,int Pos)
{
size_t Y = strlen(a2);
if (Y == 0 || parent == 0)
return;
char* a1 = a2;
while(*a1 == ' ' || *a1 == '\t' || *a1 == '\n' || *a1 == '\r')
a1++;
size_t Z = strlen(a1);
if (Z == 0)
return;
size_t PZ = Z;
while(a1[PZ - 1] == '\t' || a1[PZ - 1] == '\r' || a1[PZ - 1] == '\n' || a1[PZ - 1] == ' ')
PZ--;
if (PZ == 0)
return;
char CC = a1[PZ];
a1[PZ] = 0;
// Add this vrb
XMLContent* x = new XMLContent(parent,Pos,a1,true);
parent->AddContent(x,Pos);
a1[PZ] = CC;
}
XMLElement* XMLHelper :: ParseElementTree(XMLHeader* hdr,XMLElement* parent,char* tree,char** EndValue,XML_PARSE_STATUS& iParseStatus)
{
char *a1,*a2,*a3,*a4,*a5;//,*a6;
char c1,c2;//,c3,c4,c5,c6;
XMLElement* root = 0;
bool IsRootCommentSecond = false;
a2 = tree;
for(;;)
{
// find
a3 = strchr(a2,'<');
if (!a3)
{
int Pos = parent ? parent->GetChildrenNum() : 0;
XMLHelper :: AddBlankVariable(parent,a2,Pos);
break; // end/error
}
// Bugfix: See if a3 is cdata
bool IsCData = false;
if (strncmp(a3,"<![CDATA[",8) == 0)
IsCData = true;
// Bugfix: See if a3 is comment
bool IsComment = false;
if (strncmp(a3,"<!--",4) == 0)
IsComment = true;
// Between a3 and a2, add everything which isn't \r\n,space,tabs
*a3 = 0;
int PosV = parent ? parent->GetChildrenNum() : 0;
XMLHelper :: AddBlankVariable(parent,a2,PosV);
*a3 = '<';
if (IsCData == true)
a4 = strstr(a3,"]]>");
else
if (IsComment == true)
a4 = strstr(a3,"-->");
else
a4 = strchr(a3,'>');
if (!a4)
break; // end/error
if (IsCData)
a4 += 2; // move to '>'
if (IsComment)
a4 += 2; // move to '>'
if ((*(a3 + 1) == '!' && strlen(a3 + 1) > 2 && *(a3 + 2) == '-' && *(a3 + 3) == '-' ) || *(a3 + 1) == '?') // comment/markup
{
c2 = *a4;
*a4 = 0;
if (parent)
{
//XMLElement* c = new XMLElement(parent,a3 + 1,1);
//parent->AddElement(c);
int Pos = parent->GetChildrenNum();
Z<char> com(strlen(a3) + 100);
strncpy(com,a3 + 4,strlen(a3 + 4) - 2);
XMLComment* c = new XMLComment(parent,Pos,com);
parent->AddComment(c,Pos);
}
else // It is a root comment
{
int Pos = IsRootCommentSecond;
Z<char> com(strlen(a3) + 100);
if (strlen(a3 + 4) > 1)
strncpy(com,a3 + 4,strlen(a3 + 4) - 2);
XMLComment* c = new XMLComment(0,Pos,com);
hdr->AddComment(c,Pos);
}
*a4 = c2;
a2 = a4 + 1;
continue;
}
if ((*(a3 + 1) == '!' && strlen(a3 + 1) > 8 && strncmp(a3 + 1,"![CDATA[",8) == 0)) // cdata
{
c2 = *a4;
*a4 = 0;
int Pos = parent->GetChildrenNum();
Z<char> com(strlen(a3) + 100);
strncpy(com,a3 + 9,strlen(a3 + 9) - 2);
XMLCData* c = new XMLCData(parent,Pos,com);
parent->AddCData(c,Pos);
*a4 = c2;
a2 = a4 + 1;
continue;
}
if (*(a3 + 1) == '/') // bye bye from this element
{
if (parent && root && parent->FindElement(root) == -1)
parent->AddElement(root);
a2 = a4 + 1;
continue;
}
IsRootCommentSecond = true;
// It is an opening element
// If < /> , all ok, Add to current and continue
// If < > , then find relative at end, and recursive
if (*(a4 - 1) == '/')
{
// Yes it is this element alone
c2 = *a4;
*a4 = 0;
XMLElement* c = new XMLElement(parent,a3 + 1,0);
if (parent)
parent->AddElement(c);
else
;// invalid. Can't have a < /> root
*a4 = c2;
a2 = a4 + 1;
if (!root)
root = c;
continue;
}
// Now it is an < > entry
// Find this one at end, strchr <
a5 = XMLHelper :: FindXMLClose(a3);
if (!a5)
{
// ERROR in the FILE
iParseStatus = XML_PARSE_ERROR;
return root;
}
a5--; // fixes a bug when next element is rightly after closing
while(*a5 != '<')
a5--;
a1 = a5;
c1 = *a1;
*a1 = 0;
// Create element a3
c2 = *(a4 + 1);
*(a4 + 1) = 0;
root = new XMLElement(parent,a3,0);
*(a4 + 1) = c2;
char* eV = 0;
XMLHelper :: ParseElementTree(hdr,root,a4 + 1,&eV,iParseStatus);
char* sa2 = a2;
*a1 = c1;
a2 = a1;
if (eV)
a2 = eV;
if (a2 == sa2)
break; // whops ? error! . Break to avoid fatal loop
continue;
}
return root;
}
int XMLElement :: RemoveAllElements()
{
for(int i = childrennum - 1 ; i >= 0 ; i--)
{
if (children[i] == 0)
{
// Unload
DeleteUnloadedElementFile(i);
}
bool DoDelete = true;
for(unsigned int xi = 0 ; xi < NumBorrowedElements ; xi++)
{
if (BorrowedElements[xi].Active == 0)
continue;
if (BorrowedElements[xi].x == children[i])
{
BorrowedElements[xi].Active = 0;
DoDelete = false;
break;
}
}
if (DoDelete)
delete children[i];
children[i] = 0;
}
childrennum = 0;
return 0;
}
void XMLElement :: SetElementParam(unsigned __int64 p)
{
param = p;
}
unsigned __int64 XMLElement :: GetElementParam()
{
return param;
}
int XMLElement :: DeleteUnloadedElementFile(int i)
{
// Find Unique STR
size_t si = GetElementUniqueString(0);
Z<char> us(si);
GetElementUniqueString(us);
if (us[strlen(us) - 1] == '-')
us[strlen(us) - 1] = 0;
// Add this element
if (strlen(us))
sprintf(us + strlen(us),"-%u",i);
else
sprintf(us + strlen(us),"%u",i);
// Extension
strcat(us,".xmltmp");
#ifdef LINUX
return remove(us);
#else // Win32
#ifdef WINCE // Only Wide
Z<wchar_t> usw(si + 1000);
MultiByteToWideChar(CP_ACP,0,us,-1,usw,si + 1000);
return DeleteFileW(usw);
#else
return DeleteFileA(us);
#endif
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -