Beispiel #1
0
static cx_int16 cx_ser_reference(cx_serializer s, cx_value *info, void *userData) {
    cx_compare_ser_t *data = userData;
    void *_this = cx_valueValue(info);
    void *value = (void*)((cx_word)cx_valueValue(&data->value) + ((cx_word)_this - (cx_word)data->base));
    CX_UNUSED(s);
    
    if (*(cx_object*)_this != *(cx_object*)value) {
        data->result = CX_NEQ;
    } else {
        data->result = CX_EQ;
    }
    
    return data->result != CX_EQ;
}
Beispiel #2
0
static cx_int16 serializeText(cx_value *value, cx_string *out) {
    cx_type type = cx_valueType(value);
    cx_void *v = cx_valueValue(value);
    cx_primitiveKind kind = cx_primitive(type)->kind;
    if (kind == CX_CHARACTER || (kind == CX_TEXT && (*(cx_string *)v))) {
        cx_string raw;
        size_t length;
        int needEscape = 0;
        if (cx_convert(cx_primitive(type), v, cx_primitive(cx_string_o), &raw)) {
            goto error;
        }
        if (*raw == '@') {
            needEscape = 1;
        }
        length = stresc(NULL, 0, raw);
        *out = cx_malloc(length + 3 + needEscape);
        (*out)[0] = '"';
        (*out)[1] = '@';
        stresc(*out + 1 + needEscape, length, raw);
        (*out)[length + needEscape + 1] = '"';
        (*out)[length + needEscape + 2] = '\0';
        cx_dealloc(raw);
    } else {
        *out = cx_malloc(sizeof("null"));
        strcpy(*out, "null");
    }
    return 0;
error:
    return -1;
}
Beispiel #3
0
static cx_int16 cx_ser_construct(cx_serializer s, cx_value *info, void *userData) {
    cx_compare_ser_t *data = userData;
    cx_bool compare = FALSE;
    CX_UNUSED(s);
    
    cx_type t1 = cx_valueType(info);
    cx_type t2 = cx_valueType(&data->value);
    
    /* If types are different, validate whether comparison should take place */
    if (t1 != t2) {
        /* Certain types of collections can be compared with each other as long as their elementTypes
         * are equal */
        if ((t1->kind == CX_COLLECTION) && (t1->kind == t2->kind)) {
            switch(cx_collection(t1)->kind) {
            case CX_ARRAY:
            case CX_SEQUENCE:
            case CX_LIST:
                switch(cx_collection(t2)->kind) {
                case CX_ARRAY:
                case CX_SEQUENCE:
                case CX_LIST:
                    if (cx_collection(t1)->elementType == cx_collection(t2)->elementType) {
                        compare = TRUE;
                    }
                    break;
                case CX_MAP:
                    compare = FALSE;
                    break;
                }
                break;
            case CX_MAP:
                if (cx_collection(t2)->kind == CX_MAP) {
                    if (cx_collection(t1)->elementType == cx_collection(t2)->elementType) {
                        if (cx_map(t1)->keyType == cx_map(t2)->keyType) {
                            compare = TRUE;
                        }
                    }
                }
                break;
            }
        } else {
            if ((!t1->reference && (t1->kind == CX_VOID)) && (t2->reference || 
               ((t2->kind == CX_PRIMITIVE) && (cx_primitive(t2)->kind == CX_TEXT)))) {
                compare = TRUE;
            }
            if ((!t2->reference && (t2->kind == CX_VOID)) && (t1->reference || 
               ((t1->kind == CX_PRIMITIVE) && (cx_primitive(t1)->kind == CX_TEXT)))) {
                compare = TRUE;
            }
        }
    } else {
        compare = TRUE;
    }
    
    data->result = compare ? CX_EQ : CX_NEQ;
    data->base = cx_valueValue(info);

    return !compare;
}
Beispiel #4
0
static cx_int16 serializeBoolean(cx_value *value, cx_string *out) {
    cx_bool b = *(cx_bool *)cx_valueValue(value);
    if (b) {
        *out = cx_malloc(sizeof("true"));
        strcpy(*out, "true");
    } else {
        *out = cx_malloc(sizeof("false"));
        strcpy(*out, "false");
    }
    return 0;
}
Beispiel #5
0
static cx_int16 serializeScopeMeta(cx_serializer s, cx_value* v, void* userData) {
    CX_UNUSED(s); /* should we receive s for scalability or should we dismiss it? */
    int last;
    size_t sizeBefore, sizeAfter;
    cx_json_ser_t *data = userData;
    sizeBefore = strlen(data->buffer);
    cx_object object = cx_valueValue(v);
    last = cx_scopeWalk(object, serializeMetaWalkScopeAction, userData);
    sizeAfter = strlen(data->buffer);
    if (sizeAfter && sizeBefore < sizeAfter) {
        data->buffer[sizeAfter - 1] = '\0';
    }
    return last;
}
Beispiel #6
0
static cx_int16 serializeNumericWithPrefix(cx_value *value, cx_string *out, const char *prefix) {
    cx_string raw;
    cx_void *v = cx_valueValue(value);
    if (cx_convert(cx_primitive(cx_valueType(value)), v, cx_primitive(cx_string_o), &raw)) {
        goto error;
    }
    int length = snprintf(NULL, 0, "\"%s\" %s", prefix, raw);
    if (length < 0) {
        goto error;
    }
    *out = cx_malloc(length + 1);
    if (sprintf(*out, "\"%s %s\"", prefix, raw) < 0) {
        goto error;
    }
    cx_dealloc(raw);
    return 0;
error:
    cx_dealloc(raw);
    return -1;
}
Beispiel #7
0
static cx_int16 serializeReference(cx_serializer s, cx_value *v, void *userData) {
    CX_UNUSED(s);

    cx_json_ser_t *data;
    void *o;
    cx_object object;
    cx_id id;

    data = userData;
    o = cx_valueValue(v);
    object = *(cx_object*)o;

    if (object) {
        if (cx_checkAttr(object, CX_ATTR_SCOPED) || (cx_valueObject(v) == object)) {
            cx_uint32 length;
            cx_fullname(object, id);
            
            /* Escape value */
            cx_string escapedValue = cx_malloc((length = stresc(NULL, 0, id)) + 1);
            stresc(escapedValue, length, id);
            if (!cx_ser_appendstr(data, "\"@R %s\"", escapedValue)) {
                cx_dealloc(escapedValue);
                goto finished;
            }
            cx_dealloc(escapedValue);
        } else {
            cx_ser_appendstr(data, "\"anonymous\"");
        }
    } else {
        if (!cx_ser_appendstrbuff(data, "null")) {
            goto finished;
        }
    }
    return 0;
finished:
    return 1;

}
/* Serialize dependencies on references */
cx_int16 cx_genDepReference(cx_serializer s, cx_value* info, void* userData) {
    cx_object o;
    g_depWalk_t data;

    CX_UNUSED(s);

    data = userData;
    o = *(cx_object*)cx_valueValue(info);

    if (o && g_mustParse(data->data->g, o)) {
        cx_member m;

        m = NULL;

        if (info->kind == CX_MEMBER) {
            m = info->is.member.t;
            if (!m->type->reference) {
                m = NULL;
            }
        }

        /* Add dependency on item */
        if (m) {
            cx_depresolver_depend(data->data->resolver, data->o, CX_DEFINED, o, m->state);
        } else {
            cx_depresolver_depend(data->data->resolver, data->o, CX_DEFINED, o, CX_DEFINED);
        }

        /* Include dependencies on anonymous types */
        if (!cx_checkAttr(o, CX_ATTR_SCOPED)) {
            cx_genDepBuildAction(o, data->data);
        }
    }

    return 0;
}
Beispiel #9
0
/* Compare collections */
static cx_int16 cx_ser_collection(cx_serializer s, cx_value *info, void* userData) {
    cx_type t1, t2;
    void *v1, *v2;
    cx_equalityKind result = CX_EQ;
    cx_uint32 size1 = 0, size2 = 0;
    cx_compare_ser_t *data = userData;
    cx_any a1, a2;
    
    CX_UNUSED(s);
    
    /* If this function is reached, collection-types are either equal or comparable. When the 
     * base-object was a collection, the collection type can be different. When the base-object
     * was a composite type, the collection type has to be equal, since different composite 
     * types are considered non-comparable. */
    t1 = cx_valueType(info);
    v1 = cx_valueValue(info);
    
    /* Verify whether current serialized object is the base-object */
    if (info->parent) {
        t2 = t1;
        v2 = (void*)((cx_word)cx_valueValue(&data->value) + ((cx_word)v1 - (cx_word)data->base));
    } else {
        t2 = cx_valueType(&data->value);
        v2 = cx_valueValue(&data->value);
    }
    
    /* Prepare any structures for determining sizes of collections */
    a1.type = t1;
    a1.value = v1;
    a2.type = t2;
    a2.value = v2;
    
    if ((size1 = cx_collection_size(a1)) == (size2 = cx_collection_size(a2))) {
        void *array1=NULL, *array2=NULL;
        cx_ll list1=NULL, list2=NULL;
        cx_uint32 elementSize=0, mem=0;
        
        elementSize = cx_type_sizeof(cx_collection(t1)->elementType);
        
        switch(cx_collection(t1)->kind) {
            case CX_ARRAY:
                array1 = v1;
                elementSize = cx_type_sizeof(cx_collection(t1)->elementType);
                mem = cx_collection(t1)->max * elementSize;
                break;
            case CX_SEQUENCE:
                array1 = ((cx_objectSeq*)v1)->buffer;
                elementSize = cx_type_sizeof(cx_collection(t1)->elementType);
                mem = ((cx_objectSeq*)v1)->length * elementSize;
                break;
            case CX_LIST:
                list1 = *(cx_ll*)v1;
                break;
            case CX_MAP:
                break;
        }
        
        switch(cx_collection(t2)->kind) {
            case CX_ARRAY:
                array2 = v2;
                break;
            case CX_SEQUENCE:
                array2 = ((cx_objectSeq*)v2)->buffer;
                break;
            case CX_LIST:
                list2 = *(cx_ll*)v2;
                break;
            case CX_MAP:
                break;
        }
        
        if (array1) {
            if (array2) {
                result = memcmp(array1,array2,mem); /* TODO: do a serialized compare */
            } else if (list2) {
                result = cx_collection_compareArrayWithList(cx_collection(t1), array1, elementSize, list2);
            }
        } else if (list1) {
            if (array2) {
                result = cx_collection_compareArrayWithList(cx_collection(t1), array2, elementSize, list1);
                /* Reverse result */
                if (result != CX_EQ) {
                    if (result == CX_GT) {
                        result = CX_LT;
                    } else {
                        result = CX_GT;
                    }
                }
            } else if (list2) {
                result = cx_collection_compareListWithList(cx_collection(t1), list1, list2);
            }
        }
    } else {
        result = size1 > size2 ? CX_GT : CX_LT;
    }
    
    data->result = result < 0 ? -1 : result > 0 ? 1 : 0;
    
    return data->result != CX_EQ;
}
Beispiel #10
0
static cx_int16 cx_ser_primitive(cx_serializer s, cx_value *info, void *userData) {
    cx_equalityKind result = CX_EQ;
    cx_compare_ser_t *data = userData;
    cx_type type = cx_valueType(info);
    void *_this = cx_valueValue(info);
    void *value = (void*)((cx_word)cx_valueValue(&data->value) + ((cx_word)_this - (cx_word)data->base));
    
    CX_UNUSED(s);
    
    switch(cx_primitive(type)->kind) {
        case CX_BINARY:
            switch(cx_primitive(type)->width) {
                case CX_WIDTH_8:
                    result = CX_COMPARE(cx_octet, _this, value);
                    break;
                case CX_WIDTH_16:
                    result = CX_COMPARE(cx_uint16, _this, value);
                    break;
                case CX_WIDTH_32:
                    result = CX_COMPARE(cx_uint32, _this, value);
                    break;
                case CX_WIDTH_64:
                    result = CX_COMPARE(cx_uint64, _this, value);
                    break;
                case CX_WIDTH_WORD:
                    result = CX_COMPARE(cx_word, _this, value);
                    break;
            }
            break;
        case CX_BOOLEAN:
            result = CX_COMPARE(cx_bool, _this, value);
            break;
        case CX_CHARACTER:
            result = CX_COMPARE(cx_char, _this, value);
            break;
        case CX_INTEGER:
            switch(cx_primitive(type)->width) {
                case CX_WIDTH_8:
                    result = CX_COMPARE(cx_int8, _this, value);
                    break;
                case CX_WIDTH_16:
                    result = CX_COMPARE(cx_int16, _this, value);
                    break;
                case CX_WIDTH_32:
                    result = CX_COMPARE(cx_int32, _this, value);
                    break;
                case CX_WIDTH_64:
                    result = CX_COMPARE(cx_int64, _this, value);
                    break;
                case CX_WIDTH_WORD:
                    result = CX_COMPARE(intptr_t, _this, value);
                    break;
            }
            break;
        case CX_UINTEGER:
            switch(cx_primitive(type)->width) {
                case CX_WIDTH_8:
                    result = CX_COMPARE(cx_uint8, _this, value);
                    break;
                case CX_WIDTH_16:
                    result = CX_COMPARE(cx_uint16, _this, value);
                    break;
                case CX_WIDTH_32:
                    result = CX_COMPARE(cx_uint32, _this, value);
                    break;
                case CX_WIDTH_64:
                    result = CX_COMPARE(cx_uint64, _this, value);
                    break;
                case CX_WIDTH_WORD:
                    result = CX_COMPARE(uintptr_t, _this, value);
                    break;
            }
            break;
        case CX_FLOAT:
            switch(cx_primitive(type)->width) {
                case CX_WIDTH_32:
                    result = CX_COMPARE(cx_float32, _this, value);
                    break;
                case CX_WIDTH_64:
                    result = CX_COMPARE(cx_float64, _this, value);
                    break;
                default:
                    break;
            }
            break;
        case CX_TEXT: {
            cx_string thisStr = *(cx_string*)_this;
            cx_string valueStr = *(cx_string*)value;
            if (thisStr && valueStr) {
                result = strcmp(thisStr, valueStr);
            } else {
                result = !(thisStr == valueStr);
            }
            break;
        }
        case CX_ENUM:
        case CX_BITMASK:
            result = CX_COMPARE(cx_int32, _this, value);
            break;
        case CX_ALIAS:
            result = CX_COMPARE(cx_word, _this, value);
            break;
    }
    
    data->result = result;
    
    return data->result != CX_EQ;
}
Beispiel #11
0
static cx_int16 serializeNumber(cx_value *value, cx_string *out) {
    cx_type t = cx_valueType(value);
    cx_void  *v = cx_valueValue(value);
    cx_int16 result = cx_convert(cx_primitive(t), v, cx_primitive(cx_string_o), out);
    return result;
}
Beispiel #12
0
static cx_int16 serializeMeta(cx_serializer s, cx_value* v, void* userData) {
    CX_UNUSED(s);
    cx_json_ser_t *data = userData;
    cx_object o = cx_valueValue(v);

    if (!data->serializeMeta) {
        goto error;
    }

    if (!cx_ser_appendstr(userData, "{")) {
        goto finished;
    }

    cx_string name = cx_nameof(o);
    if (name) {
        if (!cx_appendStringAttr("name", name, userData)) {
            goto finished;
        }
    } else {
        if (!cx_ser_appendstr(userData, "\"name\":\"::\",")) {
            goto finished;
        }        
    }

    cx_id type_fullname;
    cx_fullname(cx_typeof(o), type_fullname);
    if (!cx_appendStringAttr("type", type_fullname, userData)) {
        goto finished;
    }

    if (cx_checkAttr(o, CX_ATTR_PERSISTENT)) {
        cx_time t = cx_timestampof(o);
        if (!cx_ser_appendstr(data, "\"timestamp\":\"%d.%.9d\",", t.tv_sec, t.tv_nsec)) {
            goto finished;
        }        
    }

    char states[sizeof("V|DCL|DEF")];
    dbsh_stateStr(o, states);
    if (!cx_ser_appendstr(data, "\"states\":\"%s\",", states)) {
        goto finished;
    }

    char attributes[sizeof("S|W|O|P")];
    dbsh_attrStr(o, attributes);
    if (!cx_ser_appendstr(data, "\"attributes\":\"%s\",", attributes)) {
        goto finished;
    }

    cx_id parent_fullname;
    cx_fullname(cx_parentof(o), parent_fullname);
    if (!cx_ser_appendstr(data, "\"parent\":\"%s\",", parent_fullname)) {
        goto finished;
    }

    cx_uint32 scopeSize = cx_scopeSize(o);
    if (!cx_ser_appendstr(data, "\"childCount\":%"PRId32"", scopeSize)) {
        goto finished;
    }

    if (!cx_ser_appendstr(data, "}")) {
        goto finished;
    }


    return 0;
error:
    return -1;
finished:
    return 1;
}