std::wstring CXmlNode::GetAttribute(LPCTSTR lpAttributeName) { IXMLDOMNamedNodeMap* lpNamedNodeMap; IXMLDOMNode* lpXMLNode; BSTR bstrValue; std::wstring strValue; HRESULT hr; if (NULL == lpAttributeName || NULL == m_pXMLNode) return _T(""); lpNamedNodeMap = NULL; hr = m_pXMLNode->get_attributes(&lpNamedNodeMap); if (hr == S_OK) { lpXMLNode = NULL; hr = lpNamedNodeMap->getNamedItem((WCHAR *)lpAttributeName, &lpXMLNode); if (hr == S_OK) { hr = lpXMLNode->get_text(&bstrValue); if (hr == S_OK) { strValue = (WCHAR *)bstrValue; ::SysFreeString(bstrValue); } lpXMLNode->Release(); } lpNamedNodeMap->Release(); } return strValue; }
/* Function name : CXML::CreateTextNode Description : This helper function create an attribute to the node supplied as argumnet Return type : bool Argument : IXMLDOMNode **pParentNode Argument : CString csAttribute Argument : CString csValue */ bool CXML::RemoveAttributeNode(IXMLDOMNode **pParentNode,CString csAttribute) { IXMLDOMNode * pNode = NULL; if(csAttribute.IsEmpty()) return false; if(!(*pParentNode)) return false; IXMLDOMNamedNodeMap * pAttributes = NULL; m_hr = (*pParentNode)->get_attributes(&pAttributes); if(!SUCCEEDED(m_hr) || !pAttributes) return false; IXMLDOMNode *pRemovedNode = NULL; _bstr_t bstrAttribute(csAttribute); m_hr = pAttributes->removeNamedItem(bstrAttribute,&pRemovedNode); pAttributes->Release(); if(!SUCCEEDED(m_hr) || !pRemovedNode) return false; pRemovedNode->Release(); return true; }
bool CXML::GetNodeAttributeValue(IXMLDOMNode ** ppNode,CString csAttributeName,CString &rcsValue) { IXMLDOMNode *pNodeAttribute = NULL; IXMLDOMNamedNodeMap *pNodeMap = NULL; CString csTemp; if(!ppNode || !(*ppNode)) return false; m_hr = (*ppNode)->get_attributes(&pNodeMap); if (SUCCEEDED(m_hr) == 0 || pNodeMap == NULL) return false; _bstr_t bstrAttributeName(csAttributeName); m_hr = pNodeMap->getNamedItem (bstrAttributeName,&pNodeAttribute); pNodeMap->Release(); if (SUCCEEDED(m_hr) == 0 || (pNodeAttribute == NULL)) return false; _variant_t vtAttributeVal; m_hr = pNodeAttribute->get_nodeValue(&vtAttributeVal); pNodeAttribute->Release(); if (SUCCEEDED(m_hr) == 0) return false; rcsValue = vtAttributeVal.bstrVal; return true; }
/////////////////////////////////////////////////////// // RADEventsXML::ConstructEventNode // // Creates an XMLEvent node from a RADEvent object // // An example XML node as text: // <Event num="0057" // starttime="0000020010826175602000" endtime="0000020010826175827000" // maxtime="0000020010826175702000" // sum="10941.0" maxvalue="84" // starttimedisplay="2001.08.26 - 17:56:02" // endtimedisplay="2001.08.26 - 17:58:27" // maxtimedisplay="2001.08.26 - 17:57:02" // etype="Channel" // stationname="GRAND 2" /> // // Note: the text attribute values are created from the strings // on the RADEvent object. // // Input: // pEvent - the RADEvent instance // // Returns: // IXMLDOMElement: the constructed Event node, // or a NULL pointer if processing failed. // /////////////////////////////////////////////////////// IXMLDOMElement* RADEventsXML::ConstructEventNode(RADEvent* pEvent) { IXMLDOMElement *pEventElement = NULL; _variant_t var1; _bstr_t bstr1; HRESULT hr; IXMLDOMAttribute *pAttNode=NULL; IXMLDOMNode *pIXMLDOMNode=NULL; IXMLDOMNamedNodeMap* pAttMap = NULL; int j; // construct <Event> bstr1 = "Event"; HRCALL(m_pXMLDom->createElement(bstr1,&pEventElement),"create <Event> "); HRCALL(pEventElement->get_attributes(&pAttMap), "get_attributes: "); for (j = 0; j < eRADAttMax; j++) { var1 = pEvent->values[j]; HRCALL(m_pXMLDom->createAttribute(atts[j], &pAttNode), "create attribute"); HRCALL(pAttNode->put_nodeValue(var1), "node value"); HRCALL(pAttMap->setNamedItem(pAttNode, &pIXMLDOMNode), "set named item"); if (pIXMLDOMNode) pIXMLDOMNode->Release(); } clean: if (pAttMap) pAttMap->Release(); if (pAttNode) pAttNode->Release(); return pEventElement; }
/////////////////////////////////////////////////////// // RADEventsXML::XMLToEvent // // Populates a RADEvent object with string and typed values // from the XML Event node attributes. The RADEvent class declares // the string-to-type conversion operations, per field. The XML node // attribute values are placed on the RADEvent as strings, without // modification from the XML. // // Input: // pEvent - the RADEvent instance // /////////////////////////////////////////////////////// RADEvent* RADEventsXML::XMLToEvent(IXMLDOMNode* pEvent) { HRESULT hr; RADEvent* p = NULL; IXMLDOMNode *pAtt=NULL; IXMLDOMNamedNodeMap* pat = NULL; long l; int al; HRCALL(pEvent->get_attributes(&pat), "get_attributes: "); HRCALL(pat->get_length(&l), "get_length: "); ASSERT(l <= (int)eRADAttMax); p = new RADEvent(); for (al = 0; al < l; al++) { HRCALL(pat->getNamedItem(atts[al], &pAtt), "gni"); if (pAtt) { VARIANT varValue; ::VariantInit(&varValue); pAtt->get_nodeValue(&varValue); p->SetREValue((RADEventField)al, varValue.bstrVal); ::VariantClear(&varValue); pAtt->Release(); } } clean: if (pat) pat->Release(); return p; }
bool SettingsXML::SetAttr(IXMLDOMNode* apNode, const wchar_t* asName, const wchar_t* asValue) { bool lbRc = false; HRESULT hr = S_OK; IXMLDOMNamedNodeMap* pAttrs = NULL; hr = apNode->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { lbRc = SetAttr(apNode, pAttrs, asName, asValue); pAttrs->Release(); pAttrs = NULL; } return lbRc; }
BSTR SettingsXML::GetAttr(IXMLDOMNode* apNode, const wchar_t* asName) { HRESULT hr = S_OK; BSTR bsValue = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; hr = apNode->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsValue = GetAttr(apNode, pAttrs, asName); pAttrs->Release(); pAttrs = NULL; } return bsValue; }
//-------------------------------------------------------------------------------------- BOOL ConfGetNodeAttributeW(IXMLDOMNode *pIDOMNode, PWSTR name, PWSTR *value) { BOOL bRet = FALSE; IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL; // query attributes map HRESULT hr = pIDOMNode->get_attributes(&pIXMLDOMNamedNodeMap); if (SUCCEEDED(hr) && pIXMLDOMNamedNodeMap) { IXMLDOMNode *pIDOMAttrNode = NULL; // query attribute node hr = pIXMLDOMNamedNodeMap->getNamedItem(name, &pIDOMAttrNode); if (SUCCEEDED(hr) && pIDOMAttrNode) { VARIANT varValue; hr = pIDOMAttrNode->get_nodeValue(&varValue); if (FAILED(hr)) { DbgMsg(__FILE__, __LINE__, "pIDOMAttrNode->get_nodeValue() ERROR 0x%.8x\n", hr); goto free; } BSTR val = _bstr_t(varValue); DWORD Len = (wcslen((PWSTR)val) + 1) * sizeof(WCHAR); if (*value = (PWSTR)M_ALLOC(Len)) { ZeroMemory(*value, Len); wcscpy(*value, (PWSTR)val); bRet = TRUE; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError()); } free: pIDOMAttrNode->Release(); pIDOMAttrNode = NULL; } pIXMLDOMNamedNodeMap->Release(); pIXMLDOMNamedNodeMap = NULL; } return bRet; }
/* Function name : CXML::CreateAttributeNode Description : Return type : bool Argument : IXMLDOMNode **pParentNode Argument : CString csAttribute Argument : CString csValue Tested : Ok */ bool CXML::CreateAttributeNode(IXMLDOMNode **pParentNode,CString csAttribute,CString csValue) { IXMLDOMNode * pNode = NULL; if(csAttribute.IsEmpty()) return false; if(!(*pParentNode)) return false; _variant_t vtNodeType((long)NODE_ATTRIBUTE); _bstr_t bstrName(csAttribute); _bstr_t bstrNameSpace(""); m_hr = m_pXMLDoc->createNode(vtNodeType,bstrName,bstrNameSpace,&pNode); if(!SUCCEEDED(m_hr)) return false; IXMLDOMNamedNodeMap * pAttributes = NULL; m_hr = (*pParentNode)->get_attributes(&pAttributes); if(!SUCCEEDED(m_hr) || !pAttributes) { pNode->Release(); return false; } IXMLDOMNode *pNewNode = NULL; m_hr = pAttributes->setNamedItem(pNode,&pNewNode); pNode->Release(); pAttributes->Release(); if(!SUCCEEDED(m_hr) || !pNewNode) return false; _variant_t vtValue(csValue); m_hr = pNewNode->put_nodeValue(vtValue); pNewNode->Release(); if(!SUCCEEDED(m_hr) || !pNewNode) return false; return true; }
/****************************************************************************** Function Name : vRetrieveConditionSignalValue Input(s) : IXMLDOMNode* pIDOMSChildSignal CSignalCondition& ouSignalCondition Output : void Functionality : Retrieves the Signal Info from the pIDOMSChildSignal Member of : CVerify_MessageEntity Friend of : - Author(s) : Venkatanarayana Makam Date Created : 06/04/2011 Modifications : ******************************************************************************/ void CVerify_MessageEntity::vRetrieveConditionSignalValue(IXMLDOMNode* pIDOMSChildSignal, CSignalCondition& ouSignalCondition) { CComBSTR bstrNodeName = L"name"; CComVariant NodeValue; CString omstrTemp; IXMLDOMNamedNodeMap* pIDOMAttributes; IXMLDOMNode* pIDOMChildNode; pIDOMSChildSignal->get_attributes(&pIDOMAttributes); pIDOMAttributes->getNamedItem(bstrNodeName, &pIDOMChildNode); pIDOMChildNode->get_nodeTypedValue(&NodeValue); ouSignalCondition.m_omSigName = strCopyBSTRToCString(NodeValue); pIDOMChildNode->Release(); pIDOMAttributes->Release(); pIDOMSChildSignal->get_nodeTypedValue(&NodeValue); ouSignalCondition.m_omCondition = strCopyBSTRToCString(NodeValue); ouSignalCondition.m_omCondition.Remove('\"'); }
bool CXML::HasAttributes() { if(!m_pICurrentNode) return false; IXMLDOMNamedNodeMap * pAttributeMap = 0; m_hr = m_pICurrentNode->get_attributes(&pAttributeMap); if (!SUCCEEDED(m_hr)) return false; long nCount = 0; m_hr = pAttributeMap->get_length(&nCount); pAttributeMap->Release(); if (!SUCCEEDED(m_hr)) return false; return nCount != 0; }
void lvDCOMInterface::getParams(std::map<std::string,std::string>& res) { res.clear(); char control_name_xpath[MAX_PATH_LEN]; _snprintf(control_name_xpath, sizeof(control_name_xpath), "/lvinput/section[@name='%s']/vi/param", m_configSection.c_str()); IXMLDOMNodeList* pXMLDomNodeList = NULL; HRESULT hr = m_pxmldom->selectNodes(_bstr_t(control_name_xpath), &pXMLDomNodeList); if (FAILED(hr) || pXMLDomNodeList == NULL) { return; } IXMLDOMNode *pNode, *pAttrNode1, *pAttrNode2; long n = 0; pXMLDomNodeList->get_length(&n); for(long i=0; i<n; ++i) { pNode = NULL; hr = pXMLDomNodeList->get_item(i, &pNode); if (SUCCEEDED(hr) && pNode != NULL) { IXMLDOMNamedNodeMap *attributeMap = NULL; pAttrNode1 = pAttrNode2 = NULL; pNode->get_attributes(&attributeMap); hr = attributeMap->getNamedItem(_bstr_t("name"), &pAttrNode1); hr = attributeMap->getNamedItem(_bstr_t("type"), &pAttrNode2); BSTR bstrValue1 = NULL, bstrValue2 = NULL; hr=pAttrNode1->get_text(&bstrValue1); hr=pAttrNode2->get_text(&bstrValue2); res[std::string(COLE2CT(bstrValue1))] = COLE2CT(bstrValue2); SysFreeString(bstrValue1); SysFreeString(bstrValue2); pAttrNode1->Release(); pAttrNode2->Release(); attributeMap->Release(); pNode->Release(); } } pXMLDomNodeList->Release(); }
//void SettingsXML::Save(const wchar_t *regName, const wchar_t *value) //{ // if (!value) value = L""; // сюда мог придти и NULL // // Save(regName, (LPCBYTE)value, REG_SZ, (_tcslen(value)+1)*sizeof(wchar_t)); //} void SettingsXML::Save(const wchar_t *regName, LPCBYTE value, DWORD nType, DWORD nSize) { HRESULT hr = S_OK; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMNodeList* pList = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pNode = NULL; IXMLDOMNode* pChild = NULL; IXMLDOMNode *pNodeRmv = NULL; BSTR bsValue = NULL; BSTR bsType = NULL; bool bNeedSetType = false; // nType: // REG_DWORD: сохранение числа в 16-ричном или 10-чном формате, в зависимости от того, что сейчас указано в xml ("dword"/"ulong"/"long") // REG_BINARY: строго в hex (FF,FF,...) // REG_SZ: ASCIIZ строка, можно проконтролировать, чтобы nSize/2 не был меньше длины строки // REG_MULTI_SZ: ASCIIZZ. При формировании <list...> нужно убедиться, что мы не вылезли за пределы nSize pChild = FindItem(mp_Key, L"value", regName, true); // создать, если его еще нету if (!pChild) goto wrap; hr = pChild->get_attributes(&pAttrs); if (FAILED(hr) || !pAttrs) goto wrap; bsType = GetAttr(pChild, pAttrs, L"type"); switch (nType) { case REG_DWORD: { wchar_t szValue[32]; if (bsType && (bsType[0] == L'u' || bsType[0] == L'U')) { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", *(LPDWORD)value); } else if (bsType && (bsType[0] == L'l' || bsType[0] == L'L')) { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", *(int*)value); } else { _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%08x", *(LPDWORD)value); if (bsType) ::SysFreeString(bsType); // нужно добавить/установить тип bsType = ::SysAllocString(L"dword"); bNeedSetType = true; } bsValue = ::SysAllocString(szValue); } break; case REG_BINARY: { if (nSize == 1 && bsType && (bsType[0] == L'u' || bsType[0] == L'U')) { wchar_t szValue[4]; BYTE bt = *value; _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", (DWORD)bt); bsValue = ::SysAllocString(szValue); } else if (nSize == 1 && bsType && (bsType[0] == L'l' || bsType[0] == L'L')) { wchar_t szValue[4]; char bt = *value; _wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", (int)bt); bsValue = ::SysAllocString(szValue); } else { DWORD nLen = nSize*2 + (nSize-1); // по 2 символа на байт + ',' между ними bsValue = ::SysAllocStringLen(NULL, nLen); nLen ++; // Чтобы далее не добавлять WCHAR на '\0' wchar_t* psz = (wchar_t*)bsValue; LPCBYTE ptr = value; while (nSize) { _wsprintf(psz, SKIPLEN(nLen-(psz-bsValue)) L"%02x", (DWORD)*ptr); ptr++; nSize--; psz+=2; if (nSize) *(psz++) = L','; } if (bsType && lstrcmp(bsType, L"hex")) { // Допустим только "hex" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"hex"); bNeedSetType = true; } } } break; case REG_SZ: { wchar_t* psz = (wchar_t*)value; bsValue = ::SysAllocString(psz); if (bsType && lstrcmp(bsType, L"string")) { // Допустим только "string" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"string"); bNeedSetType = true; } } break; case REG_MULTI_SZ: { if (bsType && lstrcmp(bsType, L"multi")) { // Допустим только "multi" ::SysFreeString(bsType); bsType = NULL; } if (!bsType) { // нужно добавить/установить тип bsType = ::SysAllocString(L"multi"); bNeedSetType = true; } } break; default: goto wrap; // не поддерживается } if (bNeedSetType) { _ASSERTE(bsType!=NULL); SetAttr(pChild, pAttrs, L"type", bsType); ::SysFreeString(bsType); bsType = NULL; } // Теперь собственно значение if (nType != REG_MULTI_SZ) { _ASSERTE(bsValue != NULL); SetAttr(pChild, pAttrs, L"data", bsValue); ::SysFreeString(bsValue); bsValue = NULL; } else // Тут нужно формировать список элементов <list> { // Если ранее был параметр "data" - удалить его из списка атрибутов hr = pAttrs->getNamedItem(L"data", &pNode); if (SUCCEEDED(hr) && pNode) { hr = pChild->removeChild(pNode, &pNodeRmv); pNode->Release(); pNode = NULL; SetDataChanged(); if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } } long nAllLen = nSize/2; // длина в wchar_t wchar_t* psz = (wchar_t*)value; SetMultiLine(pChild, psz, nAllLen); } mb_Modified = true; wrap: if (pIXMLDOMAttribute) { pIXMLDOMAttribute->Release(); pIXMLDOMAttribute = NULL; } if (pNode) { pNode->Release(); pNode = NULL; } if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; } if (pChild) { pChild->Release(); pChild = NULL; } if (pAttrs) { pAttrs->Release(); pAttrs = NULL; } if (bsValue) { ::SysFreeString(bsValue); bsValue = NULL; } if (bsType) { ::SysFreeString(bsType); bsType = NULL; } }
/**Read the XML config file. Currently contains keyboard choices.*/ void read_config_file() { TrainerConfig *result = new TrainerConfig(); CoInitialize(NULL); //read XML MSXML2::IXMLDOMDocumentPtr spXMLDoc; spXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60)); if (!spXMLDoc->load("ent-config.xml")) { write_text_to_log_file("No config found, using defaults"); config = result; //the default config } IXMLDOMNodeListPtr nodes = spXMLDoc->selectNodes(L"//ent-config/keys/key"); long length; nodes->get_length(&length); for (int i = 0; i < length; i++) { IXMLDOMNode *node; nodes->get_item(i, &node); IXMLDOMNamedNodeMap *attribs; node->get_attributes(&attribs); long length_attribs; attribs->get_length(&length_attribs); char *attrib_key_func = NULL; char *attrib_key_value = NULL; for (long j = 0; j < length_attribs; j++) { IXMLDOMNode *attribNode; attribs->get_item(j, &attribNode); attribNode->get_nodeName(&bstr); if (wcscmp(bstr, L"function") == 0) { VARIANT var; VariantInit(&var); attribNode->get_nodeValue(&var); attrib_key_func = _com_util::ConvertBSTRToString(V_BSTR(&var)); } else if (wcscmp(bstr, L"value") == 0) { VARIANT var; VariantInit(&var); attribNode->get_nodeValue(&var); attrib_key_value = _com_util::ConvertBSTRToString(V_BSTR(&var)); } SysFreeString(bstr); attribNode->Release(); } if (attrib_key_func != NULL && attrib_key_value != NULL) { result->get_key_config()->set_key(attrib_key_func, attrib_key_value); } delete attrib_key_func; delete attrib_key_value; attribs->Release(); node->Release(); } //nodes->Release(); //don't do this, it crashes on exit spXMLDoc.Release(); CoUninitialize(); config = result; }
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate) { HRESULT hr = S_OK; IXMLDOMNodeList* pList = NULL; IXMLDOMNode* pChild = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pIXMLDOMNode = NULL; IXMLDOMNode *pName = NULL; BSTR bsText = NULL; BSTR bsCheck = NULL; DOMNodeType nodeTypeCheck = NODE_INVALID; BOOL lbEmpty = TRUE; int iLastIndent = 1; // Получить все дочерние элементы нужного типа if (apFrom == NULL) { hr = S_FALSE; } else { long lFound = 0; // key[@name="abc"], but it is case-sensitive, and may fails in theory bsText = lstrmerge(asType, L"[@name=\"", asName, L"\"]"); hr = apFrom->selectNodes(bsText, &pList); if (SUCCEEDED(hr) && pList) { hr = pList->get_length(&lFound); if (FAILED(hr) || (lFound < 1)) { SafeRelease(pList); } } SafeFree(bsText); // May be case-insensitive search will be succeeded? // However, it is very slow if (!pList) { bsText = ::SysAllocString(asType); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; } } if (SUCCEEDED(hr) && pList) { hr = pList->reset(); while ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; hr = pIXMLDOMNode->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name"); if (bsText) { if (lstrcmpi(bsText, asName) == 0) { ::SysFreeString(bsText); bsText = NULL; pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; break; } ::SysFreeString(bsText); bsText = NULL; } } pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } if (lbEmpty && abAllowCreate && (asType[0] == L'k')) { bsText = ::SysAllocString(L"value"); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pList) { hr = pList->reset(); if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } } if (!pChild && abAllowCreate) { if (asType[0] == L'k') { hr = apFrom->get_lastChild(&pChild); if (SUCCEEDED(hr) && pChild) { hr = pChild->get_nodeType(&nodeTypeCheck); if (SUCCEEDED(hr) && (nodeTypeCheck == NODE_TEXT)) { hr = pChild->get_text(&bsCheck); if (SUCCEEDED(hr) && bsCheck) { iLastIndent = 0; LPCWSTR pszTabs = bsCheck; while (*pszTabs) { if (*(pszTabs++) == L'\t') iLastIndent++; } ::SysFreeString(bsCheck); bsCheck = NULL; } } } SafeRelease(pChild); } VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT; bsText = ::SysAllocString(asType); hr = mp_File->createNode(vtType, bsText, L"", &pChild); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pChild) { if (SetAttr(pChild, L"name", asName)) { if (asType[0] == L'k') { AppendNewLine(pChild); mb_KeyEmpty = true; TouchKey(pChild); } if (asType[0] == L'k') { //if (mb_KeyEmpty) //AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level); AppendIndent(apFrom, (mi_Level-iLastIndent)); } else if (mb_KeyEmpty) { AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level); } else { AppendIndent(apFrom, 1); } hr = apFrom->appendChild(pChild, &pIXMLDOMNode); pChild->Release(); pChild = NULL; if (FAILED(hr)) { pAttrs->Release(); pAttrs = NULL; } else { pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; } AppendNewLine(apFrom); AppendIndent(apFrom, mi_Level-1); if ((asType[0] != L'k') && mb_KeyEmpty) mb_KeyEmpty = false; } else { pChild->Release(); pChild = NULL; } } } return pChild; }
// эта функция, если значения нет (или тип некорректный) *value НЕ трогает bool SettingsXML::Load(const wchar_t *regName, wchar_t **value) { bool lbRc = false; HRESULT hr = S_OK; IXMLDOMNode* pChild = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pNode = NULL; IXMLDOMNodeList* pList = NULL; BSTR bsType = NULL; BSTR bsData = NULL; size_t nLen = 0; //if (*value) {free(*value); *value = NULL;} if (mp_Key) pChild = FindItem(mp_Key, L"value", regName, false); if (!pChild) return false; hr = pChild->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsType = GetAttr(pChild, pAttrs, L"type"); } if (SUCCEEDED(hr) && bsType) { if (!lstrcmpi(bsType, L"multi")) { // Тут значения хранятся так: //<value name="CmdLineHistory" type="multi"> // <line data="C:\Far\Far.exe"/> // <line data="cmd"/> //</value> wchar_t *pszData = NULL, *pszCur = NULL; size_t nMaxLen = 0, nCurLen = 0; long nCount = 0; if (pAttrs) { pAttrs->Release(); pAttrs = NULL; } // Получить все дочерние элементы нужного типа bsData = ::SysAllocString(L"line"); hr = pChild->selectNodes(bsData, &pList); ::SysFreeString(bsData); bsData = NULL; if (SUCCEEDED(hr) && pList) { hr = pList->get_length(&nCount); if (SUCCEEDED(hr) && (nCount > 0)) { HEAPVAL; nMaxLen = ((MAX_PATH+1) * nCount) + 1; pszData = (wchar_t*)malloc(nMaxLen * sizeof(wchar_t)); pszCur = pszData; pszCur[0] = 0; pszCur[1] = 0; nCurLen = 2; // сразу посчитать DoubleZero HEAPVAL; } } if (SUCCEEDED(hr) && pList) { hr = pList->reset(); while ((hr = pList->nextNode(&pNode)) == S_OK && pNode) { bsData = GetAttr(pNode, L"data"); pNode->Release(); pNode = NULL; if (SUCCEEDED(hr) && bsData) { nLen = _tcslen(bsData) + 1; if ((nCurLen + nLen) > nMaxLen) { // Нужно пересоздать! nMaxLen = nCurLen + nLen + MAX_PATH + 1; wchar_t *psz = (wchar_t*)malloc(nMaxLen * sizeof(wchar_t)); _ASSERTE(psz); if (!psz) break; // Не удалось выделить память! wmemmove(psz, pszData, nCurLen); pszCur = psz + (pszCur - pszData); HEAPVAL; free(pszData); pszData = psz; HEAPVAL; } lstrcpy(pszCur, bsData); pszCur += nLen; // указатель - на место для следующей строки nCurLen += nLen; *pszCur = 0; // ASCIIZZ HEAPVAL; ::SysFreeString(bsData); bsData = NULL; } } pList->Release(); pList = NULL; } // значит что-то прочитать удалось if (pszData) { if (*value) {free(*value); *value = NULL;} *value = pszData; lbRc = true; } } else if (!lstrcmpi(bsType, L"string")) { bsData = GetAttr(pChild, pAttrs, L"data"); if (SUCCEEDED(hr) && bsData) { nLen = _tcslen(bsData); if (!*value || (_tcslen(*value) <= nLen)) { *value = (wchar_t*)realloc(*value, (nLen+2)*sizeof(wchar_t)); } if (*value) { lstrcpy(*value, bsData); (*value)[nLen] = 0; // уже должен быть после lstrcpy (*value)[nLen+1] = 0; // ASCIIZZ lbRc = true; } } } // Все остальные типы - не интересуют. Нам нужны только строки } if (bsType) { ::SysFreeString(bsType); bsType = NULL; } if (bsData) { ::SysFreeString(bsData); bsData = NULL; } if (pChild) { pChild->Release(); pChild = NULL; } if (pAttrs) { pAttrs->Release(); pAttrs = NULL; } //if (!lbRc) //{ // _ASSERTE(*value == NULL); // *value = (wchar_t*)malloc(sizeof(wchar_t)*2); // (*value)[0] = 0; (*value)[1] = 0; // На случай REG_MULTI_SZ //} return lbRc; }
void CStrokeRecognition::DecodePointFromXML(std::vector<POINT> &rgPoints, BSTR strXML) { IXMLDOMDocument* pDoc; IXMLDOMNodeList* pNodeList; IXMLDOMNode* pNode; IXMLDOMNode* pInputNode; IXMLDOMNode* pAttrNode; IXMLDOMNamedNodeMap* pNodeMap; VARIANT_BOOL bLoaded; VARIANT value; BSTR nodeName; POINT pt; long n; if (SUCCEEDED(CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (LPVOID*)&pDoc))) { pDoc->put_async(VARIANT_FALSE); pDoc->loadXML(strXML, &bLoaded); if (bLoaded == VARIANT_TRUE) { if (SUCCEEDED(pDoc->get_childNodes(&pNodeList))) { pInputNode = NULL; pNodeList->get_length(&n); for (int i = 0; i < n; i++) { if (SUCCEEDED(pNodeList->get_item(i, &pNode))) { nodeName = NULL; if (SUCCEEDED(pNode->get_nodeName(&nodeName))) { if (CComBSTR(nodeName) == L"input") { pInputNode = pNode; pInputNode->AddRef(); break; } SysFreeString(nodeName); } pNode->Release(); } } pNodeList->Release(); if (pInputNode != NULL) { if (SUCCEEDED(pInputNode->get_childNodes(&pNodeList))) { pNodeList->get_length(&n); for (int i = 0; i < n; i++) { if (SUCCEEDED(pNodeList->get_item(i, &pNode))) { pt.x = 0; pt.y = 0; if (SUCCEEDED(pNode->get_attributes(&pNodeMap))) { if (SUCCEEDED(pNodeMap->getNamedItem(L"x", &pAttrNode))) { pAttrNode->get_nodeValue(&value); pt.x = _wtoi(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"y", &pAttrNode))) { pAttrNode->get_nodeValue(&value); pt.y = _wtoi(value.bstrVal); pAttrNode->Release(); } pNodeMap->Release(); } rgPoints.push_back(pt); pNode->Release(); } } pNodeList->Release(); } pInputNode->Release(); } } } pDoc->Release(); } }
bool SettingsXML::Load(const wchar_t *regName, LPBYTE value, DWORD nSize) { bool lbRc = false; HRESULT hr = S_OK; IXMLDOMNode* pChild = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pNode = NULL; BSTR bsType = NULL; BSTR bsData = NULL; if (!value || !nSize) return false; if (mp_Key) pChild = FindItem(mp_Key, L"value", regName, false); if (!pChild) return false; hr = pChild->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsType = GetAttr(pChild, pAttrs, L"type"); } if (SUCCEEDED(hr) && bsType) { bsData = GetAttr(pChild, pAttrs, L"data"); } if (SUCCEEDED(hr) && bsData) { if (!lstrcmpi(bsType, L"string")) { #ifdef _DEBUG DWORD nLen = _tcslen(bsData) + 1; #endif DWORD nMaxLen = nSize / 2; lstrcpyn((wchar_t*)value, bsData, nMaxLen); lbRc = true; } else if (!lstrcmpi(bsType, L"ulong")) { wchar_t* pszEnd = NULL; DWORD lVal = wcstoul(bsData, &pszEnd, 10); if (nSize > 4) nSize = 4; if (pszEnd && pszEnd != bsData) { memmove(value, &lVal, nSize); lbRc = true; } } else if (!lstrcmpi(bsType, L"long")) { wchar_t* pszEnd = NULL; int lVal = wcstol(bsData, &pszEnd, 10); if (nSize > 4) nSize = 4; if (pszEnd && pszEnd != bsData) { memmove(value, &lVal, nSize); lbRc = true; } } else if (!lstrcmpi(bsType, L"dword")) { wchar_t* pszEnd = NULL; DWORD lVal = wcstoul(bsData, &pszEnd, 16); if (nSize > 4) nSize = 4; if (pszEnd && pszEnd != bsData) { memmove(value, &lVal, nSize); lbRc = true; } } else if (!lstrcmpi(bsType, L"hex")) { wchar_t* pszCur = bsData; wchar_t* pszEnd = NULL; LPBYTE pCur = value; wchar_t cHex; DWORD lVal = 0; lbRc = true; while (*pszCur && nSize) { lVal = 0; cHex = *(pszCur++); if (cHex >= L'0' && cHex <= L'9') { lVal = cHex - L'0'; } else if (cHex >= L'a' && cHex <= L'f') { lVal = cHex - L'a' + 10; } else if (cHex >= L'A' && cHex <= L'F') { lVal = cHex - L'A' + 10; } else { lbRc = false; break; } cHex = *(pszCur++); if (cHex && cHex != L',') { lVal = lVal << 4; if (cHex >= L'0' && cHex <= L'9') { lVal |= cHex - L'0'; } else if (cHex >= L'a' && cHex <= L'f') { lVal |= cHex - L'a' + 10; } else if (cHex >= L'A' && cHex <= L'F') { lVal |= cHex - L'A' + 10; } else { lbRc = false; break; } cHex = *(pszCur++); } *pCur = (BYTE)lVal; pCur++; nSize--; if (cHex != L',') { break; } } while (nSize--) // очистить хвост *(pCur++) = 0; } } // Остальные типы (строки) - не интересуют if (bsType) { ::SysFreeString(bsType); bsType = NULL; } if (bsData) { ::SysFreeString(bsData); bsData = NULL; } if (pChild) { pChild->Release(); pChild = NULL; } if (pAttrs) { pAttrs->Release(); pAttrs = NULL; } return lbRc; }
STDMETHODIMP CStrokeRecognition::put_RecognitionParam(BSTR newVal) { double Segment_Error_Threshold; double Arc_Error_Threshold; double Arc_Min_Length; double Arc_Min_Curve; double Stroke_Min_Length; double Min_Turning_Angle; double Segmentation_Penalty; VARIANT value; BSTR nodeName; long n; IXMLDOMDocument* pDoc; IXMLDOMNodeList* pNodeList; IXMLDOMNode* pNode; IXMLDOMNode* pParamNode; IXMLDOMNode* pAttrNode; IXMLDOMNamedNodeMap* pNodeMap; VARIANT_BOOL bLoaded; GetFittingParam(Segment_Error_Threshold, Arc_Error_Threshold, Arc_Min_Length, Arc_Min_Curve, Stroke_Min_Length, Min_Turning_Angle, Segmentation_Penalty); if (SUCCEEDED(CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (LPVOID*)&pDoc))) { pDoc->put_async(VARIANT_FALSE); pDoc->loadXML(newVal, &bLoaded); if (bLoaded == VARIANT_TRUE) { if (SUCCEEDED(pDoc->get_childNodes(&pNodeList))) { pParamNode = NULL; pNodeList->get_length(&n); for (int i = 0; i < n; i++) { if (SUCCEEDED(pNodeList->get_item(i, &pNode))) { nodeName = NULL; if (SUCCEEDED(pNode->get_nodeName(&nodeName))) { if (CComBSTR(nodeName) == L"param") { pParamNode = pNode; pParamNode->AddRef(); break; } SysFreeString(nodeName); } pNode->Release(); } } pNodeList->Release(); if (pParamNode != NULL) { if (SUCCEEDED(pParamNode->get_attributes(&pNodeMap))) { if (SUCCEEDED(pNodeMap->getNamedItem(L"Segment_Error_Threshold", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Segment_Error_Threshold = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Error_Threshold", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Arc_Error_Threshold = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Min_Length", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Arc_Min_Length = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Min_Curve", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Arc_Min_Curve = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Stroke_Min_Length", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Stroke_Min_Length = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Min_Turning_Angle", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Min_Turning_Angle = _wtof(value.bstrVal); pAttrNode->Release(); } if (SUCCEEDED(pNodeMap->getNamedItem(L"Segmentation_Penalty", &pAttrNode))) { pAttrNode->get_nodeValue(&value); Segmentation_Penalty = _wtof(value.bstrVal); pAttrNode->Release(); } pNodeMap->Release(); } pParamNode->Release(); } } } pDoc->Release(); } SetFittingParam(Segment_Error_Threshold, Arc_Error_Threshold, Arc_Min_Length, Arc_Min_Curve, Stroke_Min_Length, Min_Turning_Angle, Segmentation_Penalty); return S_OK; }
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate) { HRESULT hr = S_OK; IXMLDOMNodeList* pList = NULL; IXMLDOMNode* pChild = NULL; IXMLDOMNamedNodeMap* pAttrs = NULL; IXMLDOMAttribute *pIXMLDOMAttribute = NULL; IXMLDOMNode *pIXMLDOMNode = NULL; IXMLDOMNode *pName = NULL; BSTR bsText = NULL; BOOL lbEmpty = TRUE; // Получить все дочерние элементы нужного типа if (apFrom == NULL) { hr = S_FALSE; } else { bsText = ::SysAllocString(asType); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; } if (SUCCEEDED(hr) && pList) { hr = pList->reset(); while((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; hr = pIXMLDOMNode->get_attributes(&pAttrs); if (SUCCEEDED(hr) && pAttrs) { bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name"); if (bsText) { if (lstrcmpi(bsText, asName) == 0) { ::SysFreeString(bsText); bsText = NULL; pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; break; } ::SysFreeString(bsText); bsText = NULL; } } pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } if (lbEmpty && abAllowCreate && (asType[0] == L'k')) { bsText = ::SysAllocString(L"value"); hr = apFrom->selectNodes(bsText, &pList); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pList) { hr = pList->reset(); if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode) { lbEmpty = FALSE; pIXMLDOMNode->Release(); pIXMLDOMNode = NULL; } pList->Release(); //pList = NULL; -- для отладки } } if (!pChild && abAllowCreate) { VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT; bsText = ::SysAllocString(asType); hr = mp_File->createNode(vtType, bsText, L"", &pChild); ::SysFreeString(bsText); bsText = NULL; if (SUCCEEDED(hr) && pChild) { if (SetAttr(pChild, L"name", asName)) { if (asType[0] == L'k') { AppendNewLine(pChild); mb_KeyEmpty = true; } if (asType[0] == L'k') { //if (mb_KeyEmpty) //AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level); AppendIndent(apFrom, (mi_Level-1)); } else if (mb_KeyEmpty) { AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level); } else { AppendIndent(apFrom, 1); } hr = apFrom->appendChild(pChild, &pIXMLDOMNode); pChild->Release(); pChild = NULL; if (FAILED(hr)) { pAttrs->Release(); pAttrs = NULL; } else { pChild = pIXMLDOMNode; pIXMLDOMNode = NULL; } AppendNewLine(apFrom); AppendIndent(apFrom, mi_Level-1); if ((asType[0] != L'k') && mb_KeyEmpty) mb_KeyEmpty = false; } else { pChild->Release(); pChild = NULL; } } } return pChild; }