bool Formatter::WriteProperties()

in src/vswhere.lib/Formatter.cpp [401:469]


bool Formatter::WriteProperties(_In_ ISetupPropertyStore* pProperties, _In_opt_ const wstring& prefix)
{
    _ASSERTE(pProperties);

    static ci_less less;

    LPSAFEARRAY psaNames = NULL;
    auto found = false;

    auto hr = pProperties->GetNames(&psaNames);
    if (FAILED(hr))
    {
        return false;
    }

    // Trim optional nested object name from specified property if matching current scope.
    wstring specified = Args().get_Property();
    if (prefix.size() > 0)
    {
        auto pos = specified.find_first_of(s_delims);
        if (pos != wstring::npos && (pos + 1) < specified.size() && s_comparer(prefix, specified.substr(0, pos)))
        {
            specified = specified.substr(pos + 1);
        }
        else if (s_comparer(prefix, specified))
        {
            // If the current nested object name is specified, clear the prefix to show the whole nested object.
            specified.clear();
        }
    }

    SafeArray<BSTR> saNames(psaNames);
    
    auto elems = saNames.Elements();
    sort(elems.begin(), elems.end(), less);

    for (const auto& bstrName : elems)
    {
        wstring name(bstrName);
        if (specified.empty() || (found = s_comparer(name, specified)))
        {
            variant_t vtValue;

            auto it = m_properties.end();

            // Don't check if we already handled nested properties as top-level properties.
            if (prefix.empty())
            {
                it = find_if(m_properties.begin(), m_properties.end(), bind(Formatter::PropertyEqual, name, _1));
            }

            if (it == m_properties.end())
            {
                hr = pProperties->GetValue(bstrName, vtValue.GetAddress());
                if (SUCCEEDED(hr))
                {
                    WriteProperty(name, vtValue);
                }
            }

            if (found)
            {
                return true;
            }
        }
    }

    return false;
}