예제 #1
0
corto_void _test_compositeApi_tc_define(
    test_compositeApi _this)
{
/* $begin(test/compositeApi/tc_define) */
    corto_int16 result;

    test_compositeType *o = test_compositeTypeDeclareChild(root_o, "o");
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeType_o));
    test_assert(!corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->x == 1);
    test_assert(o->y == 2);

    result = test_compositeTypeDefine(o, 10, 20);
    test_assert(result == 0);
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(o->x == 10);
    test_assert(o->y == 20);

    test_assert(!corto_delete(o));

/* $end */
}
예제 #2
0
파일: _wrapper.c 프로젝트: rfloresx/corto
bool _corto_delegate_compatible(
    corto_delegate _this,
    corto_type type)

{
    static corto_uint32 _methodId;
    corto_method _method;
    bool _result;
    corto_interface _abstract;

    _abstract = corto_interface(corto_typeof(_this));

    /* Determine methodId once, then cache it for subsequent calls. */
    if (!_methodId) {
        _methodId = corto_interface_resolveMethodId(_abstract, "compatible(type type)");
    }
    corto_assert(_methodId, "virtual 'compatible(type type)' not found in '%s'%s%s", corto_fullpath(NULL, _abstract), corto_lasterr() ? ": " : "", corto_lasterr() ? corto_lasterr() : "");

    /* Lookup method-object. */
    _method = corto_interface_resolveMethodById(_abstract, _methodId);
    corto_assert(_method != NULL, "unresolved method '%s::compatible(type type)@%d'", corto_idof(_this), _methodId);

    if (corto_function(_method)->kind == CORTO_PROCEDURE_CDECL) {
        _result = ((bool ___ (*)(corto_object, corto_type))((corto_function)_method)->fptr)(_this, type);
    } else {
        corto_call(corto_function(_method), &_result, _this, type);
    }
    
    return _result;
}
예제 #3
0
corto_void _test_compositeUnionApi_tc_defineDefault(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_defineDefault) */
    corto_int16 result;

    test_compositeUnionType *o = test_compositeUnionTypeDeclareChild(root_o, "o");
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(!corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->d == 2);
    test_assertstr(o->is.str, "foo");

    result = test_compositeUnionTypeDefine_other(o, 4, 10);
    test_assert(result == 0);
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(o->d == 4);
    test_assert(o->is.other == 10);

    test_assert(!corto_delete(o));

