コード例 #1
0
ファイル: value.c プロジェクト: rfloresx/corto
corto_int16 corto_value_memberExpr(corto_value *val, corto_string member, corto_value *out) {
    corto_type t = corto_value_typeof(val);
    corto_object o = corto_value_objectof(val);
    void *ptr = corto_value_ptrof(val);

    corto_id tokens;
    strncpy(tokens, member, sizeof(corto_id));

    char *cur = tokens, *prev = tokens;
    do {
        if (cur && (cur = strchr(cur + 1, '.'))) *cur = '\0';

        if (!corto_instanceof(corto_interface_o, t)) {
            corto_seterr(
                "cannot get member from a non-composite value (type is '%s')",
                corto_fullpath(NULL, t));
            goto error;
        }

        if (!strcmp(prev, "super")) {
            if (!(t = (corto_type)corto_interface(t)->base)) {
                corto_seterr("super unpexpected: interface '%s' does not have a base",
                    corto_fullpath(NULL, t));
                goto error;
            } else {
                *out = corto_value_base(ptr, t);
            }
        } else {
            corto_member m = corto_interface_resolveMember(t, prev);
            if (!m) {
                corto_seterr(
                    "unresolved member '%s' in type '%s'",
                    prev,
                    corto_fullpath(NULL, t));
                goto error;
            }

            ptr = CORTO_OFFSET(ptr, m->offset);
            t = m->type;

            *out = corto_value_member(o, m, ptr);
        }

        prev = cur + 1;
    } while (cur);

    return 0;
error:
    return -1;
}
コード例 #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
ファイル: operator.c プロジェクト: rfloresx/corto
corto_int16 corto_ptr_binaryOp(corto_type type, corto_operatorKind operator, void *operand1, void *operand2, void *result) {
    if (type->kind == CORTO_PRIMITIVE) {
        corto__binaryOperator impl = corto_binaryOps[corto_primitive(type)->convertId][operator];
        if (impl) {
            impl(operand1, operand2, result);
        } else {
            corto_seterr("binary operator '%s' is not implemented for type '%s'",
              corto_idof(corto_enum_constant(corto_operatorKind_o, operator)),
              corto_fullpath(NULL, type));
            goto error;
        }
    } else if (operator == CORTO_ASSIGN) {
        corto_ptr_copy(operand1, type, operand2);
        if (result && result != operand1) {
            corto_ptr_copy(result, type, operand1);
        }
    } else {
        corto_seterr("invalid operand for non-scalar type");
        goto error;
    }

    return 0;
error:
    return -1;
}
コード例 #4
0
ファイル: value.c プロジェクト: rfloresx/corto
static corto_type corto_valueExpr_getType(corto_type src, corto_type target, corto_bool targetIsRef) {
    corto_type result = src;

    if (!src) {
        if (target) {
            if (target->reference) {
                result = target;
            } else if ((target->kind == CORTO_PRIMITIVE) && (corto_primitive(target)->kind == CORTO_TEXT)) {
                result = corto_type(corto_string_o);
            } else {
                if (targetIsRef) {
                    result = target;
                } else {
                    corto_seterr(
                      "invalid usage of null with non-string and non-reference type '%s'",
                      corto_fullpath(NULL, target));
                    goto error;
                }
            }
        } else {
            result = corto_void_o;
        }
    } else if ((target && (target->kind == CORTO_VOID) && target->reference)) {
        result = corto_object_o;
    }

    return result;
error:
    return NULL;
}
コード例 #5
0
ファイル: dDDS.c プロジェクト: SanderMertens/dDDS
void* _dDDS_getEntity(corto_object o, corto_type type) {
    void* result = NULL;

    if (o && corto_instanceof(type, o)) {
        result = corto_olsGet(o, DDDS_ENTITY_HANDLE);
        if (!result) {
            corto_seterr("%s contains an invalid handle",
              corto_fullpath(NULL, o));
        }
    } else {
        corto_seterr("%s is not of type %s",
          corto_fullpath(NULL, o),
          corto_fullpath(NULL, type));
    }

    return result;
}
コード例 #6
0
ファイル: key.c プロジェクト: hendrenja/corto
corto_bool corto_authorized(corto_object object, corto_secure_actionKind access)
{
    if (corto_checkAttr(object, CORTO_ATTR_NAMED)) {
        corto_id objectId;
        corto_fullpath(objectId, object);
        return corto_authorizedId(objectId, access);
    } else {
        return TRUE;
    }
}
コード例 #7
0
ファイル: attributes.c プロジェクト: cortoproject/examples
void printAttr(corto_object o) {
    printf("attributes of %s: ", corto_fullpath(NULL, o));
    if (corto_checkAttr(o, CORTO_ATTR_SCOPED)) printf("S");
    if (corto_checkAttr(o, CORTO_ATTR_WRITABLE)) printf("W");
    if (corto_checkAttr(o, CORTO_ATTR_OBSERVABLE)) printf("O");
    if (corto_checkAttr(o, CORTO_ATTR_PERSISTENT)) printf("P");
    if (corto_attrof(o) == 0) {
        printf("none");
    }
    printf("\n");
}
コード例 #8
0
ファイル: operator.c プロジェクト: daltonwang/corto
corto_int16 corto_binaryOperator(corto_type type, corto_operatorKind operator, void *operand1, void *operand2, void *result) {
    if (type->kind == CORTO_PRIMITIVE) {
        corto__binaryOperator impl = corto_binaryOps[corto_primitive(type)->convertId][operator];
        if (impl) {
            impl(operand1, operand2, result);
        } else {
            corto_seterr("binary operator '%s' is not implemented for type '%s'",
              corto_idof(corto_enum_constant(corto_operatorKind_o, operator)),
              corto_fullpath(NULL, type));
            goto error;
        }
    }

    return 0;
error:
    return -1;
}
コード例 #9
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;
}
コード例 #10
0
ファイル: objects.c プロジェクト: cortoproject/examples
 *
 * 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);
コード例 #11
0
ファイル: string_deser.c プロジェクト: hendrenja/corto
/* 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;
}
コード例 #12
0
ファイル: string_deser.c プロジェクト: hendrenja/corto
/* Parse string */
static corto_string corto_string_deserParse(
    corto_string str,
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data)
{
    corto_char ch;
    corto_char *ptr, *bptr, *nonWs;
    corto_char buffer[CORTO_STRING_DESER_TOKEN_MAX]; /* TODO: dangerous in a recursive function */
    corto_bool proceed, excess;
    struct corto_string_deserIndexInfo* memberInfo;

    CORTO_UNUSED(info);

    ptr = str;
    bptr = buffer;
    nonWs = bptr;
    proceed = TRUE;
    excess = FALSE;
    memberInfo = NULL;

    if (info) {
        memberInfo = corto_string_deserIndexNext(data);
    }

    /* If ptr == NULL, an error has occurred. If proceed == FALSE, this function
     * has finished processing the current value. */
    while(ptr && (ch = *ptr) && proceed) {
        switch(ch) {
        case '=': /* Explicit member assignment */
            excess = FALSE;
            if (buffer == bptr) {
                corto_seterr("missing member identifier");
                goto error;
            } else {
                *nonWs = '\0';
                memberInfo = corto_string_deserIndexLookup(buffer, data);
                bptr = buffer;
                nonWs = bptr;
                if (!memberInfo) {
                    corto_seterr("member '%s' not found in type '%s'", buffer, corto_fullpath(NULL, data->type));
                    goto error;
                }
                break;
            }

        case '{': /* Scope open */
            if (bptr == buffer) {
                if (!(ptr = corto_string_deserParseScope(
                    ptr,
                    memberInfo,
                    data))) {
                    goto error;
                }
            } else {
                *bptr = '\0';
                if (!(ptr = corto_string_parseAnonymous(
                    ptr,
                    buffer,
                    memberInfo,
                    data))) {
                    goto error;
                }
                bptr = buffer;
            }
            break;

        case '}': /* Scope close and end of value */
            if (buffer != bptr) {
                *nonWs = '\0';
                if (memberInfo && (data->type->kind != CORTO_PRIMITIVE)) {
                    if (corto_string_deserParseValue(buffer, memberInfo, data)) {
                        goto error;
                    }
                    bptr = buffer;
                    nonWs = bptr;
                }
            }
            proceed = FALSE;
            ptr--;
            break;

        case '(':
            /* If a value is being parsed, the '(' is part of an argument list.
             * Parse up until the matching ')' */
            if (bptr != buffer) {
                char *start = ptr;

                /* Parse until matching '} */
                do {
                    *bptr = ch;
                    bptr++;
                    ptr++;
                } while((ch = *ptr) && (ch == ')'));

                ptr--;
                nonWs = bptr;

                /* ptr must always end with a '}' */
                if (*ptr != ')') {
                    corto_seterr("missing ')' at '%s' (%s)", start, ptr);
                    goto error;
                }
            }


        case '"':
            if (!(ptr = corto_string_deserParseString(ptr, buffer, &bptr))) {
                goto error;
            }
            nonWs = bptr;
            ptr--;
            break;
        case '\'':
            if (!(ptr = corto_string_deserParseCharacter(ptr+1, buffer))) {
                goto error;
            }
            *(++bptr) = '\0';
            nonWs = bptr;
            break;

        case '\n':
        case '\t':
        case ' ':
            if (bptr != buffer) {
                *bptr = ch;
                bptr++;
            }
            break;

        case ',': /* End of value */
            if (buffer != bptr) {
                *nonWs = '\0';
                if (corto_string_deserParseValue(buffer, memberInfo ? memberInfo : info, data)) {
                    goto error;
                }
                bptr = buffer;
                nonWs = bptr;
            }

            /* If memberInfo contains a member, get next member, otherwise it contains
             * an element. The same information applies to each element therefore it is only present
             * once in the index. */
            if (memberInfo) {
                if (memberInfo->m) {
                    memberInfo = corto_string_deserIndexNext(data);
                    if (!memberInfo) {
                        excess = TRUE;
                    }
                }
                data->current++;
            } else {
                /* A comma without memberInfo means that a discriminator of a
                 * union was parsed */
                proceed = FALSE;
            }
            break;
        default:
            *bptr = ch;
            bptr++;
            nonWs = bptr;
            break;
        }
        if (ptr && *ptr) ptr++;
    }

    if (bptr != buffer) {
        struct corto_string_deserIndexInfo info;
        *nonWs = '\0';
        info.type = data->type;
        info.parsed = FALSE;
        info.m = NULL;
        if (corto_string_deserParseValue(buffer, &info, data)) {
            goto error;
        }
    }

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

    return ptr;
error:
    return NULL;
}
コード例 #13
0
ファイル: string_deser.c プロジェクト: hendrenja/corto
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;
}
コード例 #14
0
ファイル: string_deser.c プロジェクト: hendrenja/corto
/* Parse value */
static corto_int16 corto_string_deserParseValue(
    corto_string value,
    struct corto_string_deserIndexInfo* info,
    corto_string_deser_t* data)
{
    void *offset;
    if (corto_string_getDestinationPtr(info, data, &offset)) {
        corto_seterr("%s: %s", value, corto_lasterr());
        goto error;
    }

    /* No more elements where available in the index, meaning an excess element */
    if (!info) {
        corto_seterr("excess elements in scope @ '%s'", value);
        goto error;
    }

    /* Can typically occur when mixing short with default notation. */
    if (info->parsed) {
        corto_seterr("member '%s' is already parsed", corto_idof(info->m));
        goto error;
    }

    /* Only parse references and primitives */
    if (info->type->reference) {
        corto_object o = NULL;
        corto_uint32 index = 0;

        /* Resolve object */
        if (corto_string_deserParseAnonymousId(value, &index)) {
            if (!index) {
                if (data->isObject) {
                    o = data->out;
                    corto_claim(o);
                } else {
                    corto_seterr("cannot refer to self (<0>), not deserializing an object");
                    goto error;
                }
            } else if (data->anonymousObjects && (index <= corto_ll_size(data->anonymousObjects))) {
                o = corto_ll_get(data->anonymousObjects, index - 1);
                corto_claim(o);
            } else {
                corto_seterr("undefined anonymous identifier '%s'", value);
                goto error;
            }
        } else {
            o = corto_resolve(data->scope, value);
        }

        if (o || !strcmp(value, "null")) {
            if (offset) corto_ptr_setref(offset, o);
            if (o) corto_release(o);
        } else {
            corto_seterr("unresolved reference to '%s' for member '%s'", value,
                corto_fullpath(NULL, info->m));
            goto error;
        }
    } else

    /* Convert string to primitive value */
    if (offset && (info->type->kind == CORTO_PRIMITIVE)) {
        if (corto_primitive(info->type)->kind != CORTO_TEXT) {
            if (corto_ptr_cast(corto_primitive(corto_string_o), &value, corto_primitive(info->type), offset)) {
                goto error;
            }
        } else {
            corto_uint32 length;
            corto_string deserialized;

            if (strcmp(value, "null")) {
                length = strlen(value);
                deserialized = corto_alloc(length+1);
                memcpy(deserialized, value, length);
                deserialized[length] = '\0';
            } else {
                deserialized = NULL;
            }

            corto_ptr_setstr(offset, deserialized);
        }
    }

    /* Members are only parsed once */
    if (info->m) {
        info->parsed = TRUE;
    }

    return 0;
error:
    return -1;
}
コード例 #15
0
ファイル: Connector.c プロジェクト: cortoproject/mqtt
static void mqtt_onMessage(
    struct mosquitto *client,
    void *data,
    const struct mosquitto_message *msg)
{
    corto_id nameBuffer;
    char *name = nameBuffer;
    corto_object o = NULL;
    mqtt_Connector this = data;
    corto_bool isDelete = FALSE;

    /* If the payload has been serialized as a corto string, the typename is
     * potentially prefixed to the value */
    char *valueStr = strchr(msg->payload, '{');

    /* mqtt is the owner of this thread. This ensures that all subsequent create
     * update / delete actions are performed with the right owner. Ownership
     * ensures to not trigger on own updates, and to only forward data from
     * other connectors (or the application). */
    corto_object prevOwner = corto_setOwner(this);

    /* Remove topic from name, so that name is relative to mount point. */
    strcpy(name, msg->topic);
    if (this->topic) {
        name += strlen(this->topic) + 1;
    }

    char *lastElem = strrchr(name, '/');
    if (lastElem && !strcmp(lastElem, "/_d")) {
        *lastElem = '\0';
        isDelete = TRUE;
    }

    corto_debug("mqtt: %s: received '%s'", msg->topic, msg->payload);

    /* If object doesn't yet exist in the store, create it */
    if (!(o = corto_lookup(corto_mount(this)->mount, name)) && !isDelete) {
        corto_id buffer;
        corto_debug("mqtt: creating new object for '%s'", name);

        /* If the mount has been configured with a fixed type, use that type to
         * create a new object. Otherwise, look for type in payload. */
        if (corto_observer(this)->type) {
            strcpy(buffer, corto_observer(this)->type);
        } else {
            char *typeStr = strchr(msg->payload, '{');
            memcpy(buffer, msg->payload, typeStr - (char*)msg->payload);
            buffer[typeStr - (char*)msg->payload] = '\0';
        }

        /* Resolve type. If type wasn't yet loaded in corto, corto_resolve will
         * do a lookup on the package repository. If it doesn't exist there
         * either throw an error. Currently, the MQTT connector does not align
         * types. */
        corto_type type = corto_resolve(NULL, buffer);
        if (!type) {
            corto_error("mqtt: type '%s' not found", buffer);
            goto error;
        }

        corto_debug("mqtt: creating '%s' with type '%s'", name, buffer);

        /* Create a new object under the mountpoint. The name is derived from
         * the MQTT topic name. */
        o = corto_declareChild(corto_mount(this)->mount, name, type);
        if (!o) {
            corto_error("mqtt: failed to create object '%s'", name);
            goto error;
        }
    } else {
        corto_debug("mqtt: found '%s' for '%s'", corto_fullpath(NULL, o), name);
    }

    /* Only continue updating object when it is owned by mqtt */
    if (o && corto_owned(o)) {
        if (isDelete) {
            if (corto_delete(o)) {
                corto_error("mqtt: failed to delete '%s': %s", name, corto_lasterr());
            }
            corto_release(o);
        } else {
            /* Start updating object (takes a writelock) */
            if (!corto_updateBegin(o)) {
                /* Serialize value from JSON string */
                if (corto_fromcontent(o, "text/json", valueStr)) {
                    corto_error("mqtt: failed to deserialize for %s: %s (%s)\n",
                        name,
                        corto_lasterr(),
                        msg->payload);

                    /* If deserialization fails, cancel the update. No notification
                     * will be sent. */
                    corto_updateCancel(o);
                    goto error;
                }
                /* Successful update. Send notification and unlock object */
                if (corto_updateEnd(o)) {
                    corto_error("mqtt: failed to update '%s': %s", name, corto_lasterr());
                    goto error;
                }
            } else {
                /* For some reason, couldn't start updating object */
                corto_error("mqtt: failed to start updating '%s': %s", name, corto_lasterr());
                goto error;
            }
        }
    } else if (o) {
        corto_debug("mqtt: '%s' not owned by me (%s, defined = %d), ignoring",
            corto_fullpath(NULL, o),
            corto_ownerof(o) ? corto_fullpath(NULL, o) : "local",
            corto_checkState(o, CORTO_DEFINED));
    }

error:
    /* Restore previous owner */
    corto_setOwner(prevOwner);
}
コード例 #16
0
ファイル: json_deser.c プロジェクト: cortoproject/json
static corto_int16 json_deserComposite(void* p, corto_type t, JSON_Value *v)
{
    corto_assert(t->kind == CORTO_COMPOSITE, "not deserializing composite");

    if (json_value_get_type(v) != JSONObject) {
        corto_seterr("expected object, got %s", json_valueTypeToString(v));
        goto error;
    }

    JSON_Object* o = json_value_get_object(v);
    size_t count = json_object_get_count(o);
    size_t i;
    corto_bool isUnion = corto_interface(t)->kind == CORTO_UNION;
    corto_int32 discriminator = 0;
    corto_member unionMember = NULL;

    for (i = 0; i < count; i++) {
        const char* memberName = json_object_get_name(o, i);
        corto_member member_o;

        if (!strcmp(memberName, "super")) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserItem(p, corto_type(corto_interface(t)->base), value)) {
                goto error;
            }
        } else if (!strcmp(memberName, "_d") && isUnion) {
            JSON_Value* value = json_object_get_value(o, memberName);
            if (json_deserPrimitive(&discriminator, corto_union(t)->discriminator, value)) {
                goto error;
            }
            unionMember = corto_union_findCase(t, discriminator);
            if (!unionMember) {
                corto_seterr("discriminator '%d' invalid for union '%s'",
                    discriminator, corto_fullpath(NULL, t));
            }
        } else {
            member_o = corto_interface_resolveMember(t, (char*)memberName);

            /* Ensure that we're not resolving members from a base type */
            if (!member_o || (corto_parentof(member_o) != t)) {
                corto_seterr(
                    "cannot find member '%s' in type '%s'",
                    memberName,
                    corto_fullpath(NULL, t));
                goto error;
            }

            if (isUnion && (unionMember != member_o)) {
                corto_seterr(
                    "member '%s' does not match discriminator '%d' (expected member '%s')",
                    memberName,
                    discriminator,
                    corto_idof(unionMember));
                goto error;
            } else if (isUnion) {
                corto_int32 prev = *(corto_int32*)p;
                if (prev != discriminator) {
                    corto_member prevMember = corto_union_findCase(t, prev);
                    corto_deinitp(CORTO_OFFSET(p, prevMember->offset), prevMember->type);
                    memset(CORTO_OFFSET(p, member_o->offset), 0, member_o->type->size);
                }
                *(corto_int32*)p = discriminator;
            }

            if (!json_deserMustSkip(member_o, p)) {
                JSON_Value* value = json_object_get_value(o, memberName);
                void *offset = CORTO_OFFSET(p, member_o->offset);
                if (member_o->modifiers & CORTO_OBSERVABLE) {
                    offset = *(void**)offset;
                    if (json_deserType(offset, member_o->type, value)) {
                        goto error;
                    }
                } else {
                    if (member_o->modifiers & CORTO_OPTIONAL) {
                        if (*(void**)offset) {
                            corto_deinitp(*(void**)offset, member_o->type);
                            memset(*(void**)offset, 0, member_o->type->size);
                        } else {
                            *(void**)offset = corto_calloc(member_o->type->size);
                        }
                        offset = *(void**)offset;
                    }
                    if (json_deserItem(offset, member_o->type, value)) {
                        goto error;
                    }
                }
            }
        }
    }

    return 0;
error:
    return -1;
}
コード例 #17
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)));
}
コード例 #18
0
ファイル: member.c プロジェクト: hendrenja/corto
/* This is a managed file. Do not delete this comment. */

#include <corto/corto.h>

#include "interface.h"

int16_t corto_member_construct(
    corto_member this)
{
    if (!this->type) {
        corto_seterr("member '%s' has no type", corto_fullpath(NULL, this));
        goto error;
    }

    if (corto_instanceof(corto_native_type_o, this->type) &&
        !(this->modifiers & CORTO_LOCAL))
    {
        corto_seterr("member '%s' of native type '%s' is not local",
            corto_fullpath(NULL, this),
            corto_fullpath(NULL, this->type));
        goto error;
    }

    if (this->type->flags & CORTO_TYPE_HAS_TARGET) {
        ((corto_type)corto_parentof(this))->flags |= CORTO_TYPE_HAS_TARGET;
    }

    if (corto_typeof(this->type) == (corto_type)corto_target_o) {
        this->modifiers |= CORTO_OBSERVABLE;
    }
コード例 #19
0
ファイル: value.c プロジェクト: rfloresx/corto
corto_int16 corto_valueExpr_getTypeForBinary(
    corto_type leftType,
    corto_bool t1ByRef,
    corto_type rightType,
    corto_bool t2ByRef,
    corto_operatorKind _operator,
    corto_type *operandType,
    corto_type *resultType)
{
    corto_type castType = NULL;
    corto_bool equal = FALSE;

    corto_assert(operandType != NULL, "NULL provided for out-parameter operandType");
    corto_assert(resultType != NULL, "NULL provided for out-parameter resultType");

    /* If operator is condition result type is a boolean */
    if (corto_valueExpr_isOperatorConditional(_operator)) {
        *resultType = corto_type(corto_bool_o);
    }

    /* Get leftType and rightType */
    if (!(leftType = corto_valueExpr_getType(leftType, NULL, FALSE))) {
        goto error;
    }

    if (!(rightType = corto_valueExpr_getType(rightType, leftType, t1ByRef))) {
        goto error;
    }

    if (!leftType) {
        leftType = rightType;
    }

    /* If objects are not scoped, verify whether they're equal */
    if (!corto_checkAttr(leftType, CORTO_ATTR_NAMED) && !corto_checkAttr(rightType, CORTO_ATTR_NAMED)) {
        if (corto_compare(leftType, rightType) == CORTO_EQ) {
            equal = TRUE;
        }
    } else {
        equal = leftType == rightType;
    }

    if (_operator == CORTO_DIV) {
        castType = corto_type(corto_float64_o);
    } else if (!equal) {
        /* Can only cast between primitive types */
        if ((leftType->kind == CORTO_PRIMITIVE ) && (rightType->kind == CORTO_PRIMITIVE)) {
            corto_primitive ltype = corto_primitive(leftType), rtype = corto_primitive(rightType);
            corto_int8 lscore, rscore;
            corto_int8 lCastScore, rCastScore;

            lscore = corto_valueExpr_getTypeScore(ltype);
            rscore = corto_valueExpr_getTypeScore(rtype);
            lCastScore = corto_valueExpr_getCastScore(ltype);
            rCastScore = corto_valueExpr_getCastScore(rtype);

            /* If expression is an assignment, always take type of lvalue.
             * Otherwise determine based on expressibility score which type to
             * cast to. */
            if (corto_valueExpr_isOperatorAssignment(_operator)) {
                if (lCastScore == rCastScore) {
                    if (ltype->width != rtype->width) {
                        castType = leftType;
                    }
                } else {
                    castType = leftType;
                }
            } else {
                if (lCastScore == rCastScore) {
                    if (ltype->width == rtype->width) {
                        /* If width and kind are equal, no conversion is required. */
                        if (lscore > rscore) {
                            *operandType = leftType;
                        } else if (lscore < rscore) {
                            *operandType = rightType;
                        }
                    } else {
                        /* If lvalue has a larger width than rvalue, cast rvalue to leftType (and vice versa) */
                        if (ltype->width > rtype->width) {
                            castType = leftType;
                        } else {
                            castType = rightType;
                        }
                    }

                /* If kinds do not match figure a cast is potentially needed. Figure out which type to cast to */
                } else {
                    if (lscore > rscore) {
                        castType = leftType;
                    } else {
                        castType = rightType;
                    }
                }
            }
        } else if (leftType->reference && rightType->reference) {
            castType = NULL;
            /* Check if types are compatible */

        } else if ((rightType->reference || (t2ByRef)) && !leftType->reference) {
            if (corto_type_castable(leftType, corto_object_o)) {
                castType = leftType;
            }
        } else {
            corto_seterr("cannot cast from '%s' to '%s'",
                    corto_fullpath(NULL, leftType),
                    corto_fullpath(NULL, rightType));
            goto error;
        }
    } else if ((rightType->reference || (t2ByRef)) && !leftType->reference) {
        if (corto_type_castable(leftType, corto_object_o)) {
            castType = leftType;
        }
    }

    if (!castType) {
        castType = leftType;
    }
    if (castType) {
        *operandType = castType;
    }
    if (!*resultType) {
        *resultType = *operandType;
    }

    return 0;
error:
    return -1;
}
コード例 #20
0
ファイル: string_deser.c プロジェクト: hendrenja/corto
/* 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;
}