Example #1
0
static c_bool
walkProperty(
    c_metaObject object,
    c_metaWalkActionArg actionArg)
{
    toolActionData actionData = (toolActionData)actionArg;
    c_object o;
    c_voidp addr;

    o = c_iterObject(actionData->stack, 0);

    if (c_baseObjectKind(object) == M_ATTRIBUTE) {
        addr = C_DISPLACE(o, (c_address)c_property(object)->offset);
        if (c_typeIsRef(c_property(object)->type)) {
            addr = *(c_voidp *)addr;
            if (c_baseObjectKind(c_property(object)->type) == M_COLLECTION) {
                if (addr) {
                    if (c_iterContains(actionData->stack, addr)) {
                        printf("Ignore cyclic reference 0x"PA_ADDRFMT"\n",
                               (os_address)addr);
                    } else {
                        OBJECT_PUSH(actionData, addr);
                        iprintf("%s ",_METANAME(object));
                        printType(c_property(object)->type, actionData);
                        OBJECT_POP(actionData);
                    }
                } else {
                    iprintf("    %s <0x"PA_ADDRFMT">", _METANAME(object), (os_address)addr);
                }
            } else {
                iprintf("    %s <0x"PA_ADDRFMT">", _METANAME(object), (os_address)addr);
                if (addr) {
                    /* Section for code to print additional type specific info. */
                    if (c_property(object)->type == v_topic_t) {
                        printf(" /* topic name is: %s */", v_topicName(addr));
                    }
                    if (c_property(object)->type == v_partition_t) {
                        printf(" /* Partition: %s */", v_partitionName(addr));
                    }
                    if (c_property(object)->type == c_type_t(c_getBase(object))) {
                        printf(" /* Type: %s */", _METANAME(c_type(addr)));
                    }
                }
            }
            printf("\n");
        } else {
            OBJECT_PUSH(actionData, addr);
            iprintf("%s ",_METANAME(object));
            printType(c_property(object)->type, actionData);
            printf("\n");
            OBJECT_POP(actionData);
        }
    }
    return TRUE;
}
/* may return null */
in_result
in_messageDeserializerRead(
    in_messageDeserializer _this,
    v_topic topic,
    os_boolean isBigEndian,
    v_message* object)
{
    in_result result = IN_RESULT_OK;
    in_messageTransformer transformer = in_messageTransformer(_this);
    c_object displacedMessage;
    c_type messageType;

    assert(_this);
    assert(in_messageDeserializerIsValid(_this));
    assert(object);
    assert(topic);

    if (topic)
    {
        /* work around, replace cdrLength in transformer by ->length */
        in_messageTransformerSetCdrLength(transformer, (os_ushort) (transformer->length));
        if (_requiresSwap(isBigEndian)) {
            in_messageTransformerSetCopyKind(transformer, IN_MESSAGE_TRANSFORMER_CM_KIND_SWAP);
        } else {
            in_messageTransformerSetCopyKind(transformer, IN_MESSAGE_TRANSFORMER_CM_KIND_COPY);
        }
        messageType = v_topicMessageType(topic);

        if (c_typeIsRef(messageType))
        {
            *object = v_topicMessageNew(topic);

            if(*object == NULL)
            {
                result = IN_RESULT_OUT_OF_MEMORY;
            } else
            {
                displacedMessage = v_topicData(topic, *object);
                in_messageDeserializerReadType(_this, v_topicDataType(topic),
                    displacedMessage);
            }
        } else
        {
            assert(FALSE);
            result = IN_RESULT_ERROR;
            *object = NULL;
        }
    } else
    {
        *object = NULL;
    }
    return result;
}
Example #3
0
static void
printStructure(
    c_structure _this,
    toolActionData actionData)
{
    c_object o;
    c_object object;
    c_long i, size;
    c_member member;

    o = c_iterObject(actionData->stack, 0);

    if (o) {
        if (c_iterLength(actionData->stack) == 1) {
            printf("%s ", _METANAME(_this));
        } else {
        }
        printf("{\n");
        size = c_structureMemberCount(_this);
        for (i=0; i<size; i++) {
            member = c_structureMember(_this, i);
            object = C_DISPLACE(o, (c_address)member->offset);
            if (c_typeIsRef(c_memberType(member))) {
                iprintf("    %s <0x"PA_ADDRFMT">\n",
                       c_specifierName(member),
                       *(os_address *)object);
            } else {
                OBJECT_PUSH(actionData, object);
                iprintf("%s ",c_specifierName(member));
                printType(c_memberType(member), actionData);
                printf("\n");
                OBJECT_POP(actionData);
            }
        }
        if (c_iterLength(actionData->stack) == 1) {
            iprintf("};");
        } else {
            iprintf("} %s;", _METANAME(_this));
        }
        if (c_type(_this) == v_handle_t) {
            v_object vo;
            v_handleClaim(*(v_handle *)o,&vo);
            v_handleRelease(*(v_handle *)o);
            printf(" /* Handle's object: <0x"PA_ADDRFMT"> */", (os_address)vo);
        }
    }
}
/* TODO should propagate the result code, might have an out of memory error
 * if allocation of the array failed
 */
