bool TickDbClassDescriptorImpl::fromXML()

in src/dxapi/native/tickdb/http/xml/tickdb_class_descriptor.cpp [39:109]


bool TickDbClassDescriptorImpl::fromXML(XMLElement *root, bool parseFields)
{
    if (!parse(className, getText(root, "name"))) {
        className.clear();
        // We now allow unnamed message types and bind them to name ""
    }

    if (!parse(guid, getText(root, "guid"))) {
        return false;
    }

    const char *parentGuid = getText(root, "parent");
    const char *classType = root->Attribute("xsi:type");

    this->parentGuid = NULL != parentGuid ? parentGuid : "";

    // Try to calculate enum size by checking all its values
    if (0 == _strcmpi(classType, "enumclass")) {
        unsigned enumSizeMax = 0;

        FOR_XML_ELEMENTS(root, value, "value") {
            const char *enumValue = getText(value, "value");
            if (NULL != enumValue) {
                int64 x = strtoll(enumValue, NULL, 10);
                unsigned enumSize = x < INT32_MIN || x > INT32_MAX ? 3 : x < INT16_MIN || x > INT16_MAX ? 2 : x < INT8_MIN || x > INT8_MAX ? 1 : 0;
                enumSizeMax = max(enumSizeMax, enumSize);

                const char *symbol = getText(value, "symbol");
                if (NULL != symbol) {
                    if (x < 0 || x > 2048) {
                        THROW_DBGLOG("Invalid enum value: %lld. Valid range [0, 2048].", (long long)x);
                    }

                    string symbol_str = symbol;
                    symbolToEnumValue[symbol_str] = (int32_t)x;
                    while (enumSymbols.size() <= (size_t)x) {
                        enumSymbols.emplace_back("");
                    }

                    enumSymbols[x] = symbol_str;
                }
            }
        }

        enumType = FieldType::fromInt((int)FieldType::ENUM8 + enumSizeMax);
    }
    else if (0 == _strcmpi(classType, "recordclass")) {
        // TODO: Use reference to enum class to set field type
        if (parseFields) {
            FOR_XML_ELEMENTS(root, field, "field") {
                const char *ftype = field->Attribute("xsi:type");
                if (NULL != ftype && 0 == strcmp("nonStaticDataField", ftype)) {
                    FieldInfo f;

                    if (parse(f.name, getText(field, "name"))) {
                        XMLElement * fieldTypeElement = field->FirstChildElement("type");
                        parseDataType(f.dataType, fieldTypeElement);

                        parse(f.relativeTo, getText(field, "relativeTo"));
                        fields.push_back(f);
                    }
                }
            }
        }
    }
    else {
        THROW_DBGLOG("TickDbClassDescriptor::fromXML(): Unknown class type: %192s", classType);
    }

    return true;
}