windows-nt/Source/XPSP1/NT/ds/security/asn1/asn1c/per.c

1717 lines
53 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/* 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;
}