/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */ /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */ #include "precomp.h" void ExaminePERType(AssignmentList_t ass, Type_t *type, char *ideref); static int __cdecl CmpIntxP(const void *v1, const void *v2); void ExaminePERType_Boolean(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Integer(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Enumerated(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Real(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_BitString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_OctetString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_UTF8String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Null(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_EmbeddedPdv(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_External(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_ObjectIdentifier(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_BMPString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_GeneralString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_GraphicString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_IA5String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_ISO646String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_NumericString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_PrintableString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_TeletexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_T61String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_UniversalString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_VideotexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_VisibleString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_UnrestrictedString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_RestrictedString(AssignmentList_t ass, Type_t *type, intx_t *up, intx_t *nchars, char *tabref, uint32_t enbits, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_GeneralizedTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_UTCTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_ObjectDescriptor(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Open(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_SequenceSet(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_SequenceSetOf(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Choice(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); void ExaminePERType_Reference(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info); /* examine all types and extract informations needed for PER encoding */ void ExaminePER(AssignmentList_t ass) { Assignment_t *a; for (a = ass; a; a = a->Next) { switch (a->Type) { case eAssignment_Type: ExaminePERType(ass, a->U.Type.Type, GetName(a)); break; default: break; } } } /* extract some type informations needed for PER encoding */ void ExaminePERType(AssignmentList_t ass, Type_t *type, char *ideref) { PERConstraints_t *per; PERTypeInfo_t *info; uint32_t lrange, lrangelog2; per = &type->PERConstraints; info = &type->PERTypeInfo; info->pPrivateDirectives = &type->PrivateDirectives; /* get the type to be examined */ if (type->Type == eType_Reference && !IsStructuredType(GetType(ass, type))) type = GetType(ass, type); /* initialize the PER informations */ info->Type = eExtension_Unextended; info->Identifier = ideref; info->Rules = type->Rules; info->Flags = type->Flags; info->EnumerationValues = NULL; info->NOctets = 0; info->Root.TableIdentifier = NULL; info->Root.Table = NULL; info->Root.SubIdentifier = NULL; info->Root.SubType = NULL; info->Root.Data = ePERSTIData_Null; info->Root.Identification = NULL; info->Root.Constraint = ePERSTIConstraint_Unconstrained; intx_setuint32(&info->Root.LowerVal, 0); intx_setuint32(&info->Root.UpperVal, 0); info->Root.NBits = 1; info->Root.Alignment = ePERSTIAlignment_OctetAligned; info->Root.Length = ePERSTILength_NoLength; info->Root.LConstraint = ePERSTIConstraint_Semiconstrained; info->Root.LLowerVal = info->Root.LUpperVal = 0; info->Root.LNBits = 1; info->Root.LAlignment = ePERSTIAlignment_OctetAligned; info->Additional = info->Root; info->Additional.NBits = 8; info->Additional.Length = ePERSTILength_InfiniteLength; info->Additional.LNBits = 1; info->Additional.LAlignment = ePERSTIAlignment_OctetAligned; /* PER informations are type specific ... */ switch (type->Type) { case eType_Boolean: ExaminePERType_Boolean(ass, type, per, info); break; case eType_Integer: ExaminePERType_Integer(ass, type, per, info); break; case eType_Enumerated: ExaminePERType_Enumerated(ass, type, per, info); break; case eType_Real: ExaminePERType_Real(ass, type, per, info); break; case eType_BitString: ExaminePERType_BitString(ass, type, per, info); break; case eType_OctetString: ExaminePERType_OctetString(ass, type, per, info); break; case eType_UTF8String: ExaminePERType_UTF8String(ass, type, per, info); break; case eType_Null: ExaminePERType_Null(ass, type, per, info); break; case eType_EmbeddedPdv: ExaminePERType_EmbeddedPdv(ass, type, per, info); break; case eType_External: ExaminePERType_External(ass, type, per, info); break; case eType_ObjectIdentifier: ExaminePERType_ObjectIdentifier(ass, type, per, info); break; case eType_BMPString: ExaminePERType_BMPString(ass, type, per, info); break; case eType_GeneralString: ExaminePERType_GeneralString(ass, type, per, info); break; case eType_GraphicString: ExaminePERType_GraphicString(ass, type, per, info); break; case eType_IA5String: ExaminePERType_IA5String(ass, type, per, info); break; case eType_ISO646String: ExaminePERType_ISO646String(ass, type, per, info); break; case eType_NumericString: ExaminePERType_NumericString(ass, type, per, info); break; case eType_PrintableString: ExaminePERType_PrintableString(ass, type, per, info); break; case eType_TeletexString: ExaminePERType_TeletexString(ass, type, per, info); break; case eType_T61String: ExaminePERType_T61String(ass, type, per, info); break; case eType_UniversalString: ExaminePERType_UniversalString(ass, type, per, info); break; case eType_VideotexString: ExaminePERType_VideotexString(ass, type, per, info); break; case eType_VisibleString: ExaminePERType_VisibleString(ass, type, per, info); break; case eType_CharacterString: ExaminePERType_UnrestrictedString(ass, type, per, info); break; case eType_GeneralizedTime: ExaminePERType_GeneralizedTime(ass, type, per, info); break; case eType_UTCTime: ExaminePERType_UTCTime(ass, type, per, info); break; case eType_ObjectDescriptor: ExaminePERType_ObjectDescriptor(ass, type, per, info); break; case eType_Open: ExaminePERType_Open(ass, type, per, info); break; case eType_Sequence: case eType_Set: case eType_InstanceOf: ExaminePERType_SequenceSet(ass, type, per, info); break; case eType_SequenceOf: case eType_SetOf: ExaminePERType_SequenceSetOf(ass, type, per, info); break; case eType_Choice: ExaminePERType_Choice(ass, type, per, info); break; case eType_RestrictedString: MyAbort(); /* may never happen */ /*NOTREACHED*/ case eType_Selection: MyAbort(); /* may never happen */ /*NOTREACHED*/ case eType_Undefined: MyAbort(); /* may never happen */ /*NOTREACHED*/ case eType_Reference: ExaminePERType_Reference(ass, type, per, info); break; } /* get real Length, LNBits and LAlignment */ if (info->Root.Length == ePERSTILength_Length) { switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: lrange = info->Root.LUpperVal - info->Root.LLowerVal + 1; lrangelog2 = uint32_log2(lrange); if (info->Root.LUpperVal < 0x10000) { if (lrange < 0x100) { info->Root.Length = ePERSTILength_BitLength; info->Root.LAlignment = ePERSTIAlignment_BitAligned; info->Root.LNBits = lrangelog2; } else if (lrange == 0x100) { info->Root.Length = ePERSTILength_BitLength; info->Root.LNBits = 8; } else if (lrange <= 0x10000) { info->Root.Length = ePERSTILength_BitLength; info->Root.LNBits = 16; } else { info->Root.Length = ePERSTILength_InfiniteLength; info->Root.LLowerVal = 0; } } else { info->Root.Length = ePERSTILength_InfiniteLength; info->Root.LLowerVal = 0; } break; case ePERSTIConstraint_Semiconstrained: info->Root.Length = ePERSTILength_InfiniteLength; info->Root.LLowerVal = 0; break; } } else if (info->Root.Length == ePERSTILength_NoLength) { info->Root.LAlignment = ePERSTIAlignment_BitAligned; } } /* * Description of the fields of PERTypeInfo_t: * info. * Identifier complete name of the type * Rules encoding directive rules * Flags encoding flags * EnumerationValues values of enumeration type * NOctets size of string characters/integer type * Type unextended/extendable/extended * Root information for the extension root * Additional information for the extensions * info.{Root,Additional}. * Data data type of value * TableIdentifier name of stringtable to use * Table stringtable to use * SubIdentifier complete name of the subtype * SubType the subtype itself * Identification identification of EMBEDDED PDV/CHARACTER STRING * NBits number of bits to use * Constraint constraint of type values * LowerVal lower bound of values (if constrained) * UpperVal upper bound of values (if constrained) * Alignment alignment to be used for value encoding * Length type of length encoding * LConstraint constraint of length * LLowerVal lower bound of length * LUpperVal upper bound of length * LAlignment alignment to be used for length encoding * * NOTES: * The encoding is mostly controlled by following arguments: * - Data, the type: one of: * ePERSTIData_Null, ePERSTIData_Boolean, * ePERSTIData_Integer, ePERSTIData_Unsigned, * ePERSTIData_Real, ePERSTIData_BitString, ePERSTIData_RZBBitString, * ePERSTIData_OctetString, ePERSTIData_SequenceOf, ePERSTIData_SetOf, * ePERSTIData_ObjectIdentifier, ePERSTIData_NormallySmall, * ePERSTIData_String, ePERSTIData_TableString, ePERSTIData_ZeroString, * ePERSTIData_ZeroTableString, ePERSTIData_Reference, * ePERSTIData_Extension, ePERSTIData_External, * ePERSTIData_EmbeddedPdv, ePERSTIData_UnrestrictedString * - NBits, the item size for encoding * - Length, the length encoding: one of: * ePERSTILength_NoLength, ePERSTILength_SmallLength, * ePERSTILength_Length * (internally eLength will be replaced by one of: * ePERSTILength_BitLength, ePERSTILength_InfiniteLength, * depending on the constraints) * * Additional arguments: * - Alignment, the value alignment: one of: * ePERSTIAlignment_BitAligned, ePERSTIAlignment_OctetAligned * - LAlignment, the length alignment: one of: * ePERSTIAlignment_BitAligned, ePERSTIAlignment_OctetAligned * - Constraint, the value constraint: one of: * ePERSTIConstraint_Unconstrained, ePERSTIConstraint_Semiconstrained, * ePERSTIConstraint_Upperconstrained, ePERSTIConstraint_Constrained * - LConstraint, the length constraint: one of: * ePERSTIConstraint_Semiconstrained, ePERSTIConstraint_Constrained * * Following arguments contain variable/function names in the generated * code: * - Identifier, the name of the current type * - SubIdentifier, the name of the subtype * - TableIdentifier, the name of the stringtable * * Following values require additional arguments: * - Constraint == ePERSTIConstraint_Semiconstrained || * Constraint == ePERSTIConstraint_Constrained: * -> LowerVal, the lower bound of the value * - Constraint == ePERSTIConstraint_Upperconstrained || * Constraint == ePERSTIConstraint_Constrained: * -> UpperVal, the upper bound of the value * - Length == ePERSTILength_Length: * -> LLowerVal, the lower bound of the length * - Length == ePERSTILength_Length && * LConstraint == ePERSTIConstraint_Constrained: * -> LUpperVal, the upper bound of the length * - Data == ePERSTIData_TableString || * Data == ePERSTIData_ZeroTableString: * -> TableIdentifier, the name of the string table * -> Table, the string table * - Data == ePERSTIData_Reference: * -> SubIdentifier, the name of the subtype * -> SubType, the subtype itself * - Data == ePERSTIData_*String: * -> NOctets, the size of the string characters * - Data == ePERSTIData_Integer || Data == ePERSTIData_Unsigned || * Data == ePERSTIData_Boolean: * -> NOctets, the size of the integer type * - Data == ePERSTIData_SequenceOf || Data == ePERSTIData_SetOf: * -> SubIdentifier, the name of the subtype * -> SubType, the subtype itself * -> Rule, the encoding directive rules * - Data == ePERSTIData_EmbeddedPdv || * Data == ePERSTIData_UnrestrictedString * -> Identification, the identification of the type if the type * is constraint to fixed identification or syntaxes identification * with single value * * Following values have optional arguments: * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned: * -> EnumerationValues, the mapping for enumeration values * * Following combinations are allowed: * * Data/NBits/Length Description * ----------------------------------------------------------------------- * Null/0/NoLength NULL type * * Boolean/1/NoLength boolean value, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Integer/0/NoLength constrained whole number of fixed * value, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Integer/n/NoLength constrained whole number of fixed * length < 64K, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Integer/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * Unsigned/0/NoLength constrained whole number of fixed * value, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Unsigned/n/NoLength constrained whole number of fixed * length < 64K, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Unsigned/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * NormallySmall/1/NoLength normally small non-negative * whole number, stored in an * uint{8,16,32}_t * (noctets == 1/2/4) * * Real/8/Length REAL value * * *BitString/0/NoLength BIT STRING of fixed length 0 * * *BitString/1/NoLength BIT STRING of fixed length < 64K * * *BitString/1/Length BIT STRING of var. length or * length >= 64K or semiconstrained * length, encoded in units of bits * * "RZB" in e*BitString means, bit * strings with removed leading zero bits * * OctetString/0/NoLength OCTET STRING of fixed length 0 * * OctetString/8/NoLength OCTET STRING of fixed length < 64K, * * OctetString/8/Length OCTET STRING of var. length or * length >= 64K or semiconstrained * length, encoded in units of octets * * Extension/n/NoLength bit field representing presence or * absence of <64K OPTIONAL/DEFAULT * components in SEQUENCEs/SETs, encoded * in n bits * * Extension/n/Length bit field representing presence or * absence of >=64K OPTIONAL/DEFAULT * components in SEQUENCEs/SETs, encoded * in n bits * * Extension/n/SmallLength bit field representing presence or * absence of components in the extension * of SEQUENCEs/SETs, encoded in n bits * * ObjectIdentifier/8/Length OBJECT IDENTIFIER value * * *String/0/NoLength String of fixed length 0 * * *String/n/NoLength String of fixed length < 64K, * encoded in n bits * * *String/n/Length String of var. length or * length >= 64K or semiconstrained * length, encoded in units of n bits * * "Zero" in *String means * zero-terminated strings, * "Table" means renumbering of the * characters. * * MultibyteString/8/Length not known-multiplier character strings * * SequenceOf/0/NoLength SEQUENCE OF subtype or SET OF subtype * SetOf/0/NoLength of zero length * * SequenceOf/1/NoLength SEQUENCE OF subtype or SET OF subtype * SetOf/1/NoLength of fixed length <64K * * SequenceOf/1/Length SEQUENCE OF subtype or SET OF subtype * SetOf/1/Length of var. length or length >= 64K or * semiconstrained length * * External/8/NoLength EXTERNAL * * EmbeddedPdv/8/Length EMBEDDED PDV * * UnrestrictedString/8/Length CHARACTER STRING * * GeneralizedTime/n/NoLength GeneralizedTime, encoded in units of * n bits * * UTCTime/n/NoLength UTCTime, encoded in units of n bits * * Reference/1/NoLength Reference to a structured subtype * * Open/8/Length Open type */ /* for sorting of intx_t's */ static int __cdecl CmpIntxP(const void *v1, const void *v2) { intx_t *n1 = *(intx_t **)v1; intx_t *n2 = *(intx_t **)v2; return intx_cmp(n1, n2); } /* * BOOLEAN: * * Data/NBits/Length used for encoding: * * Boolean/1/NoLength boolean value, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Additional arguments: * * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned || * Data == ePERSTIData_Boolean * -> NOctets, the size of the integer type */ void ExaminePERType_Boolean(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_Boolean; info->NOctets = GetOctets(GetBooleanType()); info->Root.Alignment = ePERSTIAlignment_BitAligned; } /* * INTEGER: * * Data/NBits/Length used for encoding: * * Integer/0/NoLength constrained whole number of fixed * value, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Integer/n/NoLength constrained whole number of fixed * length < 64K, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Integer/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * Unsigned/0/NoLength constrained whole number of fixed * value, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Unsigned/n/NoLength constrained whole number of fixed * length < 64K, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Unsigned/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * Additional arguments: * * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned || * Data == ePERSTIData_Boolean * -> NOctets, the size of the integer type */ void ExaminePERType_Integer(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; int32_t sign; intx_t range; uint32_t rangelog2; uint32_t rangelog256; /* calculate LowerVal, UpperVal and range of extension root */ /* set Constraint according to presence of LowerVal/UpperVal */ if (per->Value.Type == eExtension_Unconstrained) { lower.Flags = eEndPoint_Min; upper.Flags = eEndPoint_Max; } else { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Value.Root, &lower, &upper); if (lower.Flags & eEndPoint_Max) lower.Flags = eEndPoint_Min; if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; } if (!(lower.Flags & eEndPoint_Min)) { intx_dup(&info->Root.LowerVal, &GetValue(ass, lower.Value)->U.Integer.Value); info->Root.Constraint = ePERSTIConstraint_Semiconstrained; } if (!(upper.Flags & eEndPoint_Max)) { intx_dup(&info->Root.UpperVal, &GetValue(ass, upper.Value)->U.Integer.Value); info->Root.Constraint = ePERSTIConstraint_Upperconstrained; } if (!(lower.Flags & eEndPoint_Min) && !(upper.Flags & eEndPoint_Max)) { intx_sub(&range, &info->Root.UpperVal, &info->Root.LowerVal); intx_inc(&range); rangelog2 = intx_log2(&range); rangelog256 = intx_log256(&range); info->Root.Constraint = ePERSTIConstraint_Constrained; } /* calculate NOctets and Data depending on the used C-Type */ info->NOctets = GetOctets(GetIntegerType(ass, type, &sign)); info->Root.Data = sign > 0 ? ePERSTIData_Unsigned : ePERSTIData_Integer; /* calculate Length, NBits, Alignment, LConstraint, LLowerVal and */ /* LUpperVal */ switch (info->Root.Constraint) { case ePERSTIConstraint_Unconstrained: case ePERSTIConstraint_Semiconstrained: case ePERSTIConstraint_Upperconstrained: info->Root.Length = ePERSTILength_Length; info->Root.NBits = 8; info->Root.LLowerVal = 1; break; case ePERSTIConstraint_Constrained: if (intx_cmp(&range, &intx_1) == 0) { info->Root.NBits = 0; } else if (intx_cmp(&range, &intx_256) < 0 || Alignment == eAlignment_Unaligned) { info->Root.NBits = rangelog2; info->Root.Alignment = ePERSTIAlignment_BitAligned; } else if (intx_cmp(&range, &intx_256) == 0) { info->Root.NBits = 8; } else if (intx_cmp(&range, &intx_64K) <= 0) { info->Root.NBits = 16; } else { info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; info->Root.LConstraint = ePERSTIConstraint_Constrained; info->Root.LLowerVal = 1; info->Root.LUpperVal = rangelog256; } } /* check for extensions */ info->Type = per->Value.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; info->Additional.Data = info->Root.Data; } /* * ENUMERATED: * * Data/NBits/Length used for encoding: * * Integer/0/NoLength constrained whole number of fixed * value, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Integer/n/NoLength constrained whole number of fixed * length < 64K, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Integer/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * int{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * Unsigned/0/NoLength constrained whole number of fixed * value, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Unsigned/n/NoLength constrained whole number of fixed * length < 64K, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Unsigned/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * NormallySmall/1/NoLength normally small non-negative * whole number, stored in an * uint{8,16,32}_t * (noctets == 1/2/4) * * Additional arguments: * * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned || * Data == ePERSTIData_Boolean * -> NOctets, the size of the integer type */ void ExaminePERType_Enumerated(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { uint32_t nroot, nindex, i; NamedNumber_t *n; int32_t sign; uint32_t rangelog2; intx_t range; /* count number of enumeration values in extension root and extension */ /* set extension type of extensions are present/possible */ nroot = nindex = 0; for (n = type->U.Enumerated.NamedNumbers; n; n = n->Next) { switch (n->Type) { case eNamedNumber_Normal: nindex++; switch (info->Type) { case eExtension_Unextended: nroot = nindex; break; case eExtension_Extendable: info->Type = eExtension_Extended; break; } break; case eNamedNumber_ExtensionMarker: info->Type = eExtension_Extendable; break; } } /* allocate table for enumeration values and copy the values into */ info->EnumerationValues = (intx_t **)malloc((nindex + 1) * sizeof(intx_t *)); nindex = 0; for (n = type->U.Enumerated.NamedNumbers; n; n = n->Next) { switch (n->Type) { case eNamedNumber_Normal: info->EnumerationValues[nindex++] = &GetValue(ass, n->U.Normal.Value)->U.Integer.Value; break; case eNamedNumber_ExtensionMarker: break; } } info->EnumerationValues[nindex] = 0; /* sort values of extension root according to their value */ qsort(info->EnumerationValues, nroot, sizeof(*info->EnumerationValues), CmpIntxP); /* check the need for an index translation */ for (i = 0; info->EnumerationValues[i]; i++) { if (intx2uint32(info->EnumerationValues[i]) != i) break; } if (!info->EnumerationValues[i]) info->EnumerationValues = NULL; /* calculate NOctets and Data depending on the used C-Type */ info->NOctets = GetOctets(GetEnumeratedType(ass, type, &sign)); info->Root.Data = sign > 0 ? ePERSTIData_Unsigned : ePERSTIData_Integer; /* enumeration is always constrained to value from 0 to nroot-1 */ info->Root.Constraint = ePERSTIConstraint_Constrained; intx_setuint32(&info->Root.LowerVal, 0); intx_setuint32(&info->Root.UpperVal, nroot - 1); intx_setuint32(&range, nroot); rangelog2 = intx_log2(&range); /* calculate NBits and Alignment */ if (nroot <= 1) { info->Root.NBits = 0; } else if (nroot < 256) { info->Root.Alignment = ePERSTIAlignment_BitAligned; info->Root.NBits = rangelog2; } else if (nroot == 256) { info->Root.NBits = 8; } else if (nroot < 65536) { info->Root.NBits = 16; } else { MyAbort(); } /* values of extension will always be encoded as normally small numbers */ /* with lowerbound = nroot */ info->Additional.Data = ePERSTIData_NormallySmall; info->Additional.NBits = 1; info->Additional.Alignment = ePERSTIAlignment_BitAligned; info->Additional.Length = ePERSTILength_NoLength; info->Additional.Constraint = ePERSTIConstraint_Semiconstrained; intx_setuint32(&info->Additional.LowerVal, nroot); } /* * REAL: * * Data/NBits/Length used for encoding: * * Real/8/Length REAL value * * Additional arguments: * * none */ void ExaminePERType_Real(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_Real; info->Root.NBits = 8; info->NOctets = GetOctets(GetRealType(type)); } /* * BIT STRING: * * Data/NBits/Length used for encoding: * * *BitString/0/NoLength BIT STRING of fixed length 0 * * *BitString/1/NoLength BIT STRING of fixed length < 64K, * encoded in n bits * * *BitString/1/Length BIT STRING of var. length or * length >= 64K or semiconstrained * length, encoded in units of bits * * "RZB" in e*BitString means, bit * strings with removed leading zero bits * * Additional arguments: * * none */ void ExaminePERType_BitString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; /* calculate LConstraint, LLowerVal and LUpperVal */ if (per->Size.Type != eExtension_Unconstrained) { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Size.Root, &lower, &upper); if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Semiconstrained; if (!(upper.Flags & eEndPoint_Max)) { info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Constrained; } } /* calculate NBits, Alignment and Length */ info->Root.cbFixedSizeBitString = 0; // clear it up first switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: if (info->Root.LUpperVal == 0) { info->Root.NBits = 0; } else { info->Root.NBits = 1; if (info->Root.LLowerVal == info->Root.LUpperVal) { if (info->Root.LUpperVal <= 32) { info->Root.cbFixedSizeBitString = (info->Root.LUpperVal + 7) / 8; } if (info->Root.LUpperVal <= 16) { info->Root.Alignment = ePERSTIAlignment_BitAligned; } else if (info->Root.LUpperVal >= 0x10000) { info->Root.Length = ePERSTILength_Length; } } else { info->Root.Length = ePERSTILength_Length; } } break; case ePERSTIConstraint_Semiconstrained: info->Root.NBits = 1; info->Root.Length = ePERSTILength_Length; break; } /* get extension type */ info->Type = per->Size.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; /* set Data to RZBBitString/BitString */ if (type->U.BitString.NamedNumbers) info->Root.Data = ePERSTIData_RZBBitString; else info->Root.Data = ePERSTIData_BitString; /* set extension informations */ info->Additional.Data = info->Root.Data; info->Additional.NBits = 1; } /* * OCTET STRING: * * Data/NBits/Length used for encoding: * * OctetString/0/NoLength OCTET STRING of fixed length 0 * * OctetString/8/NoLength OCTET STRING of fixed length < 64K, * * OctetString/8/Length OCTET STRING of var. length or * length >= 64K or semiconstrained * length, encoded in units of octets * * Additional arguments: * * none */ void ExaminePERType_OctetString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; /* calculate LConstraint, LLowerVal and LUpperVal */ if (per->Size.Type != eExtension_Unconstrained) { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Size.Root, &lower, &upper); if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Semiconstrained; if (!(upper.Flags & eEndPoint_Max)) { info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Constrained; } } /* calculate NBits, Alignment and Length */ switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: if (info->Root.LUpperVal == 0) { info->Root.NBits = 0; } else { info->Root.NBits = 8; if (info->Root.LLowerVal == info->Root.LUpperVal) { if (info->Root.LUpperVal <= 2) { info->Root.Alignment = ePERSTIAlignment_BitAligned; } else if (info->Root.LUpperVal >= 0x10000) { info->Root.Length = ePERSTILength_Length; } } else { info->Root.Length = ePERSTILength_Length; } } break; case ePERSTIConstraint_Semiconstrained: info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; break; } /* get extension type */ info->Type = per->Size.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; /* set Data to OctetString */ info->Root.Data = ePERSTIData_OctetString; /* set extension informations */ info->Additional.Data = info->Root.Data; } void ExaminePERType_UTF8String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; /* calculate LConstraint, LLowerVal and LUpperVal */ if (per->Size.Type != eExtension_Unconstrained) { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Size.Root, &lower, &upper); if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Semiconstrained; if (!(upper.Flags & eEndPoint_Max)) { info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Constrained; } } /* calculate NBits, Alignment and Length */ switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: if (info->Root.LUpperVal == 0) { info->Root.NBits = 0; } else { info->Root.NBits = 8; if (info->Root.LLowerVal == info->Root.LUpperVal) { if (info->Root.LUpperVal <= 2) { info->Root.Alignment = ePERSTIAlignment_BitAligned; } else if (info->Root.LUpperVal >= 0x10000) { info->Root.Length = ePERSTILength_Length; } } else { info->Root.Length = ePERSTILength_Length; } } break; case ePERSTIConstraint_Semiconstrained: info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; break; } /* get extension type */ info->Type = per->Size.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; /* set Data to OctetString */ info->Root.Data = ePERSTIData_UTF8String; /* set extension informations */ info->Additional.Data = info->Root.Data; } /* * NULL: * * Data/NBits/Length used for encoding: * * Null/0/NoLength NULL type * * Additional arguments: * * none */ void ExaminePERType_Null(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.NBits = 0; info->Root.Data = ePERSTIData_Null; } /* * EMBEDDED PDV: * * Data/NBits/Length used for encoding: * * EmbeddedPdv/8/Length EMBEDDED PDV * * Additional arguments: * * - Data == ePERSTIData_EmbeddedPdv || * Data == ePERSTIData_UnrestrictedString * -> Identification, the identification of the type if the type * is constraint to fixed identification or syntaxes identification * with single value */ void ExaminePERType_EmbeddedPdv(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Identification = GetFixedIdentification(ass, type->Constraints); info->Root.Data = ePERSTIData_EmbeddedPdv; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; } /* * EXTERNAL: * * Data/NBits/Length used for encoding: * * External/8/Length EXTERNAL * * Additional arguments: * * none */ void ExaminePERType_External(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_External; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; } /* * OBJECT IDENTIFIER: * * Data/NBits/Length used for encoding: * * ObjectIdentifier/8/Length OBJECT IDENTIFIER value * * Additional arguments: * * none */ void ExaminePERType_ObjectIdentifier(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_ObjectIdentifier; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; } /* * *String: * * Data/NBits/Length used for encoding: * * *String/0/NoLength String of fixed length 0 * * *String/n/NoLength String of fixed length < 64K, * encoded in n bits * * *String/n/Length String of var. length or * length >= 64K or semiconstrained * length, encoded in units of n bits * * "Zero" in *String means * zero-terminated strings, * "Table" means renumbering of the * characters. * * MultibyteString/8/Length not known-multiplier character strings * * Additional arguments: * * - Data == ePERSTIData_TableString || dat == ePERSTIData_ZeroTableString: * -> TableIdentifier, the name of the string table * -> Table, the string table * - Data == ePERSTIData_*String: * -> NOctets, the size of the string characters */ void ExaminePERType_BMPString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0xffff); intx_setuint32(&nchars, 0x10000); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, 16, per, info); } void ExaminePERType_GeneralString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { uint32_t zero; GetStringType(ass, type, &info->NOctets, &zero); info->Root.NBits = 8; info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String; info->Root.Length = ePERSTILength_Length; } void ExaminePERType_GraphicString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { uint32_t zero; GetStringType(ass, type, &info->NOctets, &zero); info->Root.NBits = 8; info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String; info->Root.Length = ePERSTILength_Length; } void ExaminePERType_IA5String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0x7f); intx_setuint32(&nchars, 0x80); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info); } void ExaminePERType_ISO646String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0x7e); intx_setuint32(&nchars, 0x5f); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info); } void ExaminePERType_NumericString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0x39); intx_setuint32(&nchars, 0xb); ExaminePERType_RestrictedString(ass, type, &up, &nchars, "ASN1NumericStringTable", 4, per, info); } void ExaminePERType_PrintableString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0x7a); intx_setuint32(&nchars, 0x4a); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info); } void ExaminePERType_TeletexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_MultibyteString; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; info->NOctets = 1; } void ExaminePERType_T61String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_MultibyteString; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; info->NOctets = 1; } void ExaminePERType_UniversalString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0xffffffff); intx_setuint32(&nchars, 0xffffffff); intx_inc(&nchars); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, 32, per, info); } void ExaminePERType_VideotexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_MultibyteString; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; info->NOctets = 1; } void ExaminePERType_VisibleString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { intx_t up, nchars; intx_setuint32(&up, 0x7e); intx_setuint32(&nchars, 0x5f); ExaminePERType_RestrictedString(ass, type, &up, &nchars, NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info); } void ExaminePERType_RestrictedString(AssignmentList_t ass, Type_t *type, intx_t *up, intx_t *nchars, char *tabref, uint32_t enbits, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; uint32_t zero, rangelog2; intx_t ix, range; char tabbuf[256]; /* calculate NOctets depending on the used C-Type */ GetStringType(ass, type, &info->NOctets, &zero); /* calculate LConstraint, LLowerVal and LUpperVal if size constraint is */ /* given */ if (per->Size.Type != eExtension_Unconstrained) { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Size.Root, &lower, &upper); if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; if (lower.Flags & eEndPoint_Max) { lower.Flags = 0; lower.Value = Builtin_Value_Integer_0; } info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value); if (!(upper.Flags & eEndPoint_Max)) { info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Constrained; } } /* get extension type */ info->Type = per->Size.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; /* get string table if permitted alphabet constraint is present */ /* update extension type if needed */ if (per->PermittedAlphabet.Type != eExtension_Unconstrained) { info->Root.Table = per->PermittedAlphabet.Root; if (per->PermittedAlphabet.Type > info->Type) info->Type = per->PermittedAlphabet.Type; if (CountValues(ass, info->Root.Table, &ix)) { nchars = &ix; sprintf(tabbuf, "%s_StringTable", info->Identifier); tabref = tabbuf; } else { MyAbort(); /*XXX*/ } } /* get bits needed for one character */ info->Root.NBits = intx_log2(nchars); if (Alignment == eAlignment_Aligned) { if (info->Root.NBits > 16) info->Root.NBits = 32; else if (info->Root.NBits > 8) info->Root.NBits = 16; else if (info->Root.NBits > 4) info->Root.NBits = 8; else if (info->Root.NBits > 2) info->Root.NBits = 4; } /* set data type */ info->Root.Data = tabref ? (zero ? ePERSTIData_ZeroTableString : ePERSTIData_TableString) : (zero ? ePERSTIData_ZeroString : ePERSTIData_String); /* check if stringtable is really needed for encoding or extension check */ intx_dup(&range, up); intx_inc(&range); rangelog2 = intx_log2(&range); if (rangelog2 <= info->Root.NBits) { info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String; if (per->PermittedAlphabet.Type < eExtension_Extended) tabref = NULL; } info->Root.TableIdentifier = tabref ? strdup(tabref) : NULL; /* calculate Length and Alignment */ switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: if (info->Root.LUpperVal == 0) { info->Root.NBits = 0; } else { if (info->Root.LLowerVal == info->Root.LUpperVal) { if (info->Root.LUpperVal * info->Root.NBits <= 16) { info->Root.Alignment = ePERSTIAlignment_BitAligned; } else if (info->Root.LUpperVal >= 0x10000) { info->Root.Length = ePERSTILength_Length; } } else { if (info->Root.LUpperVal * info->Root.NBits <= 16) info->Root.Alignment = ePERSTIAlignment_BitAligned; info->Root.Length = ePERSTILength_Length; } } break; case ePERSTIConstraint_Semiconstrained: info->Root.Length = ePERSTILength_Length; break; } /* set extension informations */ info->Additional.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String; info->Additional.NBits = enbits; } /* * CHARACTER STRING: * * Data/NBits/Length used for encoding: * * UnrestrictedString/8/Length CHARACTER STRING * * Additional arguments: * * - Data == ePERSTIData_EmbeddedPdv || * Data == ePERSTIData_UnrestrictedString * -> Identification, the identification of the type if the type * is constraint to fixed identification or syntaxes identification * with single value */ void ExaminePERType_UnrestrictedString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Identification = GetFixedIdentification(ass, type->Constraints); info->Root.Data = ePERSTIData_UnrestrictedString; info->Root.NBits = 8; info->Root.Length = ePERSTILength_Length; } /* * GeneralizedTime: * * Data/NBits/Length used for encoding: * * GeneralizedTime/n/NoLength GeneralizedTime, encoded in units of * n bits * * Additional arguments: * * none */ void ExaminePERType_GeneralizedTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.NBits = (Alignment == eAlignment_Aligned) ? 8 : 7; info->Root.Data = ePERSTIData_GeneralizedTime; } /* * UTCTime: * * Data/NBits/Length used for encoding: * * UTCTime/n/NoLength UTCTime, encoded in units of * n bits * * Additional arguments: * * none */ void ExaminePERType_UTCTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.NBits = (Alignment == eAlignment_Aligned) ? 8 : 7; info->Root.Data = ePERSTIData_UTCTime; } /* * ObjectDescriptor: * * Data/NBits/Length used for encoding: * * *String/n/Length String of var. length or * length >= 64K or semiconstrained * length, encoded in units of n bits * * "Zero" in *String means * zero-terminated strings * * Additional arguments: * * none */ void ExaminePERType_ObjectDescriptor(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->NOctets = 1; info->Root.NBits = 8; info->Root.Data = ePERSTIData_ZeroString; info->Root.Length = ePERSTILength_Length; } /* * OpenType: * * Data/NBits/Length used for encoding: * * Open/8/Length Open type * * Additional arguments: * * none */ void ExaminePERType_Open(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->NOctets = 1; info->Root.NBits = 8; info->Root.Data = ePERSTIData_Open; info->Root.Length = ePERSTILength_Length; } /* * SEQUENCE/SET: * * Data/NBits/Length used for encoding: * * none * * Additional arguments: * * none */ void ExaminePERType_SequenceSet(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { Component_t *comp; NamedType_t *namedType; char idebuf[256]; /* examine types of components */ for (comp = type->U.SSC.Components; comp; comp = comp->Next) { switch (comp->Type) { case eComponent_Normal: case eComponent_Optional: case eComponent_Default: namedType = comp->U.NOD.NamedType; sprintf(idebuf, "%s_%s", info->Identifier, namedType->Identifier); ExaminePERType(ass, namedType->Type, strdup(idebuf)); break; } } } /* * SEQUENCE OF/SET OF: * * Data/NBits/Length used for encoding: * * SequenceOf/0/NoLength SEQUENCE OF subtype or SET OF subtype * SetOf/0/NoLength of zero length * * SequenceOf/1/NoLength SEQUENCE OF subtype or SET OF subtype * SetOf/1/NoLength of fixed length <64K * * SequenceOf/1/Length SEQUENCE OF subtype or SET OF subtype * SetOf/1/Length of var. length or length >= 64K or * semiconstrained length * * Additional arguments: * * - Data == ePERSTIData_SequenceOf || dat == ePERSTIData_SetOf: * -> SubIdentifier, the name of the subtype * -> SubType, the subtype itself * -> Rule, the encoding directive rules */ void ExaminePERType_SequenceSetOf(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { EndPoint_t lower, upper; char idebuf[256]; /* calculate LConstraint, LLowerVal and LUpperVal */ if (per->Size.Type != eExtension_Unconstrained) { lower.Flags = eEndPoint_Max; upper.Flags = eEndPoint_Min; GetMinMax(ass, per->Size.Root, &lower, &upper); if (upper.Flags & eEndPoint_Min) upper.Flags = eEndPoint_Max; info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)-> U.Integer.Value); if (!(upper.Flags & eEndPoint_Max)) { info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)-> U.Integer.Value); info->Root.LConstraint = ePERSTIConstraint_Constrained; } } /* calculate NBits, Length */ switch (info->Root.LConstraint) { case ePERSTIConstraint_Constrained: if (info->Root.LUpperVal == 0) { info->Root.NBits = 0; } else { if (info->Root.LLowerVal != info->Root.LUpperVal) info->Root.Length = ePERSTILength_Length; } break; case ePERSTIConstraint_Semiconstrained: info->Root.Length = ePERSTILength_Length; break; } /* set data type and Alignment */ info->Root.Data = (type->Type == eType_SequenceOf ? ePERSTIData_SequenceOf : ePERSTIData_SetOf); info->Root.Alignment = ePERSTIAlignment_BitAligned; /* set SubType, SubIdentifier */ info->Root.SubType = type->U.SS.Type; info->Root.SubIdentifier = GetTypeName(ass, info->Root.SubType); /* get extension type */ info->Type = per->Size.Type; if (info->Type == eExtension_Unconstrained) info->Type = eExtension_Unextended; /* set extension informations */ info->Additional.Data = info->Root.Data; info->Additional.NBits = 1; info->Additional.SubType = info->Root.SubType; info->Additional.SubIdentifier = info->Root.SubIdentifier; /* examine subtype */ sprintf(idebuf, "%s_%s", info->Identifier, type->Type == eType_SequenceOf ? "Sequence" : "Set"); ExaminePERType(ass, type->U.SS.Type, strdup(idebuf)); } /* * CHOICE: * * Data/NBits/Length used for encoding of the choice selector: * * Unsigned/0/NoLength constrained whole number of fixed * value, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * * Unsigned/n/NoLength constrained whole number of fixed * length < 64K, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in n bits * * Unsigned/8/Length constrained whole number of var. * length or length >= 64K or * semiconstrained or unconstrained * whole number, stored in an * uint{8,16,32}_t/intx_t * (noctets == 1/2/4/0) * encoded in units of octets * * NormallySmall/1/NoLength normally small non-negative * whole number, stored in an * uint{8,16,32}_t * (noctets == 1/2/4) * * Additional arguments: * * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned || * Data == ePERSTIData_Boolean * -> NOctets, the size of the integer type * */ void ExaminePERType_Choice(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { uint32_t nroot, rangelog2; intx_t range; Component_t *comp; NamedType_t *namedType; char idebuf[256]; if (type->Flags & eTypeFlags_ExtensionMarker) { info->Type = type->U.Choice.Extensions ? eExtension_Extended : eExtension_Extendable; } nroot = type->U.Choice.Alternatives; info->NOctets = GetOctets(GetChoiceType(type)); info->Root.Constraint = ePERSTIConstraint_Constrained; intx_setuint32(&info->Root.UpperVal, nroot - 1); intx_setuint32(&range, nroot); rangelog2 = intx_log2(&range); if (nroot <= 1) { info->Root.NBits = 0; } else if (nroot < 256) { info->Root.Alignment = ePERSTIAlignment_BitAligned; info->Root.NBits = rangelog2; } else if (nroot == 256) { info->Root.NBits = 8; } else if (nroot < 65536) { info->Root.NBits = 16; } else { MyAbort(); } info->Root.Data = ePERSTIData_Unsigned; info->Additional.Data = ePERSTIData_NormallySmall; info->Additional.NBits = 1; info->Additional.Alignment = ePERSTIAlignment_BitAligned; info->Additional.Length = ePERSTILength_NoLength; info->Additional.Constraint = ePERSTIConstraint_Semiconstrained; intx_setuint32(&info->Additional.LowerVal, nroot); /* examine types of alternatives */ for (comp = type->U.SSC.Components; comp; comp = comp->Next) { switch (comp->Type) { case eComponent_Normal: namedType = comp->U.NOD.NamedType; sprintf(idebuf, "%s_%s", info->Identifier, namedType->Identifier); ExaminePERType(ass, namedType->Type, strdup(idebuf)); break; } } } /* * Reference: * * Data/NBits/Length used for encoding: * * Reference/1/NoLength Reference to a structured subtype * * Additional arguments: * * - Data == ePERSTIData_Reference: * -> SubIdentifier, the name of the subtype * -> SubType, the subtype itself */ void ExaminePERType_Reference(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info) { info->Root.Data = ePERSTIData_Reference; info->Root.Alignment = ePERSTIAlignment_BitAligned; info->Root.SubIdentifier = GetName(FindAssignment(ass, eAssignment_Type, type->U.Reference.Identifier, type->U.Reference.Module)); info->Root.SubType = GetAssignment(ass, FindAssignment(ass, eAssignment_Type, type->U.Reference.Identifier, type->U.Reference.Module))->U.Type.Type; }