/* $end */
}
예제 #4
0
corto_int16 json_deserReference(void* p, corto_type t, JSON_Value* v)
{
    switch(json_value_get_type(v)) {
    case JSONString: {
        const char* reference = json_value_get_string(v);
        corto_object o = corto_resolve(NULL, (corto_string)reference);
        if (!o) {
            corto_error("unresolved reference \"%s\"", reference);
            goto error;
        }

        if (!corto_instanceof(t, o)) {
            corto_error("%s is not an instance of %s", reference, corto_idof(t));
        }

        corto_setref(p, o);
        corto_release(o);
        break;
    }
    case JSONObject: {
        JSON_Object* obj = json_value_get_object(v);

        JSON_Value* type = json_object_get_value(obj, "type");
        if (json_value_get_type(type) != JSONString) {
            corto_seterr("type parameter of anonymous object must be a string");
            goto error;
        }
        corto_type cortoType = corto_resolve(NULL, (char*)json_value_get_string(type));
        if (!cortoType) {
            corto_seterr("type '%s' not found for anonymous object", json_value_get_string(type));
            goto error;
        }

        corto_object cortoObj = *(corto_object*)p;
        if (!cortoObj || (corto_typeof(cortoObj) != cortoType)) {
            cortoObj = corto_create(cortoType);
            corto_setref(p, cortoObj);
            corto_release(cortoObj);
        }
        corto_release(cortoType);

        JSON_Value* value = json_object_get_value(obj, "value");
        if (json_deserType(cortoObj, cortoType, value)) {
            goto error;
        }
        break;
    }
    case JSONNull:
        corto_setref(p, NULL);
        break;
    default:
        corto_seterr("expected string, null or object (reference), got %s", json_valueTypeToString(v));
        break;
    }

    return 0;
error:
    return -1;
}
예제 #5
0
corto_int16 _md_DocUpdate(md_Doc _this, corto_object o, corto_uint8 level, corto_string niceName) {
    CORTO_UNUSED(_this);
    if (!corto_updateBegin(_this)) {
        if ((corto_typeof(corto_typeof(_this)) == (corto_type)corto_target_o) && !corto_owned(_this)) {
            corto_setref(&((md_Doc)((md_Doc)CORTO_OFFSET(_this, ((corto_type)md_Doc_o)->size)))->o, o);
            ((md_Doc)((md_Doc)CORTO_OFFSET(_this, ((corto_type)md_Doc_o)->size)))->level = level;
            corto_setstr(&((md_Doc)((md_Doc)CORTO_OFFSET(_this, ((corto_type)md_Doc_o)->size)))->niceName, niceName);
        } else {
            corto_setref(&((md_Doc)_this)->o, o);
            ((md_Doc)_this)->level = level;
            corto_setstr(&((md_Doc)_this)->niceName, niceName);
        }
        corto_updateEnd(_this);
    } else {
        return -1;
    }
    return 0;
}
예제 #6
0
파일: native.c 프로젝트: cortoproject/corto
corto_int16 _corto_native_type__update(corto_native_type _this, const char * name, bool is_ptr) {
    CORTO_UNUSED(_this);
    if (!corto_update_begin(_this)) {
        if ((corto_typeof(corto_typeof(_this)) == (corto_type)corto_target_o) && !corto_owned(_this)) {
            corto_set_str(&((corto_native_type)((corto_native_type)CORTO_OFFSET(_this, ((corto_type)corto_native_type_o)->size)))->name, name);
            ((corto_native_type)((corto_native_type)CORTO_OFFSET(_this, ((corto_type)corto_native_type_o)->size)))->is_ptr = is_ptr;
        } else {
            corto_set_str(&((corto_native_type)_this)->name, name);
            ((corto_native_type)_this)->is_ptr = is_ptr;
        }
        if (corto_update_end(_this)) {
            return -1;
        }
    } else {
        return -1;
    }
    return 0;
}
예제 #7
0
파일: value.c 프로젝트: rfloresx/corto
corto_value _corto_value_object(corto_object o, corto_type t) {
    corto_value val;
    val.kind = CORTO_OBJECT;
    val.parent = NULL;
    val.is.object.o = o;
    if (t) {
        val.is.object.t = t;
    } else {
        val.is.object.t = corto_typeof(o);
    }
    return val;
}
예제 #8
0
corto_void _test_voidReferenceApi_tc_createAuto(
    test_voidReferenceApi _this)
{
/* $begin(test/voidReferenceApi/tc_createAuto) */

    test_voidReferenceTypeCreate_auto(o);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == test_voidReferenceType_o);
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(!corto_delete(o));

/* $end */
}
예제 #9
0
corto_int16 _corto_delegate_bind(corto_function object) {
/* $begin(::corto::lang::delegate::bind) */
    corto_object parent = corto_parentof(object);

    if (corto_class_instanceof(corto_interface_o, corto_typeof(parent))) {
        corto_interface type = corto_interface(corto_typeof(parent));
        corto_id functionName;
        corto_member m = NULL;

        /* Get function name, lookup delegate, assign function */
        corto_signatureName(corto_nameof(object), functionName);
        if (corto_checkState(corto_type_o, CORTO_DEFINED) && (m = corto_interface_resolveMember(type, functionName)) &&
            (m->type->kind == CORTO_COMPOSITE) && (corto_interface(m->type)->kind == CORTO_DELEGATE)) {
            if (corto_delegate_instanceof(corto_delegate(m->type), object)) {
                /* Bind instance of function is a method */
                if (corto_procedure(corto_typeof(object))->kind == CORTO_METHOD) {
                    corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->instance, parent);
                }
                /* Bind procedure */
                corto_setref(&((corto_delegatedata *) CORTO_OFFSET(parent, m->offset))->procedure, object);    
            } else {
                /* If there is a member that corresponds to a delegate but has a non matching
                 * signature, always report error */
                corto_id id1, id2;
                corto_error("member '%s' of delegate type '%s' does not match signature of '%s'",
                    corto_nameof(m), corto_fullname(m->type, id1), corto_fullname(object, id2));
                goto error;
            }
        }
    }

    return 0;
error:
    return -1;
/* $end */
}
예제 #10
0
corto_void _test_compositeUnionApi_tc_create(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_create) */

    test_compositeUnionType *o = test_compositeUnionTypeCreate_flt(1, 10.5);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(o->d == 1);
    test_assert(o->is.flt == 10.5);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #11
0
corto_void _test_compositeUnionApi_tc_createAutoDefault(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_createAutoDefault) */

    test_compositeUnionTypeCreate_other_auto(o, 4, 10);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(o->d == 4);
    test_assert(o->is.other == 10);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #12
