Пример #1
0
static uint8_t *DeserializeCompact(DecodeState& ds, TxtNode *node, const StructMetadata *structDef)
{
    CrashIf(TextNode != node->type);
    TxtNode *structNode = StructNodeFromTextNode(ds, node, structDef);
    if (!structNode)
        return NULL;
    uint8_t *res = DeserializeRec(ds, structNode, structDef);
    FreeTxtNode(structNode);
    return res;
}
Пример #2
0
static uint8_t *DecodeStruct(DecodeState& ds, const FieldMetadata *fieldDef, TxtNode *node, bool isCompact)
{
    uint8_t *d = NULL;
    if (isCompact && (TextNode == node->type)) {
        d = DeserializeCompact(ds, node, GetStructDef(fieldDef));
    } else {
        if (StructNode == node->type)
            d = DeserializeRec(ds, node, GetStructDef(fieldDef));
    }
    return d;
}
Пример #3
0
uint8_t* Deserialize(char *data, size_t dataSize, const StructMetadata *def)
{
    if (!data)
        return NULL;

    DecodeState ds;
    ds.parser.SetToParse(data, dataSize);
    bool ok = ParseTxt(ds.parser);
    if (!ok)
        return NULL;

    return DeserializeRec(ds, ds.parser.nodes.At(0), def);
}
Пример #4
0
// data and defaultData is in text format. we might modify it in place
uint8_t* DeserializeWithDefault(char *data, size_t dataSize, char *defaultData, size_t defaultDataSize, StructMetadata *def, const char *fieldNamesSeq)
{
    if (!data)
        return NULL;

    DecodeState ds;
    ds.fieldNamesSeq = fieldNamesSeq;
    ds.parser.SetToParse(data, dataSize);
    bool ok = ParseTxt(ds.parser);
    if (!ok)
        return NULL;

    TxtNode *defaultFirstNode = NULL;
    DecodeState ds2;
    ds2.fieldNamesSeq = fieldNamesSeq;
    ds2.parser.SetToParse(defaultData, defaultDataSize);
    ok = ParseTxt(ds2.parser);
    if (ok)
        defaultFirstNode =  ds2.parser.nodes.At(0);

    return DeserializeRec(ds, ds.parser.nodes.At(0), defaultFirstNode, def);
}
Пример #5
0
static bool DecodeField(DecodeState& ds, TxtNode *firstNode, TxtNode *defaultFirstNode, FieldMetadata *fieldDef, uint8_t *structDataStart)
{
    Type type = fieldDef->type;
    uint8_t *structDataPtr = structDataStart + fieldDef->offset;

    if ((type & TYPE_NO_STORE_MASK) != 0) {
        WriteDefaultValue(structDataPtr, type);
        return true;
    }

    bool isCompact = ((type & TYPE_STORE_COMPACT_MASK) != 0);
    type = (Type)(type & TYPE_NO_FLAGS_MASK);

    const char *fieldName = ds.fieldNamesSeq + fieldDef->nameOffset;
    size_t fieldNameLen = str::Len(fieldName);
    TxtNode *dataNode = FindNode(firstNode, fieldName, fieldNameLen);
    TxtNode *defaultNode = FindNode(defaultFirstNode, fieldName, fieldNameLen);

    // if the node doesn't exist in data, try to get it from default data
    TxtNode *node = dataNode ? dataNode : defaultNode;
    if (!node) {
        WriteDefaultValue(structDataPtr, type);
        return true;
    }
    bool ok;
    if (TYPE_BOOL == type) {
        bool bVal;
        ok = ParseBool(node->valStart, node->valEnd, &bVal);
        if (!ok)
            return false;
        WriteStructBool(structDataPtr, bVal);
    } else if (TYPE_COLOR == type) {
        COLORREF val;
        ok = ParseColor(node->valStart, node->valEnd, &val);
        if (ok)
            WriteStructUInt(structDataPtr, TYPE_COLOR, val);
    } else if (IsUnsignedIntType(type)) {
        uint64_t n;
        ok = ParseUInt(node->valStart, node->valEnd, &n);
        if (ok)
            ok = WriteStructUInt(structDataPtr, type, n);
    } else if (IsSignedIntType(type)) {
        int64_t n;
        ok = ParseInt(node->valStart, node->valEnd, &n);
        if (ok)
            ok = WriteStructInt(structDataPtr, type, n);
    } else if (TYPE_STRUCT_PTR == type) {
        uint8_t *d = NULL;
        if (isCompact && (TextNode == node->type)) {
            d = DeserializeCompact(ds, node, defaultNode, fieldDef->def);
        } else {
            if (StructNode != node->type)
                return false;
            d = DeserializeRec(ds, node, defaultNode, fieldDef->def);
        }
        if (!d)
            goto Error;
        WriteStructPtrVal(structDataPtr, d);
    } else if (TYPE_STR == type) {
        char *s = node->valStart;
        size_t sLen = node->valEnd - s;
        if (s && (sLen > 0)) {
            // note: we don't free s because it's remembered in structDataPtr
            s = str::DupN(s, sLen);
            WriteStructStr(structDataPtr, s);
        }
    } else if (TYPE_WSTR == type) {
        char *s = node->valStart;
        size_t sLen = node->valEnd - s;
        if (s && (sLen > 0)) {
            // note: we don't free ws because it's remembered in structDataPtr
            WCHAR *ws = str::conv::FromUtf8(s);
            WriteStructWStr(structDataPtr, ws);
        }
    }  else if (TYPE_FLOAT == type) {
        float f;
        ok = ParseFloat(node->valStart, node->valEnd, &f);
        if (ok)
            WriteStructFloat(structDataPtr, f);
    } else if (TYPE_ARRAY == type) {
        CrashIf(!fieldDef->def); // array elements must be a struct
        if (StructNode != node->type)
            return false;
        TxtNode *child;
        ListNode<void> *last = NULL;
        for (size_t i = 0; i < node->children->Count(); i++) {
            child = node->children->At(i);
            if (ArrayNode != child->type)
                return false;
            uint8_t *d = DeserializeRec(ds, child, NULL, fieldDef->def);
            if (!d)
                goto Error; // TODO: free root
            ListNode<void> *tmp = AllocArray<ListNode<void>>(1);
            tmp->val = (void*)d;
            if (!last) {
                // this is root
                last = tmp;
                // we remember it so that it gets freed in case of error
                WriteStructPtrVal(structDataPtr, (void*)last);
            } else {
                last->next = tmp;
                last = tmp;
            }
        }
    } else {
        CrashIf(true);
        return false;
    }
    return true;
Error:
    return false;
}
Пример #6
0
uint8_t* Deserialize(struct TxtNode *root, const StructMetadata *def)
{
    DecodeState ds;
    return DeserializeRec(ds, root, def);
}