std::unique_ptr JSON_Parser::_ParseObject()

in Include/json_cpp/details/json_parsing.hpp [965:1038]


std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn)
{
    auto obj = utility::details::make_unique<web::json::details::_Object>(g_keep_json_object_unsorted);
    auto& elems = obj->m_object.m_elements;

    GetNextToken(tkn);
    if (tkn.m_error) goto error;

    if (tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace)
    {
        while (true)
        {
            // State 1: New field or end of object, looking for field name or closing brace
            std::basic_string<CharType> fieldName;
            switch (tkn.kind)
            {
            case JSON_Parser<CharType>::Token::TKN_StringLiteral:
                fieldName = std::move(tkn.string_val);
                break;
            default:
                goto error;
            }

            GetNextToken(tkn);
            if (tkn.m_error) goto error;

            // State 2: Looking for a colon.
            if (tkn.kind != JSON_Parser<CharType>::Token::TKN_Colon) goto done;

            GetNextToken(tkn);
            if (tkn.m_error) goto error;

            // State 3: Looking for an expression.
#ifdef ENABLE_JSON_VALUE_VISUALIZER
            auto fieldValue = _ParseValue(tkn);
            auto type = fieldValue->type();
            elems.emplace_back(utility::conversions::to_string_t(std::move(fieldName)), json::value(std::move(fieldValue), type));
#else
            elems.emplace_back(utility::conversions::to_string_t(std::move(fieldName)), json::value(_ParseValue(tkn)));
#endif
            if (tkn.m_error) goto error;

            // State 4: Looking for a comma or a closing brace
            switch (tkn.kind)
            {
            case JSON_Parser<CharType>::Token::TKN_Comma:
                GetNextToken(tkn);
                if (tkn.m_error) goto error;
                break;
            case JSON_Parser<CharType>::Token::TKN_CloseBrace:
                goto done;
            default:
                goto error;
            }
        }
    }

done:
    GetNextToken(tkn);
    if (tkn.m_error) return utility::details::make_unique<web::json::details::_Null>();

    if (!g_keep_json_object_unsorted) {
        ::std::sort(elems.begin(), elems.end(), json::object::compare_pairs);
    }

    return std::move(obj);

error:
    if (!tkn.m_error)
    {
        SetErrorCode(tkn, json_error::malformed_object_literal);
    }
    return utility::details::make_unique<web::json::details::_Null>();
}