示例#1
0
c_unionCase
c_unionCaseNew (
    c_metaObject scope,
    const c_char *name,
    c_type type,
    c_iter labels)
{
    c_unionCase o;
    c_ulong nrOfLabels;
    c_type subType;

    nrOfLabels = c_iterLength(labels);
    o = c_unionCase(c_metaDefine(scope,M_UNIONCASE));
    subType = c_type(c_metaResolve(scope,"c_literal"));
    o->labels = c_arrayNew(subType,nrOfLabels);
    c_free(subType);
    c_iterArray(labels,o->labels);
    c_specifier(o)->name = c_stringNew(c__getBase(scope),name);
    /* Do not keep type as usage expects transferral of refcount.
     * If changed then odlpp and idlpp must be adapted accordingly.
     */
    c_specifier(o)->type = type;
    return o;
}
示例#2
0
/** \brief Function for selecting the correct case label for a given switch
 *         value
 */
static c_unionCase
sd_unionDetermineLabel(
    c_union v_union,
    c_value switchValue)
{
    c_unionCase result = NULL;
    c_unionCase deflt;
    c_unionCase currentCase;
    c_literal label;
    int i,j, nLabels;

    /* Determine corresponding label */
    result = NULL;
    deflt = NULL;
    for (i=0; (i<c_arraySize(v_union->cases)) && !result; i++) {
        currentCase = c_unionCase(v_union->cases[i]);
        nLabels = c_arraySize(currentCase->labels);
        if (nLabels > 0) {
            for (j=0; (j<nLabels) && !result; j++) {
                label = c_literal(currentCase->labels[j]);

                if (c_valueCompare(switchValue, label->value) == C_EQ) {
                    result = currentCase;
                }
            }
        } else {
            deflt = currentCase;
        }
    }

    if (!result) {
        result = deflt;
    }

    return result;
}
示例#3
0
static void
c_deepwalkUnion(
    c_union v_union,
    c_object *objectPtr,
    c_deepwalkFunc action,
    void *actionArg)
{
    c_type switchType;
    c_type caseType;
    c_unionCase deflt;
    c_unionCase activeCase;
    c_unionCase currentCase;
    c_object unionData;
    c_value switchValue;
    c_literal label;
    int i,j, nCases, nLabels;

    c_long dataOffset;

    /* action for the union itself */
    /* No action, but separate actions for the switch and the data */
    /* action(c_type(v_union), objectPtr, actionArg); */
    /* action for the switch */
    c_deepwalkType(v_union->switchType, objectPtr,
                   action, actionArg);

    switchType = c_typeActualType(v_union->switchType);
    /* Determine value of the switch field */
    switch (c_baseObject(switchType)->kind) {
    case M_PRIMITIVE:
        switch (c_primitive(switchType)->kind) {
#define __CASE__(prim, type) \
        case prim: switchValue = type##Value(*((type *)*objectPtr)); break;
        __CASE__(P_BOOLEAN,c_bool)
        __CASE__(P_CHAR,c_char)
        __CASE__(P_SHORT,c_short)
        __CASE__(P_USHORT,c_ushort)
        __CASE__(P_LONG,c_long)
        __CASE__(P_ULONG,c_ulong)
        __CASE__(P_LONGLONG,c_longlong)
        __CASE__(P_ULONGLONG,c_ulonglong)
#undef __CASE__
        default:
            switchValue = c_undefinedValue();
            assert(FALSE);
        break;
        }
    break;
    case M_ENUMERATION:
        switchValue = c_longValue(*(c_long *)*objectPtr);
    break;
    default:
        switchValue = c_undefinedValue();
        assert(FALSE);
    break;
    }

    /* Determine the label corresponding to this field */

    activeCase = NULL;
    deflt = NULL;
    nCases = c_arraySize(v_union->cases);

    for (i=0; (i<nCases) && !activeCase; i++) {
        currentCase = c_unionCase(v_union->cases[i]);
        nLabels = c_arraySize(currentCase->labels);
        if (nLabels > 0) {
            for (j=0; (j<nLabels) && !activeCase; j++) {
                label = c_literal(currentCase->labels[j]);
                if (c_valueCompare(switchValue, label->value) == C_EQ) {
                    activeCase = currentCase;
                }
            }
        } else {
            deflt = currentCase;
        }
    }
    if (!activeCase) {
        activeCase = deflt;
    }
    assert(activeCase);
    if (activeCase) {
        caseType = c_specifier(activeCase)->type;
        if (c_type(v_union)->alignment >= v_union->switchType->size) {
            dataOffset = c_type(v_union)->alignment;
        } else {
            dataOffset = v_union->switchType->size;
        }
        unionData = C_DISPLACE(*objectPtr, (c_address)dataOffset);
        c_deepwalkType(caseType, &unionData, action, actionArg);
    }
}
void
in_messageDeserializerReadUnion(
    in_messageDeserializer _this,
    c_type type,
    c_voidp data)
{
    c_union utype = c_union(type);
    c_type caseType;
    c_type switchType;
    c_unionCase deflt;
    c_unionCase activeCase;
    c_unionCase currentCase;
    c_value switchValue;
    c_literal label;
    c_voidp o;
    os_uint32 length;
    os_uint32 i;
    os_uint32 j;
    os_uint32 n;

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

    /* action for the switch */
    switchType = c_typeActualType(utype->switchType);
    in_messageDeserializerReadType(_this, switchType, data);

    /* Determine value of the switch field */
    switch (c_baseObjectKind(switchType))
    {
    case M_PRIMITIVE:
        switch (c_primitiveKind(switchType))
        {
#define __CASE__(prim, type) \
        case prim: switchValue = type##Value(*((type *)data)); break;
        __CASE__(P_BOOLEAN,c_bool)
        __CASE__(P_CHAR,c_char)
        __CASE__(P_SHORT,c_short)
        __CASE__(P_USHORT,c_ushort)
        __CASE__(P_LONG,c_long)
        __CASE__(P_ULONG,c_ulong)
        __CASE__(P_LONGLONG,c_longlong)
        __CASE__(P_ULONGLONG,c_ulonglong)
#undef __CASE__
        default:
            switchValue = c_undefinedValue();
            assert(FALSE);
        break;
        }
    break;
    case M_ENUMERATION:
        switchValue = c_longValue(*(c_long *)data);
    break;
    default:
        switchValue = c_undefinedValue();
        assert(FALSE);
    break;
    }

    /* Determine the label corresponding to this field */
    activeCase = NULL;
    deflt = NULL;
    length = c_arraySize(utype->cases);

    for (i = 0; (i < length) && !activeCase; i++)
    {
        currentCase = c_unionCase(utype->cases[i]);
        n = c_arraySize(currentCase->labels);
        if (n > 0)
        {
            for (j = 0; (j < n) && !activeCase; j++)
            {
                label = c_literal(currentCase->labels[j]);
                if (c_valueCompare(switchValue, label->value) == C_EQ)
                {
                    activeCase = currentCase;
                }
            }
        } else
        {
            deflt = currentCase;
        }
    }
    if(!activeCase)
    {
        activeCase = deflt;
    }
    assert(activeCase);
    if (activeCase)
    {
        if (c_type(utype)->alignment >= utype->switchType->size)
        {
            length = c_type(utype)->alignment;
        } else
        {
            length = utype->switchType->size;
        }
        o = C_DISPLACE(data, (c_address)length);
        caseType = c_typeActualType(c_specifierType(activeCase));
        in_messageDeserializerReadType(_this, caseType, o);
    }
}
示例#5
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;
}