HRESULT XmlProfileParser::_ParseDistribution()

in XmlProfileParser/XmlProfileParser.cpp [1221:1313]


HRESULT XmlProfileParser::_ParseDistribution(IXMLDOMNode *pXmlNode, Target *pTarget)
{
    HRESULT hr = S_OK;

    for (auto& type : distributionTypes)
    {
        CComPtr<IXMLDOMNodeList> spNodeList = nullptr;
        CComVariant query(type.xPath);
        hr = pXmlNode->selectNodes(query.bstrVal, &spNodeList);
        if (SUCCEEDED(hr))
        {
            long cNodes;
            hr = spNodeList->get_length(&cNodes);
            if (SUCCEEDED(hr) && cNodes != 0)
            {
                UINT64 targetBase = 0, targetSpan;
                UINT32 ioBase = 0, ioSpan;
                vector<DistributionRange> v;

                for (int i = 0; i < cNodes; i++)
                {
                    // target span from the element
                    // note that this is the same 64bit int for both distribution types,
                    // it is the interpretation at the time the effective is calculated
                    // that makes the distinction. XSD covers range validations.
                    CComPtr<IXMLDOMNode> spNode = nullptr;
                    hr = spNodeList->get_item(i, &spNode);
                    if (SUCCEEDED(hr))
                    {
                        BSTR bstrText;
                        hr = spNode->get_text(&bstrText);
                        if (SUCCEEDED(hr))
                        {
                            targetSpan = _wtoi64((wchar_t *)bstrText);
                            SysFreeString(bstrText);
                        }
                    }

                    if (SUCCEEDED(hr))
                    {
                        // io span from the attribute
                        CComPtr<IXMLDOMNamedNodeMap> spNamedNodeMap = nullptr;
                        CComBSTR attr("IO");
                        hr = spNode->get_attributes(&spNamedNodeMap);
                        if (SUCCEEDED(hr) && (hr != S_FALSE))
                        {
                            CComPtr<IXMLDOMNode> spAttrNode = nullptr;
                            HRESULT hr = spNamedNodeMap->getNamedItem(attr, &spAttrNode);
                            if (SUCCEEDED(hr) && (hr != S_FALSE))
                            {
                                BSTR bstrText;
                                hr = spAttrNode->get_text(&bstrText);
                                if (SUCCEEDED(hr))
                                {
                                    ioSpan = _wtoi((wchar_t *)bstrText);
                                    SysFreeString(bstrText);
                                }
                            }
                        }
                    }

                    if (SUCCEEDED(hr) && (hr != S_FALSE))
                    {
                        v.emplace_back(ioBase, ioSpan,
                             make_pair(targetBase, targetSpan));
                        ioBase += ioSpan;
                        targetBase += targetSpan;
                    }
                    // failed during parse
                    else
                    {
                        break;
                    }

                    //
                    // Note that we are aware here whether we got to 100% IO specification.
                    // This validation is delayed to the common path for XML/cmdline.
                    //
                }

                if (SUCCEEDED(hr) && (hr != S_FALSE))
                {                    
                    pTarget->SetDistributionRange(v, type.t);
                }
                     
                // if we parsed into the element, we are done (success or failure) - only one type is possible.
                return hr;
            }
        }
    }

    return hr;
}