Пример #1
0
static void
extractReferences(
    c_type type,
    c_object o,
    c_voidp data)
{
    switch (c_baseObject(type)->kind) {
    case M_STRUCTURE:
    case M_EXCEPTION:
        extractStructReferences(c_structure(type),o,data);
    break;
    case M_CLASS:
        if (c_class(type)->extends != NULL) {
            extractReferences(c_type(c_class(type)->extends),o,data);
        }
    case M_INTERFACE:
        extractInterfaceReferences(c_interface(type),o,data);
    break;
    case M_UNION:
    break;
    default:
    break;
    }

}
Пример #2
0
void
in_messageDeserializerReadClass(
    in_messageDeserializer _this,
    c_type type,
    c_voidp data)
{
    c_class cls;
    in_messageDeserializerPropertyActionArg arg;

    assert(_this);
    assert(in_messageDeserializerIsValid(_this));
    assert(type);
    assert(data);

    cls = c_class(type);

    arg.object = data;
    arg.transformer = _this; /* no need to increase ref count, obviously */

    /* Walk over all properties of the class */
    c_metaWalk(
        c_metaObject(cls),
        (c_metaWalkAction)in_messageDeserializerReadPropertyAction,
        &arg);
}
Пример #3
0
c_object
c_checkType (
    c_object o,
    const c_char *name)
{
    c_type type;
    c_string str;
    c_bool found = FALSE;
    c_bool stop = FALSE;

    if (o == NULL) {
        return NULL;
    }
    c_assertValidDatabaseObject(o);
    assert(c_refCount(o) > 0);
    assert(name != NULL);
    type = c__getType(o);
    while (!found && !stop) {
        str = c_metaObject(type)->name;
        if (str == NULL) {
            found = TRUE; /** assume TRUE **/
        } else if (strcmp(str,name) != 0) {
            switch (c_baseObject(type)->kind) {
            case M_CLASS:
                type = c_type(c_class(type)->extends);
                if (type == NULL) {
                    if ((strcmp(str,"c_base") == 0) && (strcmp(name,"c_module") == 0)) {
                        found = TRUE;
                    }
                    stop = TRUE;
                }
            break;
            case M_TYPEDEF:
                type = c_typeDef(type)->alias;
                if (type == NULL) {
                    stop = TRUE;
                }
            break;
            default:
              stop = TRUE;
            }
        } else {
            found = TRUE;
        }
    }
    if (!found) {
#ifndef NDEBUG
        if(o != NULL){
            str = c_metaObject(c__getType(o))->name;
            OS_REPORT_2(OS_ERROR, "Database", 0,
                    "Type mismatch: object type is %s but %s was expected\n",
                    str,name);
        }
#endif

        return NULL;
    }
    return o;
}
Пример #4
0
static c_type
createSampleType(
    c_type messageType,
    const c_char* topicName)
{
    c_base base;
    c_type sampleType, baseType, foundType, found;
    c_metaObject o;
    c_char *name;
    c_long length,sres;

    base = c_getBase(messageType);
    baseType = c_resolve(base, "durabilityModule2::d_sample");
    assert(baseType != NULL);

    sampleType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
    c_class(sampleType)->extends = c_class(baseType);

    o = c_metaDefine(c_metaObject(sampleType),M_ATTRIBUTE);
    c_property(o)->type = c_keep(messageType);
    found = c_type(c_metaBind(c_metaObject(sampleType),"message",o));
    c_free(o);
    c_free(found);

    c_metaObject(sampleType)->definedIn = c_keep(base);
    c_metaFinalize(c_metaObject(sampleType));

#define SAMPLE_NAME   "d_sample<>"
#define SAMPLE_FORMAT "d_sample<%s>"
    /* Create a name and bind type to name */
    /* The sizeof contains \0 */
    length = sizeof(SAMPLE_NAME) + strlen(topicName);
    name = os_malloc(length);
    sres = snprintf(name,length,SAMPLE_FORMAT,topicName);
    assert(sres == (length-1));
#undef SAMPLE_NAME
#undef SAMPLE_FORMAT

    foundType = c_type(c_metaBind(c_metaObject(base),
                                  name,
                                  c_metaObject(sampleType)));
    os_free(name);
    c_free(sampleType);

    return foundType;
}
Пример #5
0
static c_type
createInstanceType(
    c_type messageType,
    d_topicInfo topicInfo)
{
    c_type instanceType, baseType, foundType;
    c_metaObject o;
    c_char *name;
    c_long length,sres;
    c_base base;

    base = c_getBase(messageType);
    baseType = c_resolve(base,"durabilityModule2::d_instanceTemplate");
    assert(baseType != NULL);

    instanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
    c_class(instanceType)->extends = c_class(baseType);

    foundType = createTopicKeyType(messageType, topicInfo->keyExpr);

    if ( foundType != NULL) {
        o = c_metaDeclare(c_metaObject(instanceType),"key",M_ATTRIBUTE);
        c_property(o)->type = foundType;
        c_free(o);
    }
    c_metaObject(instanceType)->definedIn = c_keep(base);
    c_metaFinalize(c_metaObject(instanceType));

#define INSTANCE_NAME "d_instance<d_sample<>>"
#define INSTANCE_FORMAT "d_instance<d_sample<%s>>"

    length = sizeof(INSTANCE_NAME) + strlen(topicInfo->name);
    name = os_malloc(length);
    sres = snprintf(name,length,INSTANCE_FORMAT,topicInfo->name);
    assert(sres == (length-1));
#undef INSTANCE_NAME
#undef INSTANCE_FORMAT

    foundType = c_type(c_metaBind(c_metaObject(base),
                                  name,
                                  c_metaObject(instanceType)));
    os_free(name);
    c_free(instanceType);

    return foundType;
}
Пример #6
0
static c_type
messageTypeNew(
    c_base base,
    const c_char *typeName)
{
    c_metaObject o;
    c_type baseType,dataType,type, foundType;
    c_char *name;
    c_long length, sres;

    if (base == NULL) {
        return NULL;
    }
    dataType = c_resolve(base,typeName);
    if (dataType == NULL) {
        return NULL;
    }
    baseType = c_resolve(base, "kernelModule::v_message");
    assert(baseType != NULL);

    type = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
    c_class(type)->extends = c_keep(c_class(baseType));
    o = c_metaDeclare(c_metaObject(type),
                      USERDATA_FIELD_NAME,
                      M_ATTRIBUTE);
    c_property(o)->type = dataType;
    c_free(o);
    c_metaObject(type)->definedIn = c_keep(base);
    c_metaFinalize(c_metaObject(type));


#define MESSAGE_FORMAT "v_message<%s>"
#define MESSAGE_NAME "v_message<>"
    length = sizeof(MESSAGE_NAME) + strlen(typeName);
    name = os_malloc(length);
    sres = snprintf(name,length,MESSAGE_FORMAT,typeName);
    assert(sres == (length-1));
#undef MESSAGE_FORMAT
#undef MESSAGE_NAME
    foundType = c_type(c_metaBind(c_metaObject(base),name,c_metaObject(type)));
    os_free(name);
    c_free(type);

    return foundType;
}
Пример #7
0
v_object
v_new(
    v_kernel kernel,
    c_type type)
{
    v_object o;
    c_type t;
    c_long i;

    assert(C_TYPECHECK(kernel,v_kernel));
    assert(C_TYPECHECK(type,c_type));

    if (type == NULL) {
        return NULL;
    }
    o = c_new(type);
    if (o) {
        o->kernel = kernel;
        t = type;
        while (t != NULL) {
            for (i=0;i<K_TYPECOUNT;i++) {
                if (t == kernel->type[i]) {
                    o->kind = i;
                    return o;
                }
            }
            if (c_baseObject(t)->kind == M_CLASS) {
                t = c_type(c_class(t)->extends);
            } else {
                t = NULL;
            }
        }
        o->kind = K_OBJECT;
    } else {
        OS_REPORT(OS_ERROR,
                  "v_new",0,
                  "Failed to create kernel object.");
        assert(FALSE);
    }
    return o;
}
Пример #8
0
/**************************************************************
 * constructor/destructor
 **************************************************************/