0
corto_void _test_compositeApi_tc_declare(
    test_compositeApi _this)
{
/* $begin(test/compositeApi/tc_declare) */

    test_compositeType *o = test_compositeTypeDeclare();
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeType_o));
    test_assert(!corto_checkState(o, CORTO_DEFINED));
    test_assert(o->x == 1);
    test_assert(o->y == 2);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #13
0
corto_void _test_compositeUnionApi_tc_declareAuto(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_declareAuto) */

    test_compositeUnionTypeDeclare_auto(o);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(!corto_checkState(o, CORTO_DEFINED));
    test_assert(o->d == 2);
    test_assertstr(o->is.str, "foo");
    test_assert(!corto_delete(o));

/* $end */
}
예제 #14
0
corto_void _test_compositeApi_tc_createAuto(
    test_compositeApi _this)
{
/* $begin(test/compositeApi/tc_createAuto) */

    test_compositeTypeCreate_auto(o, 10, 20);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(o->x == 10);
    test_assert(o->y == 20);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #15
0
corto_void _test_voidReferenceApi_tc_createChildAuto(
    test_voidReferenceApi _this)
{
/* $begin(test/voidReferenceApi/tc_createChildAuto) */

    test_voidReferenceTypeCreateChild_auto(root_o, o);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == test_voidReferenceType_o);
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(!corto_delete(o));

/* $end */
}
예제 #16
0
corto_void _test_compositeUnionApi_tc_declareChildAuto(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_declareChildAuto) */

    test_compositeUnionTypeDeclareChild_auto(root_o, o);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(!corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->d == 2);
    test_assertstr(o->is.str, "foo");
    test_assert(!corto_delete(o));

/* $end */
}
예제 #17
0
corto_void _test_compositeApi_tc_createChildAuto(
    test_compositeApi _this)
{
/* $begin(test/compositeApi/tc_createChildAuto) */

    test_compositeTypeCreateChild_auto(root_o, o, 10, 20);
    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->x == 10);
    test_assert(o->y == 20);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #18
0
파일: value.c 프로젝트: rfloresx/corto
corto_function corto_valueFunction(corto_value* val) {
    corto_function result;

    switch(val->kind) {
    case CORTO_OBJECT:
        if (corto_class_instanceof(corto_procedure_o, corto_typeof(val->is.object.o))) {
            result = val->is.object.o;
        } else {
            corto_seterr("object '%s' in value is not a function",
                corto_fullpath(NULL, val->is.object.o));
            result = NULL;
        }
        break;
    default:
       corto_seterr("value does not represent a function");
       result = NULL;
       break;
    }

    return result;
}
예제 #19
0
corto_void _test_compositeUnionApi_tc_createChild(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_createChild) */

    test_compositeUnionType *o = test_compositeUnionTypeCreateChild_flt(
        root_o,
        "o",
        1,
        10.5);

    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->d == 1);
    test_assert(o->is.flt == 10.5);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #20
0
corto_void _test_compositeUnionApi_tc_createChildAutoDefault(
    test_compositeUnionApi _this)
{
/* $begin(test/compositeUnionApi/tc_createChildAutoDefault) */

    test_compositeUnionTypeCreateChild_other_auto(
        root_o,
        o,
        4,
        10);

    test_assert(o != NULL);
    test_assert(corto_typeof(o) == corto_type(test_compositeUnionType_o));
    test_assert(corto_checkState(o, CORTO_DEFINED));
    test_assert(corto_checkAttr(o, CORTO_ATTR_SCOPED));
    test_assert(corto_parentof(o) == root_o);
    test_assert(!strcmp(corto_idof(o), "o"));
    test_assert(o->d == 4);
    test_assert(o->is.other == 10);
    test_assert(!corto_delete(o));

/* $end */
}
예제 #21
0
 * This example shows basic usage of core API functions to create, update
 * and delete objects.
 */

/* Callback for observer */
void onUpdate(
    corto_object this,
    corto_eventMask event,
    corto_object o,
    corto_observer observer)
{
    /* Show information about the object that triggered the observer */
    printf("update received for id='%s' parent='%s' type='%s' value='%d'\n",
      corto_idof(o),
      corto_fullpath(NULL, corto_parentof(o)),
      corto_fullpath(NULL, corto_typeof(o)),
      *corto_int32(o));
}

