xmlconfig.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,482 行 · 第 1/4 页
CPP
2,482 行
{
const char* name = tag->get_attribute("name");
if(!name)
{
ERRMSG(m_pMessages,
"%s: List tag requires a name attribute",
m_filename);
// Process anyway, give it a dummy name
name = "XXXBADLIST";
}
/*
* Remove current tag from list, push current list,
* create new list, add next level's props.
*/
_RemovePropFromList(pNewList, name);
curr_level.AddLevel(name);
if (!_PropExists(&curr_level, m_pRegistry))
{
curr_level.RemoveLevel();
ulListsToIgnore++;
}
else
{
levlist.AddHead((void*)pNewList);
if (wspacetag)
{
fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
strlen(wspacetag->m_cur_attribute->value), fpNew);
delete wspacetag;
wspacetag = 0;
}
fprintf(fpNew, "<List Name=\"%s\">", name);
pNewList = new CHXSimpleList;
_AddPropsToList(pNewList, curr_level.CharStar(), m_pRegistry);
}
}
}
}
else if(tag->m_type != XMLEndTag)
{
if (!ulListsToIgnore)
{
const char* name = tag->get_attribute("name");
const char* value = tag->get_attribute("value");
if (name)
{
curr_level.AddLevel(name);
_RemovePropFromList(pNewList, name);
/*
* Make sure this prop is still set.
*/
if (_PropExists(&curr_level, m_pRegistry))
{
if (wspacetag)
{
fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
strlen(wspacetag->m_cur_attribute->value), fpNew);
delete wspacetag;
wspacetag = 0;
}
char* p = _GetPropValueString(curr_level.CharStar(), m_pRegistry);
if (p)
{
fprintf(fpNew, "<Var %s=\"%s\"/>",
name,
p);
delete[] p;
}
}
curr_level.RemoveLevel();
}
}
}
else
{
// An End Tag
if(strcasecmp(tag->m_name, "list") == 0)
{
if (ulListsToIgnore)
{
ulListsToIgnore --;
}
else
{
/*
* Need to add the stuff at this level that was
* was not in the config file.
*/
if (pNewList->GetCount() == 0)
{
if (wspacetag)
{
fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
strlen(wspacetag->m_cur_attribute->value), fpNew);
}
}
else
{
fprintf(fpNew, "\n");
AppendPropsToFile(fpNew, curr_level, pNewList,
4, m_pRegistry, pKeyName);
_IndentFile(fpNew, 4, curr_level, pKeyName);
}
delete wspacetag;
wspacetag = 0;
fprintf(fpNew, "</List>");
curr_level.RemoveLevel();
delete pNewList;
pNewList = (CHXSimpleList*)levlist.RemoveHead();
}
}
}
break;
}
}
// Give up if we've lost all hope
if (HXR_OK != hResult)
{
break;
}
}
if (hResult == HXR_OK && wspacetag)
{
fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
strlen(wspacetag->m_cur_attribute->value), fpNew);
delete wspacetag;
wspacetag = 0;
}
/*
* Ok, done with the whole file. Make sure that all of the base level stuff
* gets added.
*/
//XXXPM Calculate this later.
if (hResult == HXR_OK)
{
int indent = 4;
AppendPropsToFile(fpNew, curr_level, pNewList, indent, m_pRegistry, pKeyName);
}
// cleanup
if (fpNew) fclose(fpNew);
if (fpOld) fclose(fpOld);
HX_DELETE(pNewList);
HX_VECTOR_DELETE(pBuf);
HX_DELETE(tag);
return hResult;
}
void
XMLConfig::_AddPropsToList(CHXSimpleList* pList, const char* pName,
IHXRegistry2* preg)
{
IHXValues* pValues = 0;
UINT32 ul;
const char* pPropName;
preg->GetPropListByName(pName, pValues);
if (pValues)
{
if (HXR_OK == pValues->GetFirstPropertyULONG32(pPropName, ul))
{
XMLPropInfo* pInfo = new XMLPropInfo;
pInfo->m_pName = new char[strlen(pPropName) + 1 - strlen(pName)];
strcpy(pInfo->m_pName, &(pPropName[strlen(pName) + 1])); /* Flawfinder: ignore */
pInfo->m_Type = preg->GetTypeByName(pPropName);
pList->AddHead((void*)pInfo);
while (HXR_OK == pValues->GetNextPropertyULONG32(pPropName, ul))
{
XMLPropInfo* pInfo = new XMLPropInfo;
pInfo->m_pName = new char[strlen(pPropName) + 1 - strlen(pName)];
strcpy(pInfo->m_pName, &(pPropName[strlen(pName) + 1]));
pInfo->m_Type = preg->GetTypeByName(pPropName);
pList->AddHead((void*)pInfo);
}
}
pValues->Release();
}
}
void
XMLConfig::_RemovePropFromList(CHXSimpleList* pList, const char* pName)
{
LISTPOSITION pos;
pos = pList->GetHeadPosition();
XMLPropInfo* pProp;
while (pos)
{
pProp = (XMLPropInfo*)pList->GetAt(pos);
if (!pProp)
{
return;
}
if (!strcasecmp(pProp->m_pName, pName))
{
pList->RemoveAt(pos);
delete pProp;
return;
}
pList->GetNext(pos);
}
}
char*
XMLConfig::_GetPropValueString(const char* pName, IHXRegistry2* pReg)
{
int vartype;
IHXBuffer* pBuffer;
INT32 l;
char* ret;
vartype = pReg->GetTypeByName(pName);
if(vartype == PT_INTEGER)
{
if(HXR_OK == pReg->GetIntByName(pName, l))
{
char num[32]; /* Flawfinder: ignore */
sprintf(num, "%d", l); /* Flawfinder: ignore */
ret = new char[strlen(num) + 1];
strcpy(ret, num); /* Flawfinder: ignore */
return ret;
}
else
{
return 0;
}
}
else if(vartype == PT_STRING)
{
if(HXR_OK == pReg->GetStrByName(pName,
pBuffer) && pBuffer)
{
ret = new char[pBuffer->GetSize()+1];
strcpy(ret, (const char*)pBuffer->GetBuffer()); /* Flawfinder: ignore */
pBuffer->Release();
return ret;
}
else
{
return 0;
}
}
return 0;
}
void
XMLConfig::_CleanList(CHXSimpleList* pList)
{
XMLPropInfo* pInfo;
while (!pList->IsEmpty())
{
pInfo = (XMLPropInfo*)pList->RemoveHead();
delete pInfo;
}
}
void
XMLConfig::AppendPropsToFile(FILE* fp, XMLConfigString level,
CHXSimpleList* pList, int indent_per_level,
IHXRegistry2* hxreg, const char* pBase)
{
XMLPropInfo* pInfo = 0;
while (!pList->IsEmpty())
{
pInfo = (XMLPropInfo*)pList->RemoveHead();
level.AddLevel(pInfo->m_pName);
_AppendPropToFile(fp, level, indent_per_level, hxreg, pBase);
level.RemoveLevel();
delete pInfo;
}
}
void
XMLConfig::_IndentFile(FILE* fp, int indent_per_level,
XMLConfigString level,
const char* pBase)
{
int dots_to_ignore = 1;
INT32 i;
const char* pc;
pc = pBase;
while (*pc)
{
if (*pc == '.')
{
dots_to_ignore ++;
}
pc++;
}
pc = level.CharStar();
while (*pc)
{
if (*pc == '.')
{
if (dots_to_ignore)
{
dots_to_ignore--;
}
else
{
for (i = 0; i < indent_per_level; i++)
{
fprintf(fp, " ");
}
}
}
pc ++;
}
}
void
XMLConfig::_AppendPropToFile(FILE* fp, XMLConfigString level,
int indent_per_level,
IHXRegistry2* hxreg,
const char* pBase)
{
/*
* Indent a proper amount.
*/
INT32 i;
IHXBuffer* pBuf = 0;
_IndentFile(fp, indent_per_level, level, pBase);
HXPropType type = hxreg->GetTypeByName(level.CharStar());
switch (type)
{
case PT_COMPOSITE:
fprintf(fp, "<List Name=\"%s\">\n", level.Top());
IHXValues* pValues;
if (HXR_OK == hxreg->GetPropListByName(level.CharStar(),
pValues) && pValues)
{
HX_RESULT res;
UINT32 ul;
const char* pName;
res = pValues->GetFirstPropertyULONG32(pName, ul);
while (res == HXR_OK)
{
const char* pc = pName + strlen(pName);
while (pc > pName)
{
pc--;
if (*pc == '.')
{
pc++;
level.AddLevel(pc);
_AppendPropToFile(fp, level, indent_per_level, hxreg, pBase);
level.RemoveLevel();
res = pValues->GetNextPropertyULONG32(pName, ul);
break;
}
}
}
pValues->Release();
}
_IndentFile(fp, indent_per_level, level, pBase);
fprintf(fp, "</List>\n");
break;
case PT_INTEGER:
if (HXR_OK == hxreg->GetIntByName(level.CharStar(), i))
{
fprintf(fp, "<Var %s=\"%ld\"/>\n", level.Top(),
i);
}
break;
case PT_STRING:
if (HXR_OK == hxreg->GetStrByName(level.CharStar(), pBuf)
&& pBuf)
{
fprintf(fp, "<Var %s=\"%s\"/>\n", level.Top(),
(const char*)pBuf->GetBuffer());
pBuf->Release();
pBuf = 0;
}
break;
}
}
int
XMLConfig::_PropExists(XMLConfigString* p, IHXRegistry2* preg)
{
return (preg->GetPropStatusByName(p->CharStar()) == HXR_OK) ? TRUE : FALSE;
}
/*
* IHXRegConfig::WriteKey
*/
STDMETHODIMP
XMLConfig::WriteKey(const char* pKeyName)
{
/*
* If there is a filename then we got it from a file.
*/
if (m_filename)
{
WriteToFile(pKeyName, m_filename);
return HXR_OK;
}
HX_ASSERT(0);
return HXR_FAIL;
}
HX_RESULT
XMLConfig::Reconfigure(IHXReconfigServerResponse* pResp)
{
if (m_pReconfigureResponse)
{
return HXR_UNEXPECTED;
}
m_pReconfigureResponse = pResp;
m_pReconfigureResponse->AddRef();
/*
* If they started from a config file, then reload
* from the config file.
*/
if (m_filename)
{
return Reconfigure(m_filename);
}
/*
* If we got here there was a booboo
*/
m_pReconfigureResponse->ReconfigServerDone(HXR_OK, 0, 0);
m_pReconfigureResponse->Release();
m_pReconfigureResponse = 0;
return HXR_OK;
}
HX_RESULT
XMLConfig::Reconfigure(const char* pFileName)
{
if (!pFileName)
{
return HXR_FAIL;
}
FILE* fp = fopen(pFileName, "r");
if (!fp)
{
return HXR_FAIL;
}
/*
* Pretend that there is one outstanding just to keep
* the done methods from getting called, seeing a 0,
* and sending the response until the end of this
* func.
*/
m_ActiveSetsOutstanding++;
const char* pKeyName = "config";
int l = 0;
BOOL filedone = 0;
XMLTag* tag = 0;
CBigByteQueue queue(MAX_TAG_SIZE);
XMLParser parser;
HX_RESULT hResult = HXR_OK;
/*
* Files are all aready. Now we need to build our config levels list.
*/
CHXSimpleList levlist;
/*
* Add for level 0.
*/
CHXSimpleList* pNewList = new CHXSimpleList;
IHXValues* pValues = 0;
_AddPropsToList(pNewList, pKeyName, m_pRegistry);
XMLConfigString curr_level;
curr_level.AddLevel(pKeyName);
// read the config file into the byte queue
INT32 nBufSize = 16384;
BYTE* pBuf = new BYTE[nBufSize];
while (!filedone && hResult == HXR_OK)
{
l = fread(pBuf, 1, nBufSize, fp);
if (l > 0)
{
if (!queue.EnQueue(pBuf, l))
{
if (!queue.Grow(l))
{
ERRMSG(m_pMessages,
"error expanding data structure while parsing %s",
pFileName);
hResult = HXR_FAIL;
}
if (!queue.EnQueue(pBuf, l))
{
ERRMSG(m_pMessages,
"unknown error while parsing %s",
pFileName);
hResult = HXR_FAIL;
}
}
}
else
{
filedone = TRUE;
}
}
UINT32 bytesUsed=0;
UINT32 bytesAvail=0;
BYTE* p=0;
while (hResult == HXR_OK && (bytesAvail = queue.GetQueuedItemCount()) > 0)
{
if (bytesAvail > nBufSize)
{
HX_VECTOR_DELETE(pBuf);
pBuf = new BYTE[bytesAvail];
nBufSize = bytesAvail;
}
p = pBuf;
queue.DeQueue(pBuf, bytesAvail);
bytesUsed = bytesAvail;
HX_DELETE(tag);
XMLParseResult res = parser.Parse((const char*&)p, bytesAvail, tag);
queue.EnQueue(p, bytesAvail - (p - pBuf));
switch(res)
{
case XMLPNoClose:
// A tag opener was found, but no closer yet.
if (filedone)
{
pBuf[bytesAvail - 1] = '\0';
if (bytesAvail > MAX_ERROR_CHARS)
{
pBuf[MAX_ERROR_CHARS - 1] = '\0';
}
ERRMSG(m_pMessages,
"%s: Missing close for tag %s...", m_filename, pBuf);
hResult = HXR_FAIL;
}
break;
case XMLPNoTagType:
*p = 0;
ERRMSG(m_pMessages,
"%s: Badly formed tag %s", m_filename, pBuf);
break;
case XMLPBadAttribute:
*p = 0;
ERRMSG(m_pMessages,
"%s: Badly formed attribute in %s", m_filename,
pBuf);
break;
case XMLPPlainText:
break;
case XMLPBadEndTag:
*p = 0;
ERRMSG(m_pMessages,
"%s: Unexpected tag %s", m_filename, pBuf);
break;
case XMLPComment:
break;
case XMLPDirective:
// A directive. We don't handle any yet.
break;
case XMLPProcInst:
// A processing Instruction, whee!
break;
case XMLPTag:
{
if(Expand(tag, &queue))
break;
if(tag->m_need_close)
{
if(strcasecmp(tag->m_name, "list") == 0)
{
const char* name = tag->get_attribute("name");
if(!name)
{
ERRMSG(m_pMessages,
"%s: List tag requires a name attribute",
m_filename);
// Process anyway, give it a dummy name
name = "XXXBADLIST";
}
/*
* Remove current tag from list, push current list,
* create new list, add next level's props.
*/
_RemovePropFromList(pNewList, name);
curr_level.AddLevel(name);
levlist.AddHead((void*)pNewList);
pNewList = new CHXSimpleList;
_AddPropsToList(pNewList, curr_level.CharStar(), m_pRegistry);
}
}
else if(tag->m_type != XMLEndTag)
{
const char* name = tag->get_attribute("name");
const char* value = tag->get_attribute("value");
if (name)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?