📄 xmlconfig.cpp
字号:
{ 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;}voidXMLConfig::_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(); }}voidXMLConfig::_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;}voidXMLConfig::_CleanList(CHXSimpleList* pList){ XMLPropInfo* pInfo; while (!pList->IsEmpty()) { pInfo = (XMLPropInfo*)pList->RemoveHead(); delete pInfo; }}voidXMLConfig::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; }}voidXMLConfig::_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 ++; }}voidXMLConfig::_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; }}intXMLConfig::_PropExists(XMLConfigString* p, IHXRegistry2* preg){ return (preg->GetPropStatusByName(p->CharStar()) == HXR_OK) ? TRUE : FALSE;}/* * IHXRegConfig::WriteKey */STDMETHODIMPXMLConfig::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_RESULTXMLConfig::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_RESULTXMLConfig::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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -