static corto_int16 corto_ser_initObservable( corto_walk_opt* s, corto_value* v, void* userData) { corto_member m = v->is.member.member; int create_mask = CORTO_DECLARE|CORTO_FORCE_TYPE|CORTO_DEFINE; /* Initialize member to a new object of member type */ corto_type t = corto_value_typeof(v); corto_object p = corto_value_objectof(v); void* ptr = corto_value_ptrof(v); if ((m->modifiers & CORTO_SINGLETON) == CORTO_SINGLETON) { /* If member is a singleton, create observable member in the scope of * the composite type */ p = corto_parentof(t); } else { /* If this is a regular observable member, create object as orphan */ create_mask |= CORTO_ORPHAN; } /* Create observable that is not added to the scope of its parent */ corto_object o = corto(create_mask, { .parent = p, .id = corto_idof(m), .type = t });
int16_t corto_value_field( corto_value *val, const char* field_expr, corto_value *out) { corto_type t = corto_value_typeof(val); corto_object o = corto_value_objectof(val); void *ptr = corto_value_ptrof(val); corto_field field = {0}; ut_try(corto_field_lookup(field_expr, t, ptr, &field), NULL); if (field.index != -1) { *out = corto_value_element(o, field.type, field.index, field.ptr); } else if (!field.member && !field.is_super) { if (o == ptr) { *out = corto_value_base(field.ptr, field.type); } else { /* super member of a nested sub-struct */ *out = corto_value_pointer(field.ptr, field.type); } } else { if (field.is_super) { *out = corto_value_base(field.ptr, field.type); } else { *out = corto_value_member(o, field.member, field.ptr); } } return 0; error: return -1; }
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; }
corto_int16 corto_ser_initObservable(corto_walk_opt* s, corto_value* v, void* userData) { corto_member m = v->is.member.t; /* Initialize member to a new object of member type */ corto_type t = corto_value_typeof(v); corto_object p = corto_value_objectof(v); void* ptr = corto_value_ptrof(v); /* Create observable that is not added to the scope of its parent */ corto_attr prev = corto_setAttr(CORTO_OBSERVABLE); corto_object o = corto_createOrphan(p, corto_idof(m), t); corto_setAttr(prev); if (!o) { goto error; } *(corto_object*)ptr = o; return corto_walk_observable(s, v, userData); error: return -1; }