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; }
/** \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; }
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); } }
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; }