void
in_messageDeserializerReadArray(
    in_messageDeserializer _this,
    c_type type,
    c_voidp data)
{
    in_result result = IN_RESULT_OK;
    c_collectionType ctype = c_collectionType(type);
    os_uint32 size;
    os_uint32 length;
    os_uint32 i;
    c_voidp array = NULL;
    c_object o;
    c_collKind typeKind;
    c_metaKind subTypeKind;

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

    /* First determine the length of the array. For IDL array types the length
     * is known, but for sequences it is encoded ahead of the elements as an
     * unsigned long
     */
    typeKind = ctype->kind;

    if(typeKind == C_ARRAY)
    {
        array = data;
        length = ctype->maxSize;
        assert(array);
    } else
    {
        assert(typeKind == C_SEQUENCE);
        /* For a sequence the length is encoded as an unsigned long, which in
         * CDR is 4 octets(bytes) in size.
         */
        assert(sizeof(os_uint32) == 4);
        in_messageDeserializerReadPrim(_this, 4, &length);
        /* Verify that the length is equal to or smaller then the maxSize if
         * maxSize is bigger then 0
         */
        if(ctype->maxSize > 0)
        {
            array = data;
            assert((c_long)length <= ctype->maxSize);
            assert(array);
        } else
        {
            if(*(c_voidp *)data)
            {
                array = *(c_voidp *)data;
            } else
            {
                array = c_arrayNew(type, (c_long)length);
                if(length > 0 && !array)
                {
                    result = IN_RESULT_OUT_OF_MEMORY;
                }
                *(c_voidp *)data = array;
            }
        }
    }

    if (length > 0 && result == IN_RESULT_OK)
    {
        assert(array);
        subTypeKind = c_baseObjectKind(c_baseObject(ctype->subType));
        if((subTypeKind == M_PRIMITIVE) ||(subTypeKind == M_ENUMERATION))
        {
            o = array;
           /* in_messageDeserializerReadPrimArray(
                _this,
                ctype->subType->size,
                length,
                o);*/
        } else
        {
            if (c_typeIsRef(ctype->subType))
            {
                size = sizeof(c_voidp);
            } else
            {
                size = ctype->subType->size;
            }
            o = array;
            for (i = 0; i < length; i++)
            {
                in_messageDeserializerReadType(_this, ctype->subType, o);
                o = C_DISPLACE(o, size);
            }
        }
    }
}
Example #5
0
static void
printCollection(
    c_collectionType type,
    toolActionData actionData)
{
    c_long size, i, offset, esize;
    c_object o;
    c_voidp p;
    c_object arrayElement;
    c_type subtype;
    c_bool isRef;

    o = c_iterObject(actionData->stack, 0);
    switch (type->kind) {
    case C_ARRAY:
    case C_SEQUENCE:
        /* Walk over all entries */
        switch (type->kind) {
        case C_ARRAY:
            if (type->maxSize == 0) {
                size = c_arraySize((c_array)o);
            } else {
                size = type->maxSize;
            }
        break;
        case C_SEQUENCE:
            size = c_arraySize((c_array)o);
        break;
        default:
            size = 0;
            assert(FALSE);
        break;
        }

        if (c_typeIsRef(type->subType)) {
            esize = sizeof(c_voidp);
            isRef = TRUE;
        } else {
            esize = type->subType->size;
            isRef = FALSE;
        }
        p = o;
        offset = 0;
        for (i=0; i<size; i++) {
            iprintf("Element (%d) Offset (%d)\n",i,offset);
            arrayElement = isRef ? *((c_object *)p) : (c_object) p;
            if (arrayElement != NULL) {
                OBJECT_PUSH(actionData, arrayElement);
                if (isRef) {
                    subtype = c_getType(arrayElement);
                    printType(subtype, actionData);
                } else {
                    iprintf(" ");
                    printType(type->subType, actionData);
                }
                printf("\n");
                OBJECT_POP(actionData);
            } else {
                iprintf("    <0x0>\n");
            }
            p = C_DISPLACE(p, esize);
            offset += esize;
        }
    break;
    case C_STRING:
        printf(" \"%s\"",(c_char *)o);
    break;
    case C_SET:
    case C_LIST:
    case C_BAG:
    case C_DICTIONARY:
    case C_QUERY:
    {
        if (o != NULL) {
            /* Walk over the elements */
            c_walk(o, (c_action)printCollectionAction, actionData);
            if (c_count(o) == 0) {
                iprintf("<EMPTY>");
            }
        } else {
            iprintf("<NULL>");
        }
    }
    break;
    case C_SCOPE:
        c_scopeWalk(o, printCollectionAction, actionData);
    break;
    default:
        printf("Specified type <0x"PA_ADDRFMT"> is not a valid collection type\n",
               (os_address)type);
    break;
    }
}
Example #6
0
static in_result
in_ddsiStreamReaderImplProcessAppdefDataPayloadNoData(
    in_ddsiStreamReaderImpl _this,
    in_ddsiSubmessageData submessage,
    in_connectivityPeerWriter peerWriter,
    v_message *messageObject)
{
	v_topic topic;
	in_result result;
	c_type messageType;
	c_octet* keyHash;

	assert(peerWriter);
	assert(messageObject);
	assert(submessage);

	*messageObject = NULL;
	topic = lookupTopic(_this, peerWriter);

	if(topic)
	{
		messageType = v_topicMessageType(topic);

		if (c_typeIsRef(messageType))
		{
			*messageObject = v_topicMessageNew(topic);

			if(*messageObject)
			{
				(*messageObject)->sequenceNumber = (submessage->writerSN.low);
				(*messageObject)->writerGID = in_connectivityPeerWriterGetGid(
					peerWriter);
				(*messageObject)->allocTime = _this->receiver.haveTimestamp ?
					_this->receiver.timestamp : C_TIME_ZERO;
				(*messageObject)->writeTime = _this->receiver.haveTimestamp ?
					_this->receiver.timestamp : C_TIME_ZERO;

				/* WriterInstanceGID unused in kernel, so not necessary to fill it*/
				(*messageObject)->writerInstanceGID.systemId =
					(*messageObject)->writerGID.systemId;
				(*messageObject)->writerInstanceGID.localId = 0;
				(*messageObject)->writerInstanceGID.serial = 0;
				(*messageObject)->qos = in_messageQos_new(peerWriter,
					c_getBase(topic));

				result = in_ddsiParameterListGetPidKeyHash(
					&(submessage->inlineQos), &keyHash);

				if(result == IN_RESULT_OK)
				{
					result = in_ddsiStreamReaderImplDerializePayloadByKeyHash(
						_this, submessage, peerWriter, topic, messageObject,
						keyHash);
					os_free(keyHash);

					if(result == IN_RESULT_OK)
					{
						result = in_ddsiParameterListGetPidStatusInfo(
										&(submessage->inlineQos),
										&(v_messageState(*messageObject)));
					} else
					{
                        IN_REPORT_WARNING(IN_SPOT, "Unable to copy key values in message.");
					}
				} else
				{
                    IN_REPORT_WARNING(IN_SPOT, "Found DATA submessage without serializedPayload and no PID_KEY_HASH inlineQos.");
					result = IN_RESULT_ERROR;
				}


			} else
			{
				result = IN_RESULT_OUT_OF_MEMORY;
			}
		} else
		{
			result = IN_RESULT_ERROR;
		}
		c_free(topic);
	} else
	{
		result = IN_RESULT_ERROR;
	}
	return result;
}
Example #7
0
void
c_copyOut (
    c_type type,
    c_object o,
    c_voidp *data)
{
    c_long i,size;
    c_type t,subType;

    if (data == NULL) {
        OS_REPORT(OS_ERROR,"Database misc",0,
                  "c_copyOut: no destination specified");
        return;
    }
    if (o == NULL) {
        *data = NULL;
        return;
    }
    t = c_typeActualType(type);
    size = c_typeSize(t);
    if (size == 0) {
        OS_REPORT(OS_WARNING,"Database misc",0,
                  "c_copyOut: zero sized type specified");
        *data = NULL;
        return;
    }
    if (*data == NULL) {
        *data = (c_voidp)os_malloc(size);
    }
    if (c_baseObject(t)->kind == M_COLLECTION) {
        switch(c_collectionType(t)->kind) {
        case C_STRING:
            *data = os_strdup((c_char *)o);
        break;
        case C_LIST:
        case C_BAG:
        case C_SET:
        case C_MAP:
        case C_DICTIONARY:
            OS_REPORT(OS_WARNING,"Database misc",0,
                      "c_copyOut: ODL collections unsupported");
            assert(FALSE);
        break;
        case C_ARRAY:
            size = c_collectionType(t)->maxSize;
            if (size > 0) {
                subType = c_collectionType(t)->subType;
                for (i=0;i<size;i++) {
                    c_copyIn(subType,
                             ((c_voidp *)o)[i],
                             &((c_voidp *)(*data))[i]);
                }
            } else {
                OS_REPORT(OS_WARNING,"Database misc",0,
                          "c_copyOut: dynamic sized arrays unsupported");
            }
        case C_SEQUENCE:
            OS_REPORT(OS_WARNING,"Database misc",0,
                      "c_copyOut: sequences unsupported");
            assert(FALSE);
        break;
        default:
            OS_REPORT_1(OS_ERROR,"Database misc",0,
                        "c_copyOut: unknown collection kind (%d)",
                        c_collectionType(t)->kind);
            assert(FALSE);
        break;
        }
    } else if (c_typeIsRef(t)) {
        memcpy(*data,*(void**)o,size);
        extractReferences(t,*(void**)o,*data);
    } else {
        memcpy(*data,o,size);
        extractReferences(t,o,*data);
    }
}
Example #8
0
void
c_cloneIn (
    c_type type,
    c_voidp data,
    c_voidp *dest)
{
    c_long size,subSize;
    c_type t;

    if (data == NULL) {
        *dest = NULL;
        return;
    }

    t = c_typeActualType(type);
    if (c_baseObject(t)->kind == M_COLLECTION) {
        switch(c_collectionType(t)->kind) {
        case C_STRING:
            *dest = c_stringNew(c_getBase(t), data);
            break;
        case C_LIST:
        case C_BAG:
        case C_SET:
        case C_MAP:
        case C_DICTIONARY:
            OS_REPORT(OS_WARNING,"Database misc",0,
                      "c_cloneIn: ODL collections unsupported");
        break;
        case C_ARRAY:
            subSize = c_collectionType(t)->subType->size;
            size = c_collectionType(t)->maxSize;
            if (size == 0) {
            	size = c_arraySize(data);
                *dest = c_newArray(c_collectionType(t), size);
            }
            if (size > 0) {
                memcpy(*dest, data, size * subSize);
                /* Find indirections */
                c__cloneReferences(t, data, dest);
            }
            break;
        case C_SEQUENCE:
            subSize = c_collectionType(t)->subType->size;
            size = c_sequenceSize(data);
            if (size > 0) {
                *dest = c_newSequence(c_collectionType(t), size);
                memcpy(*dest, data, size * subSize);
                /* Find indirections */
                c__cloneReferences(t, data, dest);
            }
            break;
        break;
        default:
            OS_REPORT_1(OS_ERROR,"Database misc",0,
                        "c_cloneIn: unknown collection kind (%d)",
                        c_collectionType(t)->kind);
            assert(FALSE);
        break;
        }
    } else if (c_typeIsRef(t)) {
        *dest = c_new(t);
        memcpy(*dest, data, t->size);
        /* Find indirections */
        c__cloneReferences(t, data, *dest);
    } else {
        memcpy(*dest, data, t->size);
        /* Find indirections */
        c__cloneReferences(t, data, *dest);
    }
}
Example #9
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;
}
Example #10
0
void
c_copyIn (
    c_type type,
    c_voidp data,
    c_voidp *dest)
{
    c_long size, subSize, i;
    c_type t, refType;

    if (data == NULL) {
        *dest = NULL;
        return;
    }
    t = c_typeActualType(type);
    if (c_baseObject(t)->kind == M_COLLECTION) {
        switch(c_collectionType(t)->kind) {
        case C_STRING:
            *dest = c_stringNew(c_getBase(t),data);
            return;
        case C_LIST:
        case C_BAG:
        case C_SET:
        case C_MAP:
        case C_DICTIONARY:
            OS_REPORT(OS_WARNING,"Database misc",0,
                      "c_copyIn: ODL collections unsupported");
        break;
        case C_ARRAY:
            refType = c_typeActualType(c_collectionType(type)->subType);
            subSize = refType->size;
            size = c_collectionType(t)->maxSize;
            if (size == 0) {
                size = c_arraySize(data);
                *dest = c_newArray(c_collectionType(t), size);
            }
            if (size > 0) {
                c_array ar = c_array(data);
                c_array destar = c_array(*dest);
                if (c_typeIsRef(refType)) {
                    for (i = 0; i < size; i++) {
                        copyReferences(refType, destar[i], ar[i]);
                    }
                } else {
                    memcpy(*dest, data, size * subSize);
                    /* Find indirections */
                    for (i = 0; i < size; i++) {
                        copyReferences(refType, C_DISPLACE(destar, (i*subSize)), C_DISPLACE(ar, (i*subSize)));
                    }
                }
            }
        break;
        case C_SEQUENCE:
            refType = c_typeActualType(c_collectionType(type)->subType);
            subSize = refType->size;
            size = c_sequenceSize(data);
            if (size > 0) {
                *dest = c_newSequence(c_collectionType(t), size);
                if (c_typeIsRef(refType)) {
                    c_sequence seq = c_sequence(data);
                    c_sequence destseq = c_sequence(*dest);
                    for (i = 0; i < size; i++) {
                        copyReferences(refType, destseq[i], seq[i]);
                    }
                } else {
                    memcpy(*dest, data, size * subSize);
                    /* Find indirections */
                    for (i = 0; i < size; i++) {
                        copyReferences(refType, C_DISPLACE(*dest, (i*subSize)), C_DISPLACE(data, (i*subSize)));
                    }
                }
            }
        break;
        default:
            OS_REPORT_1(OS_ERROR,"Database misc",0,
                        "c_copyIn: unknown collection kind (%d)",
                        c_collectionType(t)->kind);
            assert(FALSE);
        break;
        }
    } else if (c_typeIsRef(t)) {
        *dest = c_new(t);
        memcpy(*dest, data, t->size);
        copyReferences(t, *dest, data);
    } else {
        memcpy(*dest, data, t->size);
        copyReferences(t, *dest, data);
    }
}