int objectsMain(int argc, char *argv[]) {

    /* Create a signed integer object in the global object hierarchy */
    corto_int32 *i = corto_createChild(root_o, "i", corto_int32_o);
    if (!i) {
        goto error;
    }

    /* Observe the object for updates */
    corto_observer observer = corto_observe(CORTO_ON_UPDATE, i).callback(onUpdate);

    /* Change the value of the object */
예제 #22
0
void printInfo(corto_object o) {
    printf("object '%s' created with parent=%s, type=%s\n",
           corto_fullpath(NULL, o),
           corto_fullpath(NULL, corto_parentof(o)),
           corto_fullpath(NULL, corto_typeof(o)));
}
예제 #23
0
/* Deserialize string in object */
corto_string corto_string_deser(corto_string str, corto_string_deser_t* data) {
    corto_char *ptr;
    corto_bool createdNew = FALSE;

    {
        corto_id buffer;
        corto_char *bptr, ch;

        /* Parse typename that potentially precedes string */
        bptr = buffer;
        ptr = str;
        while((ch = *ptr) && (ch != '{')) {
            if (!((ch == ' ') || (ch == '\n') || (ch == '\t'))) {
                *bptr = ch;
                bptr++;
            }
            ptr++;
        }
        *bptr = '\0';

        /* If no type is found, reset ptr */
        if ((ch != '{') || (ptr == str)) {
            ptr = str;
        } else {
            corto_object type;

            /* If no out is provided create an object of the specified type */
            if ((bptr != buffer)) {
                type = corto_resolve(NULL, buffer);
                if (type) {
                    if (data->type && (type != data->type)) {
                        corto_seterr(
                          "type of object ('%s') does not match string ('%s')",
                          corto_fullpath(NULL, data->type),
                          corto_fullpath(NULL, type));
                        corto_release(type);
                        goto error;
                    }
                    if (corto_instanceof(corto_type(corto_type_o), type)) {
                        if (!data->out) {
                            data->out = corto_declare(type);
                            createdNew = TRUE;
                        }
                        data->type = type;
                    } else {
                        corto_seterr("'%s' is not a type", buffer);
                        corto_release(type);
                        goto error;
                    }
                    corto_release(type);
                } else {
                    corto_seterr("unknown type '%s'", buffer);
                    goto error;
                }
            } else {
                type = data->type;
            }

            if (type && (corto_type(type)->kind == CORTO_PRIMITIVE)) {
                ptr++;
            }
        }
    }

    data->current = 0;
    data->index = NULL;
    data->ptr = data->out;
    data->anonymousObjects = NULL;
    data->allocValue = NULL;
    data->allocUdata = NULL;

    if (data->out && data->isObject) {
        if (!data->type) {
            data->type = corto_typeof(data->out);
        } else if (!corto_instanceofType(corto_typeof(data->out), data->type)) {
            corto_seterr("object '%s' of type '%s' is not an instance of type '%s'",
                corto_fullpath(NULL, data->out),
                corto_fullpath(NULL, corto_typeof(data->out)),
                corto_fullpath(NULL, data->type));
            goto error;
        }
    }

    if (!data->type) {
        corto_seterr("no type provided for '%s'", str);
        goto error;
    }
    
    if (data->type->kind == CORTO_PRIMITIVE) {
        ptr = corto_string_deserParse(ptr, NULL, data);
    } else {
        ptr = corto_string_deserParseScope(ptr, NULL, data);
        if (ptr) {
            ptr ++;
        }
    }

    if (!ptr) {
        if (!corto_lasterr()) {
            corto_seterr("failed to deserialize '%s'", str);
        } else {
            corto_seterr("failed to deserialize '%s': %s", str, corto_lasterr());
        }
        goto error;
    }

    if (data->anonymousObjects) {
        corto_ll_free(data->anonymousObjects);
    }

    return ptr;
error:
    if (data->out) {
        if (createdNew) {
            corto_release(data->out);
        }
        data->out = NULL;
    }
    return NULL;
}
예제 #24
0
/* Parse scope */
static corto_string corto_string_deserParseScope(corto_string str, struct corto_string_deserIndexInfo* info, corto_string_deser_t* data) {
    struct corto_string_deserIndexInfo rootInfo;
    corto_typeKind kind;
    void *ptr = data->ptr;

    if (data->allocValue) {
        ptr = data->allocValue(ptr, data);
    }

    /* Prepare privateData */
    corto_string_deser_t privateData = {
        .out = data->out,
        .scope = data->scope,
        .anonymousObjects = data->anonymousObjects,
        .type = data->type,
        .isObject = data->isObject,
        .members = {0, NULL}
    };

    /* Offset the scope-members with the current offset */
    if (info && info->m) {
        ptr = corto_getMemberPtr(data->isObject ? data->out : NULL, ptr, info->m);
    }
    privateData.ptr = ptr;

    /* Open scope of type */
    if (!info) {
        if (!data->type) {
            rootInfo.type = corto_typeof(data->out);
        } else {
            rootInfo.type = data->type;
        }
        rootInfo.m = NULL;
        rootInfo.parsed = FALSE;
        info = &rootInfo;
    }

    /* Check if type is any, composite or collection */
    kind = info->type->kind;

    if ((kind != CORTO_COMPOSITE) && (kind != CORTO_COLLECTION) && (kind != CORTO_ANY)) {
        corto_seterr("'{' unexpected for type '%s'",
            corto_fullpath(NULL, info->type));
        goto error;
    }

    /* Build index for type */
    if (info->type->kind == CORTO_COMPOSITE) {
        if (corto_interface(info->type)->kind == CORTO_UNION) {
            /* Parse discriminator */
            struct corto_string_deserIndexInfo dInfo;
            dInfo.type = (corto_type)corto_int32_o;
            dInfo.parsed = FALSE;
            dInfo.m = NULL;
            str = corto_string_deserParse(str + 1, &dInfo, &privateData);
            if (!str) {
                goto error;
            }

            /* Find corresponding union case */
            corto_int32 d = *(corto_int32*)ptr;
            corto_member m = safe_corto_union_findCase(info->type, d);
            if (!m) {
                corto_seterr("discriminator '%d' invalid for union '%s'",
                    d, corto_fullpath(NULL, info->type));
                goto error;
            }

            /* Build index for one member */
            struct corto_string_deserIndexInfo *caseInfo =
                corto_alloc(sizeof(struct corto_string_deserIndexInfo));
            caseInfo->type = m->type;
            caseInfo->parsed = FALSE;
            caseInfo->m = m;
            corto_string_deserIndexInsert(&privateData, caseInfo);
        } else {
            corto_walk_opt s = corto_string_deserBuildIndex();
            s.members = data->members;
            if (s.members.length) {
                s.access = 0;
            }
            if (corto_metawalk(&s, info->type, &privateData)) {
                goto error;
            }
        }

        /* Create iterator for index */
        if (privateData.index) {
            privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
        }
    /* If type is a collection, build index with one node for element */
    } else if (info->type->kind == CORTO_COLLECTION) {
        struct corto_string_deserIndexInfo *elementNode;
        elementNode = corto_alloc(sizeof(struct corto_string_deserIndexInfo));
        elementNode->m = NULL;
        elementNode->parsed = FALSE;
        elementNode->type = corto_collection(info->type)->elementType;
        corto_string_deserIndexInsert(&privateData, elementNode);

        /* Create iterator for index */
        privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
        privateData.allocValue = corto_string_deserAllocElem;
        privateData.allocUdata = info->type;

        if (ptr) {
            switch(corto_collection(info->type)->kind) {
            case CORTO_ARRAY:
            case CORTO_SEQUENCE:
                break;
            case CORTO_LIST:
                if (!*(corto_ll*)ptr) {
                    *(corto_ll*)ptr = corto_ll_new();
                } else {
                    corto_ll_clear(*(corto_ll*)ptr);
                }
                privateData.ptr = ptr;
                break;
            default:
                break;
            }
        }
    } else if (info->type->kind == CORTO_ANY) {
          struct corto_string_deserIndexInfo *anyNode;
          anyNode = corto_alloc(sizeof(struct corto_string_deserIndexInfo));
          anyNode->m = NULL;
          anyNode->parsed = FALSE;
          anyNode->type = corto_type(corto_type_o);
          corto_string_deserIndexInsert(&privateData, anyNode);
          privateData.currentIter = _corto_ll_iter(privateData.index, &privateData.iterData);
          privateData.allocValue = corto_string_deserAllocAny;
          privateData.allocUdata = anyNode;
    }

    /* Parse scope */
    if (!(str = corto_string_deserParse(str+1, info, &privateData))) {
        goto error;
    }

    corto_string_deserFreeIndex(&privateData);

    data->anonymousObjects = privateData.anonymousObjects;

    return str;
error:
    return NULL;
}

/* Get pointer to current destination value */
corto_int16 corto_string_getDestinationPtr(
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data,
    void **ptr_out)
{
    void *result = data->ptr;

    *ptr_out = NULL;

    if (!info) {
        corto_seterr("excess elements in string");
        goto error;
    }

    if (data->allocValue) {
        result = data->allocValue(result, data);
    }

    if (info->m) {
        result = corto_getMemberPtr(data->isObject ? data->out : NULL, data->ptr, info->m);
    }

    *ptr_out = result;

    return 0;
error:
    return -1;
}
예제 #25
0
static corto_string corto_string_parseAnonymous(
    corto_string str,
    corto_string value,
    struct corto_string_deserIndexInfo *info,
    corto_string_deser_t *data)
{
    corto_object o = NULL;
    char *ptr = str;
    char *valuePtr = value;
    corto_uint32 index = 0;
    void *offset;

    if (corto_string_getDestinationPtr(info, data, &offset)) {
        corto_seterr("%s: %s", str, corto_lasterr());
        goto error;
    }

    /* Check if this is a 'named' anonymous object in which case it is
     * prefixed with <[id]> */
    if ((valuePtr = corto_string_deserParseAnonymousId(valuePtr, &index))) {
        if (data->anonymousObjects && (index <= corto_ll_size(data->anonymousObjects))) {
            if (!*valuePtr) {
                o = corto_ll_get(data->anonymousObjects, index - 1);
                corto_claim(o);
            } else {
                /* If the <n> is followed up with more data, a new anonymous
                 * object is being created while one existed already with the
                 * specified number */
                corto_seterr("identifier <%d> is already defined (%s)", index, value);
                goto error;
            }
        }
    } else {
        valuePtr = value;
    }

    /* If no object has been referenced, create an anonymous object */
    if (!o && *valuePtr) {
        corto_object type = corto_resolve(NULL, valuePtr);
        if (!type) {
            corto_seterr("unresolved type '%s'", valuePtr);
            goto error;
        }

        if (offset) {
            o = *(corto_object*)offset;
            if (!o || (type != corto_typeof(o))) {
                if (!corto_instanceof(corto_type_o, type)) {
                    corto_seterr("'%s' is not a type", corto_fullpath(NULL, type));
                    goto error;
                }

                o = corto_declare(type);
                if (!o) {
                    corto_seterr("failed to declare %s: %s",
                        value,
                        corto_lasterr());
                    goto error;
                }
            } else {
                corto_claim(o);
            }
        }

        corto_string_deser_t privateData = {
            .out = data->out, // Preserve original out to determine ownership
            .ptr = o,
            .type = type,
            .anonymousObjects = data->anonymousObjects,
            .scope = data->scope,
            .isObject = data->isObject
        };

        if (corto_type(type)->kind == CORTO_PRIMITIVE) {
            ptr ++;
            if (!(ptr = corto_string_deserParse(ptr, NULL, &privateData))) {
                goto error;
            }
        } else {
            if (!(ptr = corto_string_deserParseScope(ptr, NULL, &privateData))) {
                goto error;
            }
        }

        if (o) {
            if (corto_define(o)) {
                goto error;
            }
            data->anonymousObjects = privateData.anonymousObjects;

            if (!data->anonymousObjects) {
                data->anonymousObjects = corto_ll_new();
            }

            corto_ll_append(data->anonymousObjects, o);
        }
    }

    if (offset) corto_ptr_setref(offset, o);
    if (o) corto_release(o);

    return ptr;
error:
    if (o) corto_release(o);
    return NULL;
}
예제 #26
0
파일: _wrapper.c 프로젝트: daltonwang/corto
 * This file contains wrapper functions for /corto/lang.
 */

#include <corto/lang/lang.h>
#include <corto/lang/_meta.h>

corto_bool _corto_collection_castable(
    corto_collection this,
    corto_type type)
{
    static corto_uint32 _methodId;
    corto_method _method;
    corto_bool _result;
    corto_interface _abstract;

    _abstract = corto_interface(corto_typeof(this));

    /* Determine methodId once, then cache it for subsequent calls. */
    if (!_methodId) {
        _methodId = corto_interface_resolveMethodId(_abstract, "castable(type type)");
    }
    corto_assert(_methodId, "virtual 'castable(type type)' not found in '%s'%s%s", corto_fullpath(NULL, _abstract), corto_lasterr()?": ":"", corto_lasterr());

    /* Lookup method-object. */
    _method = corto_interface_resolveMethodById(_abstract, _methodId);
    corto_assert(_method != NULL, "unresolved method '%s::castable(type type)@%d'", corto_idof(this), _methodId);

    corto_call(corto_function(_method), &_result, this, type);
    
    return _result;
}