v_serviceState
v_serviceStateNew(
    v_kernel k,
    const c_char *name,
    const c_char *extStateName)
{
    v_serviceState s;
    c_type type;

    assert(C_TYPECHECK(k, v_kernel));

    if (extStateName == NULL) {
        s = v_serviceState(v_objectNew(k, K_SERVICESTATE));
    } else {
        type = c_resolve(c_getBase(c_object(k)), extStateName);
        if (type != NULL) {
#if !defined NDEBUG
            c_type t = type;
            c_bool correctType;
            correctType = FALSE;

            while ((correctType == FALSE) &&
                   (t != NULL) &&
                   (c_baseObject(t)->kind == M_CLASS)) {
                if (strcmp(c_metaObject(t)->name, "v_serviceState") == 0) {
                    correctType = TRUE;
                } else {
                    t = c_type(c_class(t)->extends);
                }
            }

            if ((correctType == FALSE) && (t != NULL)) {
                OS_REPORT(OS_FATAL, "v_serviceState", 0, "Given type not a class");
                assert(0);
            } else {

                if (correctType == FALSE) {
                    OS_REPORT(OS_FATAL, "v_serviceState",
                              0, "Given type does not extend v_serviceState");
                    assert(0);
                }
            }
#endif
            s = v_serviceState(c_new(type));
            if (s) {
                v_objectKind(s) = K_SERVICESTATE;
                v_object(s)->kernel = k;
            } else {
                OS_REPORT(OS_ERROR,
                          "v_serviceStateNew",0,
                          "Failed to allocate v_serviceState object.");
                assert(FALSE);
            }
        } else {
            s = NULL;
        }
    }
    if (s != NULL) {
        v_serviceStateInit(s, name);
    }

    return s;
}
Пример #9
0
static c_type
sampleTypeNew(
    v_topic topic)
{
    c_metaObject o;
    c_type msgType,sampleType,foundType;
    c_base base;
    c_char *name;
    os_size_t length;
    int sres;

    assert(C_TYPECHECK(topic,v_topic));
    assert(topic);

    name = NULL;
    foundType = NULL;

    if (v_topicName(topic) == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic name");
        return NULL;
    }

    base = c_getBase(topic);

    if (base == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive base");
        return NULL;
    }

    msgType = c_keep(v_topicMessageType(topic));

    if (msgType == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic message type");
        return NULL;
    }

    sampleType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
    if (sampleType) {
        c_class(sampleType)->extends = v_dataReaderSample_t(base);
        o = c_metaDeclare(c_metaObject(sampleType),"message",M_ATTRIBUTE);
        if (o) {
            c_property(o)->type = c_keep(msgType);
            c_metaObject(sampleType)->definedIn = c_keep(base);
            c_metaFinalize(c_metaObject(sampleType));

#define SAMPLE_FORMAT "v_indexSample<%s>"
#define SAMPLE_NAME   "v_indexSample<>"
            /* sizeof contains \0 */
            length = sizeof(SAMPLE_NAME) + strlen(v_topicName(topic));
            name = os_malloc(length);
            sres = snprintf(name,length,SAMPLE_FORMAT,v_topicName(topic));
            assert(sres >= 0 && (os_size_t) sres == (length-1));
            OS_UNUSED_ARG(sres);
#undef SAMPLE_FORMAT
#undef SAMPLE_NAME

            foundType = c_type(c_metaBind(c_metaObject(base),
                                          name,
                                          c_metaObject(sampleType)));
            c_free(o);
        } else {
            foundType = NULL;
        }
        c_free(sampleType);
    } else {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic sample type");
    }
    os_free(name);
    c_free(msgType);

    return foundType;
}
Пример #10
0
static c_type
createInstanceType (
    v_topic topic,
    c_char *keyExpr,
    c_array *keyListRef)
{
    c_metaObject o;
    c_type instanceType, baseType, foundType;
    c_type sampleType, keyType, keyInstanceType;
    c_base base;
    c_char *name;
    os_size_t length;
    int sres;

    assert(C_TYPECHECK(topic,v_topic));

    foundType = NULL;
    if (keyExpr) {
        keyType = v_topicKeyTypeCreate(topic,keyExpr,keyListRef);
    } else {
        keyExpr = v_topicKeyExpr(topic);
        keyType = v_topicKeyType(topic);
        *keyListRef = c_keep(v_topicMessageKeyList(topic));
    }
    sampleType = sampleTypeNew(topic);
    if (sampleType) {
        base = c_getBase(topic);
        baseType = v_dataReaderInstance_t(base);
        instanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
        if (instanceType != NULL) {
            c_class(instanceType)->extends = c_keep(c_class(baseType));
            o = c_metaDeclare(c_metaObject(instanceType),
                              "sample",M_ATTRIBUTE);
            c_property(o)->type = c_keep(sampleType);
            c_free(o);
            o = c_metaDeclare(c_metaObject(instanceType),
                              "oldest",M_ATTRIBUTE);
            c_property(o)->type = (c_type)c_metaResolveType(c_metaObject(base),
                                                    "c_voidp");
            assert(c_property(o)->type);
            c_free(o);
            c_metaFinalize(c_metaObject(instanceType));
#define INSTANCE_NAME   "v_indexInstance<v_indexSample<>>"
#define INSTANCE_FORMAT "v_indexInstance<v_indexSample<%s>>"
            /* The sizeof contains \0 */
            length = sizeof(INSTANCE_NAME) + strlen(v_topicName(topic));
            name = os_alloca(length);
            sres = snprintf(name,length,INSTANCE_FORMAT,v_topicName(topic));
            assert(sres >= 0 && (os_size_t) sres == (length-1));
            OS_UNUSED_ARG(sres);
#undef INSTANCE_NAME
#undef INSTANCE_FORMAT
            foundType = c_type(c_metaBind(c_metaObject(base),
                                          name,
                                          c_metaObject(instanceType)));
            if (foundType == NULL) {
                OS_REPORT(OS_ERROR,
                        "v_index::createInstanceType",V_RESULT_INTERNAL_ERROR,
                        "Could not create instance type");
            }

            os_freea(name);

            if (keyType != NULL) {
                keyInstanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
                if (keyInstanceType) {
                    c_class(keyInstanceType)->extends = c_keep(c_class(instanceType));
                    o = c_metaDeclare(c_metaObject(keyInstanceType),
                                      "key",M_ATTRIBUTE);
                    c_property(o)->type = c_keep(keyType);
                    c_free(o);
                    c_metaFinalize(c_metaObject(keyInstanceType));
#define INSTANCE_NAME   "v_indexKeyInstance<v_indexSample<>,>"
#define INSTANCE_FORMAT "v_indexKeyInstance<v_indexSample<%s>,%s>"
                    /* The sizeof contains \0 */
                    length = sizeof(INSTANCE_NAME) +
                             strlen(v_topicName(topic)) +
                             strlen(keyExpr);
                    name = os_alloca(length);
                    sres = snprintf(name,
                                    length,
                                    INSTANCE_FORMAT,
                                    v_topicName(topic),
                                    keyExpr);
                    assert(sres >= 0 && (os_size_t) sres == (length-1));
                    OS_UNUSED_ARG(sres);
#undef INSTANCE_NAME
#undef INSTANCE_FORMAT
                    c_free(foundType); /* Will be overwritten, so free */
                    foundType = c_type(c_metaBind(c_metaObject(base),
                                                  name,
                                                  c_metaObject(keyInstanceType)));
                    if (foundType == NULL) {
                        OS_REPORT(OS_ERROR,
                                  "v_index::createInstanceType",V_RESULT_INTERNAL_ERROR,
                                  "Could not create key instance type");
                    }
                    os_freea(name);
                    c_free(keyInstanceType);
                }
                c_free(keyType);
            }
            c_free(instanceType);
            c_free(baseType);
        } else {
            foundType = baseType; /* transfer refCount to caller */
        }
        c_free(sampleType);
    }

    return foundType;
}
Пример #11
0
static c_bool
c__cloneReferences (
    c_type type,
    c_voidp data,
    c_voidp dest)
{
    c_type refType;
    c_class cls;
    c_array references, labels, ar, destar;
    c_sequence seq, destseq;
    c_property property;
    c_member member;
    c_long i,j,length,size;
    c_long nrOfRefs,nrOfLabs;
    c_value v;

    switch (c_baseObject(type)->kind) {
    case M_CLASS:
		cls = c_class(type);
		while (cls) {
			length = c_arraySize(c_interface(cls)->references);
			for (i=0;i<length;i++) {
				property = c_property(c_interface(cls)->references[i]);
				refType = property->type;
				_cloneReference(refType,
						C_DISPLACE(data, property->offset),
						C_DISPLACE(dest, property->offset));
			}
			cls = cls->extends;
		}
    break;
    case M_INTERFACE:
        length = c_arraySize(c_interface(type)->references);
        for (i=0;i<length;i++) {
            property = c_property(c_interface(type)->references[i]);
            refType = property->type;
			_cloneReference(refType,
					C_DISPLACE(data, property->offset),
					C_DISPLACE(dest, property->offset));
        }
    break;
    case M_EXCEPTION:
    case M_STRUCTURE:
        length = c_arraySize(c_structure(type)->references);
        for (i=0;i<length;i++) {
            member = c_member(c_structure(type)->references[i]);
            refType = c_specifier(member)->type;
			_cloneReference(refType,
					C_DISPLACE(data, member->offset),
					C_DISPLACE(dest, member->offset));
        }
    break;
    case M_UNION:
#define _CASE_(k,t) case k: v = t##Value(*((t *)data)); break
        switch (c_metaValueKind(c_metaObject(c_union(type)->switchType))) {
        _CASE_(V_BOOLEAN,   c_bool);
        _CASE_(V_OCTET,     c_octet);
        _CASE_(V_SHORT,     c_short);
        _CASE_(V_LONG,      c_long);
        _CASE_(V_LONGLONG,  c_longlong);
        _CASE_(V_USHORT,    c_ushort);
        _CASE_(V_ULONG,     c_ulong);
        _CASE_(V_ULONGLONG, c_ulonglong);
        _CASE_(V_CHAR,      c_char);
        _CASE_(V_WCHAR,     c_wchar);
        default:
            OS_REPORT(OS_ERROR,
                      "c__cloneReferences",0,
                      "illegal union switch type detected");
            assert(FALSE);
            return FALSE;
        break;
        }
#undef _CASE_
        references = c_union(type)->references;
        if (references != NULL) {
            i=0; refType=NULL;
            nrOfRefs = c_arraySize(references);
            while ((i<nrOfRefs) && (refType == NULL)) {
                labels = c_unionCase(references[i])->labels;
                j=0;
                nrOfLabs = c_arraySize(labels);
                while ((j<nrOfLabs) && (refType == NULL)) {
                    if (c_valueCompare(v,c_literal(labels[j])->value) == C_EQ) {
                        c__cloneReferences(c_type(references[i]),
                                           C_DISPLACE(data, c_type(type)->alignment),
                                           C_DISPLACE(dest, c_type(type)->alignment));
                        refType = c_specifier(references[i])->type;
                    }
                    j++;
                }
                i++;
            }
        }
    break;
    case M_COLLECTION:
        refType = c_typeActualType(c_collectionType(type)->subType);
        switch (c_collectionType(type)->kind) {
        case C_ARRAY:
            ar = c_array(data);
            destar = c_array(dest);
            length = c_collectionType(type)->maxSize;
            if (length == 0) {
                length = c_arraySize(ar);
            }
            if (c_typeIsRef(refType)) {
                for (i=0;i<length;i++) {
                    c_cloneIn(refType, ar[i], &destar[i]);
                }
            } else {
                if (c_typeHasRef(refType)) {
                    size = refType->size;
                    for (i=0;i<length;i++) {
                        _cloneReference(refType, C_DISPLACE(data, (i*size)), C_DISPLACE(dest, (i*size)));
                    }
                }
            }
        break;
        case C_SEQUENCE:
            seq = c_sequence(data);
            destseq = c_sequence(dest);
            length = c_sequenceSize(seq);
            if (c_typeIsRef(refType)) {
                for (i=0;i<length;i++) {
                    c_cloneIn(refType, seq[i], &destseq[i]);
                }
            } else {
                if (c_typeHasRef(refType)) {
                    size = refType->size;
                    for (i=0;i<length;i++) {
                        _cloneReference(refType, C_DISPLACE(seq, (i*size)), C_DISPLACE(dest, (i*size)));
                    }
                }
            }
        break;
        default:
            OS_REPORT(OS_ERROR,
                  "c__cloneReferences",0,
                  "illegal collectionType found");
        break;
        }
    break;
    case M_BASE:
    break;
    case M_TYPEDEF:
        c__cloneReferences(c_type(c_typeDef(type)->alias), data, dest);
    break;
    case M_ATTRIBUTE:
    case M_RELATION:
        refType = c_typeActualType(c_property(type)->type);
        _cloneReference(refType,
        		C_DISPLACE(data, c_property(type)->offset),
        		C_DISPLACE(dest, c_property(type)->offset));
    break;
    case M_MEMBER:
        refType = c_typeActualType(c_specifier(type)->type);
        _cloneReference(refType,
        		C_DISPLACE(data, c_member(type)->offset),
        		C_DISPLACE(dest, c_member(type)->offset));
    break;
    case M_UNIONCASE:
        refType = c_typeActualType(c_specifier(type)->type);
        _cloneReference(refType, data, dest);
    break;
    case M_MODULE:
        /* Do nothing */
    break;
    case M_PRIMITIVE:
        /* Do nothing */
    break;
    case M_EXTENT:
    case M_EXTENTSYNC:
    default:
        OS_REPORT(OS_ERROR,
                  "c__cloneReferences",0,
                  "illegal meta object specified");
        assert(FALSE);
        return FALSE;
    }
    return TRUE;
}
Пример #12
0
struct v_messageExtCdrInfo *
v_messageExtCdrInfoNew(
    c_type topicMessageType,
    const struct sd_cdrControl *control)
{
    static const char headerTypeName[] = "kernelModule::v_messageExt";
    c_base base = c_getBase (topicMessageType);
    c_property userDataProperty = c_property(c_metaResolve(c_metaObject(topicMessageType),"userData"));
    c_type topicDataType = userDataProperty->type;
    c_type headerClass = c_resolve (base, headerTypeName);
    c_type dataClass;
    c_type type;
    c_object o;
    c_array members;
    struct v_messageExtCdrInfo *xci;
    struct c_type_s const *tstk[2];
    c_free(userDataProperty);

    /* Wrap user data in a class, so that we can make a struct with a pointer to it */
    dataClass = c_type(c_metaDefine(c_metaObject(base), M_CLASS));
    c_class(dataClass)->extends = NULL;
    o = c_metaDeclare(c_metaObject(dataClass), "userData", M_ATTRIBUTE);
    c_property(o)->type = c_keep(topicDataType);
    c_metaObject(dataClass)->definedIn = c_keep(base);
    c_metaFinalize(c_metaObject(dataClass));
    c_free(o);

    /* Make a struct containing two pointers, one to the v_messageExt class, and one to
     the just-created anonymous dataClass type, corresponding to struct v_messageExtCdrTmp */
    type = c_type(c_metaDefine(c_metaObject(base),M_STRUCTURE));
    members = c_arrayNew(c_member_t(base),2);
    members[0] = (c_voidp)c_metaDefine(c_metaObject(base),M_MEMBER);
    c_specifier(members[0])->name = c_stringNew(base,"h");
    c_specifier(members[0])->type = c_keep(headerClass);
    members[1] = (c_voidp)c_metaDefine(c_metaObject(base),M_MEMBER);
    c_specifier(members[1])->name = c_stringNew(base,"d");
    c_specifier(members[1])->type = c_keep(dataClass);
    c_structure(type)->members = members;
    c_metaObject(type)->definedIn = c_keep(base);
    c_metaFinalize(c_metaObject(type));
    c_free(dataClass);
    c_free(headerClass);

    xci = os_malloc(sizeof(*xci));
    xci->ci = sd_cdrInfoNewControl(type, control);

    /* Note: current simplistic annotation processing requires the annotations
     to be made in the order in which they are encountered when walking the
     type */
    tstk[0] = type;
    tstk[1] = headerClass;
    if (sd_cdrNoteQuietRef(xci->ci, 2, tstk) < 0) {
        goto err_note;
    }
    tstk[1] = dataClass;
    if (sd_cdrNoteQuietRef(xci->ci, 2, tstk) < 0) {
        goto err_note;
    }

    if (sd_cdrCompile(xci->ci) < 0) {
        goto err_compile;
    }
    xci->vmsgType = c_keep(topicMessageType);
    c_free(type);
    return xci;

err_compile:
err_note:
    os_free(xci);
    c_free(type);
    return NULL;
}