📄 xml.cpp
字号:
int XMLElement :: RemoveElement(unsigned int i)
{
if (i >= childrennum)
return childrennum;
if (children[i] == 0)
{
// Unloaded already, just delete the file
DeleteUnloadedElementFile(i);
}
bool DoDelete = true;
// Check if this item is borrowed
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;
for(unsigned int k = i ; k < childrennum ; k++)
children[k] = children[k + 1];
children[childrennum - 1] = 0;
return --childrennum;
}
int XMLElement :: RemoveElementAndKeep(unsigned int i,XMLElement** el)
{
if (el)
*el = 0;
if (i >= childrennum)
return childrennum;
if (children[i] == 0) // unloaded
ReloadElement(i);
//delete children[i];
if (el)
*el = children[i];
children[i] = 0;
for(unsigned int k = i ; k < childrennum ; k++)
children[k] = children[k + 1];
children[childrennum - 1] = 0;
return --childrennum;
}
int XMLElement :: UnloadElement(unsigned int i)
{
XMLElement* e = children[i];
if (!e)
return 1; // already unloaded
e->ReloadAllElements();
// 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");
FILE* fp = fopen(us,"rb");
if (fp)
{
// file exists !
fclose(fp);
return 0;
}
fp = fopen(us,"wb");
if (!fp)
{
// Failed !
return 0;
}
e->Export(fp,1,XML_SAVE_MODE_ZERO);
fclose(fp);
// Delete this element, but do not remove it.
delete children[i];
children[i] = 0;
return 1;
}
int XMLElement :: ReloadElement(unsigned int i)
{
if (children[i])
return 1; // Item is already here
// 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");
FILE* fp = fopen(us,"rb");
if (!fp)
{
// file failed !
return 0;
}
fclose(fp);
XML fx(us);
int K = fx.ParseStatus();
if (K == 2) // Fatal error
return 0;
XMLElement* r = fx.RemoveRootElementAndKeep();
// Reload element
children[i] = r;
r->SetParent(this);
#ifdef LINUX
remove(us);
#else // Win32
#ifdef WINCE // Only Wide
Z<wchar_t> usw(si + 1000);
MultiByteToWideChar(CP_ACP,0,us,-1,usw,si + 1000);
DeleteFileW(usw);
#else
DeleteFileA(us);
#endif
#endif
return 1;
}
int XMLElement :: ReloadAllElements()
{
for(unsigned int i = 0 ; i < childrennum ; i++)
{
if (children[i] == 0)
ReloadElement(i);
}
return 0;
}
int XMLElement :: MoveElement(unsigned int i,unsigned int y)
{
if (i >= childrennum || y >= childrennum)
return childrennum;
XMLElement* x = children[i];
children[i] = 0;
for(unsigned int k = i ; k < childrennum ; k++)
children[k] = children[k + 1];
childrennum--;
return InsertElement(y,x);
}
int XMLElement :: InsertElement(unsigned int y,XMLElement* x)
{
// leave from 0 to y
// move from y + 1 to childrennum + 1
// save
// childrennum++;
if (y >= childrennum)
return AddElement(x);
SpaceForElement(1);
memmove((void*)(children + y + 1),(void*)(children + y),(childrennum - y)*sizeof(XMLElement*));
children[y] = x;
x->SetParent(this);
childrennum++;
return y;
}
int XMLElement :: BorrowElement(XMLElement*x,unsigned int y)
{
// Same as Insert or Add, but no SetParent
// put 'x' in the list of 'borrowed elements'
if (BorrowedElements.is() <= NumBorrowedElements)
BorrowedElements.AddResize(5);
XMLBORROWELEMENT xb = {0};
xb.Active = 1;
xb.x = x;
BorrowedElements[NumBorrowedElements++] = xb;
SpaceForElement(1);
if (y >= childrennum)
{
children[childrennum++] = x;
return childrennum;
}
memmove((void*)(children + y + 1),(void*)(children + y),(childrennum - y)*sizeof(XMLElement*));
children[y] = x;
childrennum++;
return y;
}
int XMLElement :: ReleaseBorrowedElements()
{
int R = 0;
for(unsigned int y = 0 ; y < NumBorrowedElements ; y++)
{
XMLBORROWELEMENT& xb = BorrowedElements[y];
if (xb.Active == 0)
continue;
for(int i = (childrennum - 1) ; i >= 0 ; i--)
{
if (children[i] == xb.x)
{
RemoveElement(i);
xb.Active = 0;
R++;
}
}
}
NumBorrowedElements = 0;
return R;
}
int XMLElement :: UpdateElement(XMLElement* e,bool UpdateVariableValues)
{
/*
Formula
Checks variables, if not existing, copies
If existing, does nothing.
Search is case-sensitive.
Checks elements, if not existing, copies
if existing, calls UpdateElement() for each element
*/
// Test the variables
Z<char> vn(1000);
for(unsigned int i = 0 ; i < e->GetVariableNum() ; i++)
{
XMLVariable* v = e->GetVariables()[i];
if (v->GetName(0) > 1000)
vn.Resize(v->GetName(0) + 1000);
v->GetName(vn);
XMLVariable* tv = FindVariableZ(vn,0);
if (tv == 0)
{
// Create
AddVariable(v->Duplicate());
}
else
{
if (UpdateVariableValues)
{
if (v->GetValue(0) > 1000)
vn.Resize(v->GetValue(0) + 1000);
v->GetValue(vn);
tv->SetValue(vn);
}
}
}
// Test the elements
for(unsigned int i = 0 ; i < e->GetChildrenNum() ; i++)
{
XMLElement* c = e->GetChildren()[i];
if (c->GetElementName(0) > 1000)
vn.Resize(c->GetElementName(0) + 1000);
c->GetElementName(vn);
XMLElement* tc = FindElementZ(vn,0);
if (tc == 0)
{
// Copy
AddElement(c->Duplicate());
}
else
{
tc->UpdateElement(c,UpdateVariableValues);
}
}
return 0;
}
int XMLElement :: RemoveTemporalVariables(bool Deep)
{
int iNum = 0;
for(int i = variablesnum - 1 ; i >= 0 ; i--)
{
if (variables[i]->IsTemporal())
{
RemoveVariable(i);
iNum++;
}
}
if (Deep)
{
for(unsigned int i = 0 ; i < childrennum ; i++)
{
iNum += children[i]->RemoveTemporalVariables();
}
}
return iNum;
}
int XMLElement :: RemoveTemporalElements(bool Deep)
{
int iNum = 0;
for(int i = childrennum - 1 ; i >= 0 ; i--)
{
if (children[i]->IsTemporal())
{
RemoveElement(i);
iNum++;
}
}
if (Deep)
{
for(unsigned int i = 0 ; i < childrennum ; i++)
{
iNum += children[i]->RemoveTemporalElements();
}
}
return iNum;
}
int XMLElement :: RemoveAllVariables()
{
for(int i = variablesnum - 1 ; i >= 0 ; i--)
{
delete variables[i];
variables[i] = 0;
}
variablesnum = 0;
return 0;
}
int XMLElement :: RemoveVariable(unsigned int i)
{
if (i >= variablesnum)
return variablesnum;
delete variables[i];
variables[i] = 0;
for(unsigned int k = i ; k < variablesnum ; k++)
variables[k] = variables[k + 1];
variables[variablesnum - 1] = 0;
return --variablesnum;
}
int XMLElement :: RemoveVariableAndKeep(unsigned int i,XMLVariable** vr)
{
if (vr)
{
*vr = 0;
}
if (i >= variablesnum)
return variablesnum;
//delete variables[i];
if (vr)
{
*vr = variables[i];
}
variables[i] = 0;
for(unsigned int k = i ; k < variablesnum ; k++)
variables[k] = variables[k + 1];
variables[variablesnum - 1] = 0;
return --variablesnum;
}
void XML :: Export(FILE* fp,XML_SAVE_MODE SaveMode,XML_TARGET_MODE TargetMode,XMLHeader *hdr,class XMLTransform* eclass,class XMLTransformData* edata)
{
// Export all elements
root->Export(fp,1,SaveMode,TargetMode,hdr,eclass,edata);
}
void XML :: SetExportFormatting(XMLEXPORTFORMAT* xf)
{
root->SetExportFormatting(xf);
}
XMLElement* XMLElement :: GetElementInSection(const char* section2)
{
// From section, get the element we need
XMLElement* r = this;
if (strcmp(section2,"") == 0)
return this;
Z<char> section(strlen(section2) + 1);
strcpy(section,section2);
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;
}
return r;
}
void XMLElement :: Write16String(FILE* fp,const char* s)
{
#ifdef _WIN32
size_t sl = strlen(s)*2 + 100;
Z<wchar_t> ws(sl);
MultiByteToWideChar(CP_UTF8,0,s,-1,ws,(int)sl);
fwrite(ws.operator wchar_t*(),1,wcslen(ws)*2,fp);
#endif
}
void XMLElement :: printc(FILE* fp,XMLElement* root,int deep,int ShowAll,XML_SAVE_MODE SaveMode,XML_TARGET_MODE TargetMode)
{
if (!root)
return;
root->ReloadAllElements();
char* sp = (char*)fp;
if (TargetMode == 1)
sp += strlen(sp);
unsigned int spi = 0;
#ifdef _WIN32
HKEY pKey = (HKEY)fp;
HKEY pKey2 = 0;
#endif
/*
Targetmodes
0 - Export to a FILE*
1 - Export to memory
2 - Export to a registry key (Win32)
3 - Export to a FILE* , utf-16
*/
char DelimiterChar[100] = {0};
if (root->xfformat.UseSpace)
{
for(int i = 0 ; i < root->xfformat.nId ; i++)
strcat(DelimiterChar," ");
}
else
{
for(int i = 0 ; i < root->xfformat.nId ; i++)
strcat(DelimiterChar,"\t");
}
//* Use it later
size_t Sug = root->GetElementName(0,SaveMode);
Z<char> b(Sug + deep + 100);
for(int i = 0 ; i < deep ; i++)
//strcat(b,"\t");
strcat(b,DelimiterChar);
strcat(b,"<");
root->GetElementName(b.operator char*() + strlen(b),SaveMode);
if (TargetMode == 1)
{
spi = sprintf(sp,"%s",b.operator char*());
sp += spi;
}
else
if (TargetMode == 2)
{
#ifdef _WIN32
#ifndef WINCE
XMLElement* par = root->GetParent();
int bP = 0;
if (par)
{
bP = par->FindElement(root);
}
sprintf(b,"E%u",bP);
root->GetElementName(b.operator char *() + strlen(b),SaveMode);
DWORD dw = 0;
RegCreateKeyExA(pKey,b,0,0,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,0,&pKey2,&dw);
#endif
#endif
}
else
if (TargetMode == 3)
Write16String(fp,b.operator char*());
else
fprintf(fp,"%s",b.operator char*());
int iY = root->GetVariableNum();
int iC = root->GetChildrenNum();
// print variables if they exist
// XMLVariable* SaveAstVariable = 0;
if (iY)
{
for(int i = 0 ; i < iY ; i++)
{
XMLVariable* v = root->GetVariables()[i];
size_t s1 = v->GetName(0,SaveMode);
size_t s2 = v->GetValue(0,SaveMode);
Z<char> Name(s1 + 10);
Z<char> Value(s2 + 10);
v->GetName(Name,SaveMode);
v->GetValue(Value,SaveMode);
/* if (strcmp(Name,"*") == 0)
SaveAstVariable = v;
else*/
{
if (TargetMode == 1)
{
spi = sprintf(sp," %s=",Name.operator char*());
sp += spi;
spi = sprintf(sp,"\"%s\"",Value.operator char*());
sp += spi;
}
else
if (TargetMode == 2)
{
#ifdef _WIN32
#ifndef WINCE
// create a value
Z<char> VName(strlen(Name) + 10);
sprintf(VName,"V%s",Name.operator char*());
RegSetValueExA(pKey2,VName,0,REG_SZ,(const BYTE*)Value.operator char *(),(int)(strlen(Value) + 1));
#endif
#endif
}
else
if (TargetMode == 3)
{
Z<char> xy(strlen(Name)*2 + 100 + strlen(Value)*2);
sprintf(xy," %s=\"%s\"",Name.operator char*(),Value.operator char*());
Write16String(fp,xy);
}
else // TM == 0
{
fprintf(fp," %s=",Name.operator char*());
fprintf(fp,"\"%s\"",Value.operator char*());
}
}
}
}
// cdatas, comments, contents may be between children
int TotalCDatas = root->GetCDatasNum();
int NextCData = 0;
int TotalComments = root->GetCommentsNum();
int NextComment = 0;
int TotalContents = root->GetContentsNum();
int NextContent = 0;
// children ?
// close now if no children/contents/comments
if ((!iC || ShowAll == 0) && /*SaveAstVariable == 0 &&*/ TotalContents == 0 && TotalComments == 0 && TotalCDatas == 0)
{
if (TargetMode == 1)
{
spi = sprintf(sp,"/>\r\n");
sp += spi;
}
else
if (TargetMode == 2)
; // Nothing :)
else
if (TargetMode == 3)
fwrite(L"/>\r\n",1,4,fp);
else // 0
fprintf(fp,"/>\r\n");
return;
}
if (TargetMode == 1)
{
spi = sprintf(sp,">\r\n",b.operator char*());
sp += spi;
}
else
{
// Write \r\n only if ElementBreak
if (root->xfformat.ElementsNoBreak == false || TotalContents != 1 || TotalComments || TotalCDatas || iC)
{
if (TargetMode == 2)
; // Nothing :)
else
if (TargetMode == 3)
fwrite(L">\r\n",1,3,fp);
else
fprintf(fp,">\r\n",b.operator char*());
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -