Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1716 lines
53 KiB

  1. /* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
  2. /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
  3. #include "precomp.h"
  4. void ExaminePERType(AssignmentList_t ass, Type_t *type, char *ideref);
  5. static int __cdecl CmpIntxP(const void *v1, const void *v2);
  6. void ExaminePERType_Boolean(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  7. void ExaminePERType_Integer(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  8. void ExaminePERType_Enumerated(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  9. void ExaminePERType_Real(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  10. void ExaminePERType_BitString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  11. void ExaminePERType_OctetString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  12. void ExaminePERType_UTF8String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  13. void ExaminePERType_Null(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  14. void ExaminePERType_EmbeddedPdv(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  15. void ExaminePERType_External(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  16. void ExaminePERType_ObjectIdentifier(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  17. void ExaminePERType_BMPString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  18. void ExaminePERType_GeneralString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  19. void ExaminePERType_GraphicString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  20. void ExaminePERType_IA5String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  21. void ExaminePERType_ISO646String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  22. void ExaminePERType_NumericString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  23. void ExaminePERType_PrintableString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  24. void ExaminePERType_TeletexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  25. void ExaminePERType_T61String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  26. void ExaminePERType_UniversalString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  27. void ExaminePERType_VideotexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  28. void ExaminePERType_VisibleString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  29. void ExaminePERType_UnrestrictedString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  30. 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);
  31. void ExaminePERType_GeneralizedTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  32. void ExaminePERType_UTCTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  33. void ExaminePERType_ObjectDescriptor(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  34. void ExaminePERType_Open(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  35. void ExaminePERType_SequenceSet(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  36. void ExaminePERType_SequenceSetOf(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  37. void ExaminePERType_Choice(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  38. void ExaminePERType_Reference(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info);
  39. /* examine all types and extract informations needed for PER encoding */
  40. void
  41. ExaminePER(AssignmentList_t ass)
  42. {
  43. Assignment_t *a;
  44. for (a = ass; a; a = a->Next) {
  45. switch (a->Type) {
  46. case eAssignment_Type:
  47. ExaminePERType(ass, a->U.Type.Type, GetName(a));
  48. break;
  49. default:
  50. break;
  51. }
  52. }
  53. }
  54. /* extract some type informations needed for PER encoding */
  55. void
  56. ExaminePERType(AssignmentList_t ass, Type_t *type, char *ideref)
  57. {
  58. PERConstraints_t *per;
  59. PERTypeInfo_t *info;
  60. uint32_t lrange, lrangelog2;
  61. per = &type->PERConstraints;
  62. info = &type->PERTypeInfo;
  63. info->pPrivateDirectives = &type->PrivateDirectives;
  64. /* get the type to be examined */
  65. if (type->Type == eType_Reference && !IsStructuredType(GetType(ass, type)))
  66. type = GetType(ass, type);
  67. /* initialize the PER informations */
  68. info->Type = eExtension_Unextended;
  69. info->Identifier = ideref;
  70. info->Rules = type->Rules;
  71. info->Flags = type->Flags;
  72. info->EnumerationValues = NULL;
  73. info->NOctets = 0;
  74. info->Root.TableIdentifier = NULL;
  75. info->Root.Table = NULL;
  76. info->Root.SubIdentifier = NULL;
  77. info->Root.SubType = NULL;
  78. info->Root.Data = ePERSTIData_Null;
  79. info->Root.Identification = NULL;
  80. info->Root.Constraint = ePERSTIConstraint_Unconstrained;
  81. intx_setuint32(&info->Root.LowerVal, 0);
  82. intx_setuint32(&info->Root.UpperVal, 0);
  83. info->Root.NBits = 1;
  84. info->Root.Alignment = ePERSTIAlignment_OctetAligned;
  85. info->Root.Length = ePERSTILength_NoLength;
  86. info->Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  87. info->Root.LLowerVal = info->Root.LUpperVal = 0;
  88. info->Root.LNBits = 1;
  89. info->Root.LAlignment = ePERSTIAlignment_OctetAligned;
  90. info->Additional = info->Root;
  91. info->Additional.NBits = 8;
  92. info->Additional.Length = ePERSTILength_InfiniteLength;
  93. info->Additional.LNBits = 1;
  94. info->Additional.LAlignment = ePERSTIAlignment_OctetAligned;
  95. /* PER informations are type specific ... */
  96. switch (type->Type) {
  97. case eType_Boolean:
  98. ExaminePERType_Boolean(ass, type, per, info);
  99. break;
  100. case eType_Integer:
  101. ExaminePERType_Integer(ass, type, per, info);
  102. break;
  103. case eType_Enumerated:
  104. ExaminePERType_Enumerated(ass, type, per, info);
  105. break;
  106. case eType_Real:
  107. ExaminePERType_Real(ass, type, per, info);
  108. break;
  109. case eType_BitString:
  110. ExaminePERType_BitString(ass, type, per, info);
  111. break;
  112. case eType_OctetString:
  113. ExaminePERType_OctetString(ass, type, per, info);
  114. break;
  115. case eType_UTF8String:
  116. ExaminePERType_UTF8String(ass, type, per, info);
  117. break;
  118. case eType_Null:
  119. ExaminePERType_Null(ass, type, per, info);
  120. break;
  121. case eType_EmbeddedPdv:
  122. ExaminePERType_EmbeddedPdv(ass, type, per, info);
  123. break;
  124. case eType_External:
  125. ExaminePERType_External(ass, type, per, info);
  126. break;
  127. case eType_ObjectIdentifier:
  128. ExaminePERType_ObjectIdentifier(ass, type, per, info);
  129. break;
  130. case eType_BMPString:
  131. ExaminePERType_BMPString(ass, type, per, info);
  132. break;
  133. case eType_GeneralString:
  134. ExaminePERType_GeneralString(ass, type, per, info);
  135. break;
  136. case eType_GraphicString:
  137. ExaminePERType_GraphicString(ass, type, per, info);
  138. break;
  139. case eType_IA5String:
  140. ExaminePERType_IA5String(ass, type, per, info);
  141. break;
  142. case eType_ISO646String:
  143. ExaminePERType_ISO646String(ass, type, per, info);
  144. break;
  145. case eType_NumericString:
  146. ExaminePERType_NumericString(ass, type, per, info);
  147. break;
  148. case eType_PrintableString:
  149. ExaminePERType_PrintableString(ass, type, per, info);
  150. break;
  151. case eType_TeletexString:
  152. ExaminePERType_TeletexString(ass, type, per, info);
  153. break;
  154. case eType_T61String:
  155. ExaminePERType_T61String(ass, type, per, info);
  156. break;
  157. case eType_UniversalString:
  158. ExaminePERType_UniversalString(ass, type, per, info);
  159. break;
  160. case eType_VideotexString:
  161. ExaminePERType_VideotexString(ass, type, per, info);
  162. break;
  163. case eType_VisibleString:
  164. ExaminePERType_VisibleString(ass, type, per, info);
  165. break;
  166. case eType_CharacterString:
  167. ExaminePERType_UnrestrictedString(ass, type, per, info);
  168. break;
  169. case eType_GeneralizedTime:
  170. ExaminePERType_GeneralizedTime(ass, type, per, info);
  171. break;
  172. case eType_UTCTime:
  173. ExaminePERType_UTCTime(ass, type, per, info);
  174. break;
  175. case eType_ObjectDescriptor:
  176. ExaminePERType_ObjectDescriptor(ass, type, per, info);
  177. break;
  178. case eType_Open:
  179. ExaminePERType_Open(ass, type, per, info);
  180. break;
  181. case eType_Sequence:
  182. case eType_Set:
  183. case eType_InstanceOf:
  184. ExaminePERType_SequenceSet(ass, type, per, info);
  185. break;
  186. case eType_SequenceOf:
  187. case eType_SetOf:
  188. ExaminePERType_SequenceSetOf(ass, type, per, info);
  189. break;
  190. case eType_Choice:
  191. ExaminePERType_Choice(ass, type, per, info);
  192. break;
  193. case eType_RestrictedString:
  194. MyAbort(); /* may never happen */
  195. /*NOTREACHED*/
  196. case eType_Selection:
  197. MyAbort(); /* may never happen */
  198. /*NOTREACHED*/
  199. case eType_Undefined:
  200. MyAbort(); /* may never happen */
  201. /*NOTREACHED*/
  202. case eType_Reference:
  203. ExaminePERType_Reference(ass, type, per, info);
  204. break;
  205. }
  206. /* get real Length, LNBits and LAlignment */
  207. if (info->Root.Length == ePERSTILength_Length) {
  208. switch (info->Root.LConstraint) {
  209. case ePERSTIConstraint_Constrained:
  210. lrange = info->Root.LUpperVal - info->Root.LLowerVal + 1;
  211. lrangelog2 = uint32_log2(lrange);
  212. if (info->Root.LUpperVal < 0x10000) {
  213. if (lrange < 0x100) {
  214. info->Root.Length = ePERSTILength_BitLength;
  215. info->Root.LAlignment = ePERSTIAlignment_BitAligned;
  216. info->Root.LNBits = lrangelog2;
  217. } else if (lrange == 0x100) {
  218. info->Root.Length = ePERSTILength_BitLength;
  219. info->Root.LNBits = 8;
  220. } else if (lrange <= 0x10000) {
  221. info->Root.Length = ePERSTILength_BitLength;
  222. info->Root.LNBits = 16;
  223. } else {
  224. info->Root.Length = ePERSTILength_InfiniteLength;
  225. info->Root.LLowerVal = 0;
  226. }
  227. } else {
  228. info->Root.Length = ePERSTILength_InfiniteLength;
  229. info->Root.LLowerVal = 0;
  230. }
  231. break;
  232. case ePERSTIConstraint_Semiconstrained:
  233. info->Root.Length = ePERSTILength_InfiniteLength;
  234. info->Root.LLowerVal = 0;
  235. break;
  236. }
  237. } else if (info->Root.Length == ePERSTILength_NoLength) {
  238. info->Root.LAlignment = ePERSTIAlignment_BitAligned;
  239. }
  240. }
  241. /*
  242. * Description of the fields of PERTypeInfo_t:
  243. * info.
  244. * Identifier complete name of the type
  245. * Rules encoding directive rules
  246. * Flags encoding flags
  247. * EnumerationValues values of enumeration type
  248. * NOctets size of string characters/integer type
  249. * Type unextended/extendable/extended
  250. * Root information for the extension root
  251. * Additional information for the extensions
  252. * info.{Root,Additional}.
  253. * Data data type of value
  254. * TableIdentifier name of stringtable to use
  255. * Table stringtable to use
  256. * SubIdentifier complete name of the subtype
  257. * SubType the subtype itself
  258. * Identification identification of EMBEDDED PDV/CHARACTER STRING
  259. * NBits number of bits to use
  260. * Constraint constraint of type values
  261. * LowerVal lower bound of values (if constrained)
  262. * UpperVal upper bound of values (if constrained)
  263. * Alignment alignment to be used for value encoding
  264. * Length type of length encoding
  265. * LConstraint constraint of length
  266. * LLowerVal lower bound of length
  267. * LUpperVal upper bound of length
  268. * LAlignment alignment to be used for length encoding
  269. *
  270. * NOTES:
  271. * The encoding is mostly controlled by following arguments:
  272. * - Data, the type: one of:
  273. * ePERSTIData_Null, ePERSTIData_Boolean,
  274. * ePERSTIData_Integer, ePERSTIData_Unsigned,
  275. * ePERSTIData_Real, ePERSTIData_BitString, ePERSTIData_RZBBitString,
  276. * ePERSTIData_OctetString, ePERSTIData_SequenceOf, ePERSTIData_SetOf,
  277. * ePERSTIData_ObjectIdentifier, ePERSTIData_NormallySmall,
  278. * ePERSTIData_String, ePERSTIData_TableString, ePERSTIData_ZeroString,
  279. * ePERSTIData_ZeroTableString, ePERSTIData_Reference,
  280. * ePERSTIData_Extension, ePERSTIData_External,
  281. * ePERSTIData_EmbeddedPdv, ePERSTIData_UnrestrictedString
  282. * - NBits, the item size for encoding
  283. * - Length, the length encoding: one of:
  284. * ePERSTILength_NoLength, ePERSTILength_SmallLength,
  285. * ePERSTILength_Length
  286. * (internally eLength will be replaced by one of:
  287. * ePERSTILength_BitLength, ePERSTILength_InfiniteLength,
  288. * depending on the constraints)
  289. *
  290. * Additional arguments:
  291. * - Alignment, the value alignment: one of:
  292. * ePERSTIAlignment_BitAligned, ePERSTIAlignment_OctetAligned
  293. * - LAlignment, the length alignment: one of:
  294. * ePERSTIAlignment_BitAligned, ePERSTIAlignment_OctetAligned
  295. * - Constraint, the value constraint: one of:
  296. * ePERSTIConstraint_Unconstrained, ePERSTIConstraint_Semiconstrained,
  297. * ePERSTIConstraint_Upperconstrained, ePERSTIConstraint_Constrained
  298. * - LConstraint, the length constraint: one of:
  299. * ePERSTIConstraint_Semiconstrained, ePERSTIConstraint_Constrained
  300. *
  301. * Following arguments contain variable/function names in the generated
  302. * code:
  303. * - Identifier, the name of the current type
  304. * - SubIdentifier, the name of the subtype
  305. * - TableIdentifier, the name of the stringtable
  306. *
  307. * Following values require additional arguments:
  308. * - Constraint == ePERSTIConstraint_Semiconstrained ||
  309. * Constraint == ePERSTIConstraint_Constrained:
  310. * -> LowerVal, the lower bound of the value
  311. * - Constraint == ePERSTIConstraint_Upperconstrained ||
  312. * Constraint == ePERSTIConstraint_Constrained:
  313. * -> UpperVal, the upper bound of the value
  314. * - Length == ePERSTILength_Length:
  315. * -> LLowerVal, the lower bound of the length
  316. * - Length == ePERSTILength_Length &&
  317. * LConstraint == ePERSTIConstraint_Constrained:
  318. * -> LUpperVal, the upper bound of the length
  319. * - Data == ePERSTIData_TableString ||
  320. * Data == ePERSTIData_ZeroTableString:
  321. * -> TableIdentifier, the name of the string table
  322. * -> Table, the string table
  323. * - Data == ePERSTIData_Reference:
  324. * -> SubIdentifier, the name of the subtype
  325. * -> SubType, the subtype itself
  326. * - Data == ePERSTIData_*String:
  327. * -> NOctets, the size of the string characters
  328. * - Data == ePERSTIData_Integer || Data == ePERSTIData_Unsigned ||
  329. * Data == ePERSTIData_Boolean:
  330. * -> NOctets, the size of the integer type
  331. * - Data == ePERSTIData_SequenceOf || Data == ePERSTIData_SetOf:
  332. * -> SubIdentifier, the name of the subtype
  333. * -> SubType, the subtype itself
  334. * -> Rule, the encoding directive rules
  335. * - Data == ePERSTIData_EmbeddedPdv ||
  336. * Data == ePERSTIData_UnrestrictedString
  337. * -> Identification, the identification of the type if the type
  338. * is constraint to fixed identification or syntaxes identification
  339. * with single value
  340. *
  341. * Following values have optional arguments:
  342. * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned:
  343. * -> EnumerationValues, the mapping for enumeration values
  344. *
  345. * Following combinations are allowed:
  346. *
  347. * Data/NBits/Length Description
  348. * -----------------------------------------------------------------------
  349. * Null/0/NoLength NULL type
  350. *
  351. * Boolean/1/NoLength boolean value, stored in an
  352. * int{8,16,32}_t/intx_t
  353. * (noctets == 1/2/4/0)
  354. *
  355. * Integer/0/NoLength constrained whole number of fixed
  356. * value, stored in an
  357. * int{8,16,32}_t/intx_t
  358. * (noctets == 1/2/4/0)
  359. *
  360. * Integer/n/NoLength constrained whole number of fixed
  361. * length < 64K, stored in an
  362. * int{8,16,32}_t/intx_t
  363. * (noctets == 1/2/4/0)
  364. * encoded in n bits
  365. *
  366. * Integer/8/Length constrained whole number of var.
  367. * length or length >= 64K or
  368. * semiconstrained or unconstrained
  369. * whole number, stored in an
  370. * int{8,16,32}_t/intx_t
  371. * (noctets == 1/2/4/0)
  372. * encoded in units of octets
  373. *
  374. * Unsigned/0/NoLength constrained whole number of fixed
  375. * value, stored in an
  376. * uint{8,16,32}_t/intx_t
  377. * (noctets == 1/2/4/0)
  378. *
  379. * Unsigned/n/NoLength constrained whole number of fixed
  380. * length < 64K, stored in an
  381. * uint{8,16,32}_t/intx_t
  382. * (noctets == 1/2/4/0)
  383. * encoded in n bits
  384. *
  385. * Unsigned/8/Length constrained whole number of var.
  386. * length or length >= 64K or
  387. * semiconstrained or unconstrained
  388. * whole number, stored in an
  389. * uint{8,16,32}_t/intx_t
  390. * (noctets == 1/2/4/0)
  391. * encoded in units of octets
  392. *
  393. * NormallySmall/1/NoLength normally small non-negative
  394. * whole number, stored in an
  395. * uint{8,16,32}_t
  396. * (noctets == 1/2/4)
  397. *
  398. * Real/8/Length REAL value
  399. *
  400. * *BitString/0/NoLength BIT STRING of fixed length 0
  401. *
  402. * *BitString/1/NoLength BIT STRING of fixed length < 64K
  403. *
  404. * *BitString/1/Length BIT STRING of var. length or
  405. * length >= 64K or semiconstrained
  406. * length, encoded in units of bits
  407. *
  408. * "RZB" in e*BitString means, bit
  409. * strings with removed leading zero bits
  410. *
  411. * OctetString/0/NoLength OCTET STRING of fixed length 0
  412. *
  413. * OctetString/8/NoLength OCTET STRING of fixed length < 64K,
  414. *
  415. * OctetString/8/Length OCTET STRING of var. length or
  416. * length >= 64K or semiconstrained
  417. * length, encoded in units of octets
  418. *
  419. * Extension/n/NoLength bit field representing presence or
  420. * absence of <64K OPTIONAL/DEFAULT
  421. * components in SEQUENCEs/SETs, encoded
  422. * in n bits
  423. *
  424. * Extension/n/Length bit field representing presence or
  425. * absence of >=64K OPTIONAL/DEFAULT
  426. * components in SEQUENCEs/SETs, encoded
  427. * in n bits
  428. *
  429. * Extension/n/SmallLength bit field representing presence or
  430. * absence of components in the extension
  431. * of SEQUENCEs/SETs, encoded in n bits
  432. *
  433. * ObjectIdentifier/8/Length OBJECT IDENTIFIER value
  434. *
  435. * *String/0/NoLength String of fixed length 0
  436. *
  437. * *String/n/NoLength String of fixed length < 64K,
  438. * encoded in n bits
  439. *
  440. * *String/n/Length String of var. length or
  441. * length >= 64K or semiconstrained
  442. * length, encoded in units of n bits
  443. *
  444. * "Zero" in *String means
  445. * zero-terminated strings,
  446. * "Table" means renumbering of the
  447. * characters.
  448. *
  449. * MultibyteString/8/Length not known-multiplier character strings
  450. *
  451. * SequenceOf/0/NoLength SEQUENCE OF subtype or SET OF subtype
  452. * SetOf/0/NoLength of zero length
  453. *
  454. * SequenceOf/1/NoLength SEQUENCE OF subtype or SET OF subtype
  455. * SetOf/1/NoLength of fixed length <64K
  456. *
  457. * SequenceOf/1/Length SEQUENCE OF subtype or SET OF subtype
  458. * SetOf/1/Length of var. length or length >= 64K or
  459. * semiconstrained length
  460. *
  461. * External/8/NoLength EXTERNAL
  462. *
  463. * EmbeddedPdv/8/Length EMBEDDED PDV
  464. *
  465. * UnrestrictedString/8/Length CHARACTER STRING
  466. *
  467. * GeneralizedTime/n/NoLength GeneralizedTime, encoded in units of
  468. * n bits
  469. *
  470. * UTCTime/n/NoLength UTCTime, encoded in units of n bits
  471. *
  472. * Reference/1/NoLength Reference to a structured subtype
  473. *
  474. * Open/8/Length Open type
  475. */
  476. /* for sorting of intx_t's */
  477. static int
  478. __cdecl CmpIntxP(const void *v1, const void *v2)
  479. {
  480. intx_t *n1 = *(intx_t **)v1;
  481. intx_t *n2 = *(intx_t **)v2;
  482. return intx_cmp(n1, n2);
  483. }
  484. /*
  485. * BOOLEAN:
  486. *
  487. * Data/NBits/Length used for encoding:
  488. *
  489. * Boolean/1/NoLength boolean value, stored in an
  490. * int{8,16,32}_t/intx_t
  491. * (noctets == 1/2/4/0)
  492. *
  493. * Additional arguments:
  494. *
  495. * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned ||
  496. * Data == ePERSTIData_Boolean
  497. * -> NOctets, the size of the integer type
  498. */
  499. void
  500. ExaminePERType_Boolean(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  501. {
  502. info->Root.Data = ePERSTIData_Boolean;
  503. info->NOctets = GetOctets(GetBooleanType());
  504. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  505. }
  506. /*
  507. * INTEGER:
  508. *
  509. * Data/NBits/Length used for encoding:
  510. *
  511. * Integer/0/NoLength constrained whole number of fixed
  512. * value, stored in an
  513. * int{8,16,32}_t/intx_t
  514. * (noctets == 1/2/4/0)
  515. *
  516. * Integer/n/NoLength constrained whole number of fixed
  517. * length < 64K, stored in an
  518. * int{8,16,32}_t/intx_t
  519. * (noctets == 1/2/4/0)
  520. * encoded in n bits
  521. *
  522. * Integer/8/Length constrained whole number of var.
  523. * length or length >= 64K or
  524. * semiconstrained or unconstrained
  525. * whole number, stored in an
  526. * int{8,16,32}_t/intx_t
  527. * (noctets == 1/2/4/0)
  528. * encoded in units of octets
  529. *
  530. * Unsigned/0/NoLength constrained whole number of fixed
  531. * value, stored in an
  532. * uint{8,16,32}_t/intx_t
  533. * (noctets == 1/2/4/0)
  534. *
  535. * Unsigned/n/NoLength constrained whole number of fixed
  536. * length < 64K, stored in an
  537. * uint{8,16,32}_t/intx_t
  538. * (noctets == 1/2/4/0)
  539. * encoded in n bits
  540. *
  541. * Unsigned/8/Length constrained whole number of var.
  542. * length or length >= 64K or
  543. * semiconstrained or unconstrained
  544. * whole number, stored in an
  545. * uint{8,16,32}_t/intx_t
  546. * (noctets == 1/2/4/0)
  547. * encoded in units of octets
  548. *
  549. * Additional arguments:
  550. *
  551. * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned ||
  552. * Data == ePERSTIData_Boolean
  553. * -> NOctets, the size of the integer type
  554. */
  555. void
  556. ExaminePERType_Integer(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  557. {
  558. EndPoint_t lower, upper;
  559. int32_t sign;
  560. intx_t range;
  561. uint32_t rangelog2;
  562. uint32_t rangelog256;
  563. /* calculate LowerVal, UpperVal and range of extension root */
  564. /* set Constraint according to presence of LowerVal/UpperVal */
  565. if (per->Value.Type == eExtension_Unconstrained) {
  566. lower.Flags = eEndPoint_Min;
  567. upper.Flags = eEndPoint_Max;
  568. } else {
  569. lower.Flags = eEndPoint_Max;
  570. upper.Flags = eEndPoint_Min;
  571. GetMinMax(ass, per->Value.Root, &lower, &upper);
  572. if (lower.Flags & eEndPoint_Max)
  573. lower.Flags = eEndPoint_Min;
  574. if (upper.Flags & eEndPoint_Min)
  575. upper.Flags = eEndPoint_Max;
  576. }
  577. if (!(lower.Flags & eEndPoint_Min)) {
  578. intx_dup(&info->Root.LowerVal,
  579. &GetValue(ass, lower.Value)->U.Integer.Value);
  580. info->Root.Constraint = ePERSTIConstraint_Semiconstrained;
  581. }
  582. if (!(upper.Flags & eEndPoint_Max)) {
  583. intx_dup(&info->Root.UpperVal,
  584. &GetValue(ass, upper.Value)->U.Integer.Value);
  585. info->Root.Constraint = ePERSTIConstraint_Upperconstrained;
  586. }
  587. if (!(lower.Flags & eEndPoint_Min) && !(upper.Flags & eEndPoint_Max)) {
  588. intx_sub(&range, &info->Root.UpperVal, &info->Root.LowerVal);
  589. intx_inc(&range);
  590. rangelog2 = intx_log2(&range);
  591. rangelog256 = intx_log256(&range);
  592. info->Root.Constraint = ePERSTIConstraint_Constrained;
  593. }
  594. /* calculate NOctets and Data depending on the used C-Type */
  595. info->NOctets = GetOctets(GetIntegerType(ass, type, &sign));
  596. info->Root.Data = sign > 0 ? ePERSTIData_Unsigned : ePERSTIData_Integer;
  597. /* calculate Length, NBits, Alignment, LConstraint, LLowerVal and */
  598. /* LUpperVal */
  599. switch (info->Root.Constraint) {
  600. case ePERSTIConstraint_Unconstrained:
  601. case ePERSTIConstraint_Semiconstrained:
  602. case ePERSTIConstraint_Upperconstrained:
  603. info->Root.Length = ePERSTILength_Length;
  604. info->Root.NBits = 8;
  605. info->Root.LLowerVal = 1;
  606. break;
  607. case ePERSTIConstraint_Constrained:
  608. if (intx_cmp(&range, &intx_1) == 0) {
  609. info->Root.NBits = 0;
  610. } else if (intx_cmp(&range, &intx_256) < 0 || Alignment == eAlignment_Unaligned) {
  611. info->Root.NBits = rangelog2;
  612. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  613. } else if (intx_cmp(&range, &intx_256) == 0) {
  614. info->Root.NBits = 8;
  615. } else if (intx_cmp(&range, &intx_64K) <= 0) {
  616. info->Root.NBits = 16;
  617. } else {
  618. info->Root.NBits = 8;
  619. info->Root.Length = ePERSTILength_Length;
  620. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  621. info->Root.LLowerVal = 1;
  622. info->Root.LUpperVal = rangelog256;
  623. }
  624. }
  625. /* check for extensions */
  626. info->Type = per->Value.Type;
  627. if (info->Type == eExtension_Unconstrained)
  628. info->Type = eExtension_Unextended;
  629. info->Additional.Data = info->Root.Data;
  630. }
  631. /*
  632. * ENUMERATED:
  633. *
  634. * Data/NBits/Length used for encoding:
  635. *
  636. * Integer/0/NoLength constrained whole number of fixed
  637. * value, stored in an
  638. * int{8,16,32}_t/intx_t
  639. * (noctets == 1/2/4/0)
  640. *
  641. * Integer/n/NoLength constrained whole number of fixed
  642. * length < 64K, stored in an
  643. * int{8,16,32}_t/intx_t
  644. * (noctets == 1/2/4/0)
  645. * encoded in n bits
  646. *
  647. * Integer/8/Length constrained whole number of var.
  648. * length or length >= 64K or
  649. * semiconstrained or unconstrained
  650. * whole number, stored in an
  651. * int{8,16,32}_t/intx_t
  652. * (noctets == 1/2/4/0)
  653. * encoded in units of octets
  654. *
  655. * Unsigned/0/NoLength constrained whole number of fixed
  656. * value, stored in an
  657. * uint{8,16,32}_t/intx_t
  658. * (noctets == 1/2/4/0)
  659. *
  660. * Unsigned/n/NoLength constrained whole number of fixed
  661. * length < 64K, stored in an
  662. * uint{8,16,32}_t/intx_t
  663. * (noctets == 1/2/4/0)
  664. * encoded in n bits
  665. *
  666. * Unsigned/8/Length constrained whole number of var.
  667. * length or length >= 64K or
  668. * semiconstrained or unconstrained
  669. * whole number, stored in an
  670. * uint{8,16,32}_t/intx_t
  671. * (noctets == 1/2/4/0)
  672. * encoded in units of octets
  673. *
  674. * NormallySmall/1/NoLength normally small non-negative
  675. * whole number, stored in an
  676. * uint{8,16,32}_t
  677. * (noctets == 1/2/4)
  678. *
  679. * Additional arguments:
  680. *
  681. * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned ||
  682. * Data == ePERSTIData_Boolean
  683. * -> NOctets, the size of the integer type
  684. */
  685. void
  686. ExaminePERType_Enumerated(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  687. {
  688. uint32_t nroot, nindex, i;
  689. NamedNumber_t *n;
  690. int32_t sign;
  691. uint32_t rangelog2;
  692. intx_t range;
  693. /* count number of enumeration values in extension root and extension */
  694. /* set extension type of extensions are present/possible */
  695. nroot = nindex = 0;
  696. for (n = type->U.Enumerated.NamedNumbers; n; n = n->Next) {
  697. switch (n->Type) {
  698. case eNamedNumber_Normal:
  699. nindex++;
  700. switch (info->Type) {
  701. case eExtension_Unextended:
  702. nroot = nindex;
  703. break;
  704. case eExtension_Extendable:
  705. info->Type = eExtension_Extended;
  706. break;
  707. }
  708. break;
  709. case eNamedNumber_ExtensionMarker:
  710. info->Type = eExtension_Extendable;
  711. break;
  712. }
  713. }
  714. /* allocate table for enumeration values and copy the values into */
  715. info->EnumerationValues =
  716. (intx_t **)malloc((nindex + 1) * sizeof(intx_t *));
  717. nindex = 0;
  718. for (n = type->U.Enumerated.NamedNumbers; n; n = n->Next) {
  719. switch (n->Type) {
  720. case eNamedNumber_Normal:
  721. info->EnumerationValues[nindex++] =
  722. &GetValue(ass, n->U.Normal.Value)->U.Integer.Value;
  723. break;
  724. case eNamedNumber_ExtensionMarker:
  725. break;
  726. }
  727. }
  728. info->EnumerationValues[nindex] = 0;
  729. /* sort values of extension root according to their value */
  730. qsort(info->EnumerationValues, nroot,
  731. sizeof(*info->EnumerationValues), CmpIntxP);
  732. /* check the need for an index translation */
  733. for (i = 0; info->EnumerationValues[i]; i++) {
  734. if (intx2uint32(info->EnumerationValues[i]) != i)
  735. break;
  736. }
  737. if (!info->EnumerationValues[i])
  738. info->EnumerationValues = NULL;
  739. /* calculate NOctets and Data depending on the used C-Type */
  740. info->NOctets = GetOctets(GetEnumeratedType(ass, type, &sign));
  741. info->Root.Data = sign > 0 ? ePERSTIData_Unsigned : ePERSTIData_Integer;
  742. /* enumeration is always constrained to value from 0 to nroot-1 */
  743. info->Root.Constraint = ePERSTIConstraint_Constrained;
  744. intx_setuint32(&info->Root.LowerVal, 0);
  745. intx_setuint32(&info->Root.UpperVal, nroot - 1);
  746. intx_setuint32(&range, nroot);
  747. rangelog2 = intx_log2(&range);
  748. /* calculate NBits and Alignment */
  749. if (nroot <= 1) {
  750. info->Root.NBits = 0;
  751. } else if (nroot < 256) {
  752. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  753. info->Root.NBits = rangelog2;
  754. } else if (nroot == 256) {
  755. info->Root.NBits = 8;
  756. } else if (nroot < 65536) {
  757. info->Root.NBits = 16;
  758. } else {
  759. MyAbort();
  760. }
  761. /* values of extension will always be encoded as normally small numbers */
  762. /* with lowerbound = nroot */
  763. info->Additional.Data = ePERSTIData_NormallySmall;
  764. info->Additional.NBits = 1;
  765. info->Additional.Alignment = ePERSTIAlignment_BitAligned;
  766. info->Additional.Length = ePERSTILength_NoLength;
  767. info->Additional.Constraint = ePERSTIConstraint_Semiconstrained;
  768. intx_setuint32(&info->Additional.LowerVal, nroot);
  769. }
  770. /*
  771. * REAL:
  772. *
  773. * Data/NBits/Length used for encoding:
  774. *
  775. * Real/8/Length REAL value
  776. *
  777. * Additional arguments:
  778. *
  779. * none
  780. */
  781. void
  782. ExaminePERType_Real(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  783. {
  784. info->Root.Data = ePERSTIData_Real;
  785. info->Root.NBits = 8;
  786. info->NOctets = GetOctets(GetRealType(type));
  787. }
  788. /*
  789. * BIT STRING:
  790. *
  791. * Data/NBits/Length used for encoding:
  792. *
  793. * *BitString/0/NoLength BIT STRING of fixed length 0
  794. *
  795. * *BitString/1/NoLength BIT STRING of fixed length < 64K,
  796. * encoded in n bits
  797. *
  798. * *BitString/1/Length BIT STRING of var. length or
  799. * length >= 64K or semiconstrained
  800. * length, encoded in units of bits
  801. *
  802. * "RZB" in e*BitString means, bit
  803. * strings with removed leading zero bits
  804. *
  805. * Additional arguments:
  806. *
  807. * none
  808. */
  809. void
  810. ExaminePERType_BitString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  811. {
  812. EndPoint_t lower, upper;
  813. /* calculate LConstraint, LLowerVal and LUpperVal */
  814. if (per->Size.Type != eExtension_Unconstrained) {
  815. lower.Flags = eEndPoint_Max;
  816. upper.Flags = eEndPoint_Min;
  817. GetMinMax(ass, per->Size.Root, &lower, &upper);
  818. if (upper.Flags & eEndPoint_Min)
  819. upper.Flags = eEndPoint_Max;
  820. info->Root.LLowerVal =
  821. intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value);
  822. info->Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  823. if (!(upper.Flags & eEndPoint_Max)) {
  824. info->Root.LUpperVal =
  825. intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value);
  826. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  827. }
  828. }
  829. /* calculate NBits, Alignment and Length */
  830. info->Root.cbFixedSizeBitString = 0; // clear it up first
  831. switch (info->Root.LConstraint) {
  832. case ePERSTIConstraint_Constrained:
  833. if (info->Root.LUpperVal == 0) {
  834. info->Root.NBits = 0;
  835. } else {
  836. info->Root.NBits = 1;
  837. if (info->Root.LLowerVal == info->Root.LUpperVal) {
  838. if (info->Root.LUpperVal <= 32)
  839. {
  840. info->Root.cbFixedSizeBitString = (info->Root.LUpperVal + 7) / 8;
  841. }
  842. if (info->Root.LUpperVal <= 16) {
  843. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  844. } else if (info->Root.LUpperVal >= 0x10000) {
  845. info->Root.Length = ePERSTILength_Length;
  846. }
  847. } else {
  848. info->Root.Length = ePERSTILength_Length;
  849. }
  850. }
  851. break;
  852. case ePERSTIConstraint_Semiconstrained:
  853. info->Root.NBits = 1;
  854. info->Root.Length = ePERSTILength_Length;
  855. break;
  856. }
  857. /* get extension type */
  858. info->Type = per->Size.Type;
  859. if (info->Type == eExtension_Unconstrained)
  860. info->Type = eExtension_Unextended;
  861. /* set Data to RZBBitString/BitString */
  862. if (type->U.BitString.NamedNumbers)
  863. info->Root.Data = ePERSTIData_RZBBitString;
  864. else
  865. info->Root.Data = ePERSTIData_BitString;
  866. /* set extension informations */
  867. info->Additional.Data = info->Root.Data;
  868. info->Additional.NBits = 1;
  869. }
  870. /*
  871. * OCTET STRING:
  872. *
  873. * Data/NBits/Length used for encoding:
  874. *
  875. * OctetString/0/NoLength OCTET STRING of fixed length 0
  876. *
  877. * OctetString/8/NoLength OCTET STRING of fixed length < 64K,
  878. *
  879. * OctetString/8/Length OCTET STRING of var. length or
  880. * length >= 64K or semiconstrained
  881. * length, encoded in units of octets
  882. *
  883. * Additional arguments:
  884. *
  885. * none
  886. */
  887. void
  888. ExaminePERType_OctetString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  889. {
  890. EndPoint_t lower, upper;
  891. /* calculate LConstraint, LLowerVal and LUpperVal */
  892. if (per->Size.Type != eExtension_Unconstrained) {
  893. lower.Flags = eEndPoint_Max;
  894. upper.Flags = eEndPoint_Min;
  895. GetMinMax(ass, per->Size.Root, &lower, &upper);
  896. if (upper.Flags & eEndPoint_Min)
  897. upper.Flags = eEndPoint_Max;
  898. info->Root.LLowerVal =
  899. intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value);
  900. info->Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  901. if (!(upper.Flags & eEndPoint_Max)) {
  902. info->Root.LUpperVal =
  903. intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value);
  904. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  905. }
  906. }
  907. /* calculate NBits, Alignment and Length */
  908. switch (info->Root.LConstraint) {
  909. case ePERSTIConstraint_Constrained:
  910. if (info->Root.LUpperVal == 0) {
  911. info->Root.NBits = 0;
  912. } else {
  913. info->Root.NBits = 8;
  914. if (info->Root.LLowerVal == info->Root.LUpperVal) {
  915. if (info->Root.LUpperVal <= 2) {
  916. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  917. } else if (info->Root.LUpperVal >= 0x10000) {
  918. info->Root.Length = ePERSTILength_Length;
  919. }
  920. } else {
  921. info->Root.Length = ePERSTILength_Length;
  922. }
  923. }
  924. break;
  925. case ePERSTIConstraint_Semiconstrained:
  926. info->Root.NBits = 8;
  927. info->Root.Length = ePERSTILength_Length;
  928. break;
  929. }
  930. /* get extension type */
  931. info->Type = per->Size.Type;
  932. if (info->Type == eExtension_Unconstrained)
  933. info->Type = eExtension_Unextended;
  934. /* set Data to OctetString */
  935. info->Root.Data = ePERSTIData_OctetString;
  936. /* set extension informations */
  937. info->Additional.Data = info->Root.Data;
  938. }
  939. void
  940. ExaminePERType_UTF8String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  941. {
  942. EndPoint_t lower, upper;
  943. /* calculate LConstraint, LLowerVal and LUpperVal */
  944. if (per->Size.Type != eExtension_Unconstrained) {
  945. lower.Flags = eEndPoint_Max;
  946. upper.Flags = eEndPoint_Min;
  947. GetMinMax(ass, per->Size.Root, &lower, &upper);
  948. if (upper.Flags & eEndPoint_Min)
  949. upper.Flags = eEndPoint_Max;
  950. info->Root.LLowerVal =
  951. intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value);
  952. info->Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  953. if (!(upper.Flags & eEndPoint_Max)) {
  954. info->Root.LUpperVal =
  955. intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value);
  956. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  957. }
  958. }
  959. /* calculate NBits, Alignment and Length */
  960. switch (info->Root.LConstraint) {
  961. case ePERSTIConstraint_Constrained:
  962. if (info->Root.LUpperVal == 0) {
  963. info->Root.NBits = 0;
  964. } else {
  965. info->Root.NBits = 8;
  966. if (info->Root.LLowerVal == info->Root.LUpperVal) {
  967. if (info->Root.LUpperVal <= 2) {
  968. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  969. } else if (info->Root.LUpperVal >= 0x10000) {
  970. info->Root.Length = ePERSTILength_Length;
  971. }
  972. } else {
  973. info->Root.Length = ePERSTILength_Length;
  974. }
  975. }
  976. break;
  977. case ePERSTIConstraint_Semiconstrained:
  978. info->Root.NBits = 8;
  979. info->Root.Length = ePERSTILength_Length;
  980. break;
  981. }
  982. /* get extension type */
  983. info->Type = per->Size.Type;
  984. if (info->Type == eExtension_Unconstrained)
  985. info->Type = eExtension_Unextended;
  986. /* set Data to OctetString */
  987. info->Root.Data = ePERSTIData_UTF8String;
  988. /* set extension informations */
  989. info->Additional.Data = info->Root.Data;
  990. }
  991. /*
  992. * NULL:
  993. *
  994. * Data/NBits/Length used for encoding:
  995. *
  996. * Null/0/NoLength NULL type
  997. *
  998. * Additional arguments:
  999. *
  1000. * none
  1001. */
  1002. void
  1003. ExaminePERType_Null(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1004. {
  1005. info->Root.NBits = 0;
  1006. info->Root.Data = ePERSTIData_Null;
  1007. }
  1008. /*
  1009. * EMBEDDED PDV:
  1010. *
  1011. * Data/NBits/Length used for encoding:
  1012. *
  1013. * EmbeddedPdv/8/Length EMBEDDED PDV
  1014. *
  1015. * Additional arguments:
  1016. *
  1017. * - Data == ePERSTIData_EmbeddedPdv ||
  1018. * Data == ePERSTIData_UnrestrictedString
  1019. * -> Identification, the identification of the type if the type
  1020. * is constraint to fixed identification or syntaxes identification
  1021. * with single value
  1022. */
  1023. void
  1024. ExaminePERType_EmbeddedPdv(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1025. {
  1026. info->Root.Identification = GetFixedIdentification(ass, type->Constraints);
  1027. info->Root.Data = ePERSTIData_EmbeddedPdv;
  1028. info->Root.NBits = 8;
  1029. info->Root.Length = ePERSTILength_Length;
  1030. }
  1031. /*
  1032. * EXTERNAL:
  1033. *
  1034. * Data/NBits/Length used for encoding:
  1035. *
  1036. * External/8/Length EXTERNAL
  1037. *
  1038. * Additional arguments:
  1039. *
  1040. * none
  1041. */
  1042. void
  1043. ExaminePERType_External(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1044. {
  1045. info->Root.Data = ePERSTIData_External;
  1046. info->Root.NBits = 8;
  1047. info->Root.Length = ePERSTILength_Length;
  1048. }
  1049. /*
  1050. * OBJECT IDENTIFIER:
  1051. *
  1052. * Data/NBits/Length used for encoding:
  1053. *
  1054. * ObjectIdentifier/8/Length OBJECT IDENTIFIER value
  1055. *
  1056. * Additional arguments:
  1057. *
  1058. * none
  1059. */
  1060. void
  1061. ExaminePERType_ObjectIdentifier(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1062. {
  1063. info->Root.Data = ePERSTIData_ObjectIdentifier;
  1064. info->Root.NBits = 8;
  1065. info->Root.Length = ePERSTILength_Length;
  1066. }
  1067. /*
  1068. * *String:
  1069. *
  1070. * Data/NBits/Length used for encoding:
  1071. *
  1072. * *String/0/NoLength String of fixed length 0
  1073. *
  1074. * *String/n/NoLength String of fixed length < 64K,
  1075. * encoded in n bits
  1076. *
  1077. * *String/n/Length String of var. length or
  1078. * length >= 64K or semiconstrained
  1079. * length, encoded in units of n bits
  1080. *
  1081. * "Zero" in *String means
  1082. * zero-terminated strings,
  1083. * "Table" means renumbering of the
  1084. * characters.
  1085. *
  1086. * MultibyteString/8/Length not known-multiplier character strings
  1087. *
  1088. * Additional arguments:
  1089. *
  1090. * - Data == ePERSTIData_TableString || dat == ePERSTIData_ZeroTableString:
  1091. * -> TableIdentifier, the name of the string table
  1092. * -> Table, the string table
  1093. * - Data == ePERSTIData_*String:
  1094. * -> NOctets, the size of the string characters
  1095. */
  1096. void
  1097. ExaminePERType_BMPString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1098. {
  1099. intx_t up, nchars;
  1100. intx_setuint32(&up, 0xffff);
  1101. intx_setuint32(&nchars, 0x10000);
  1102. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1103. NULL, 16, per, info);
  1104. }
  1105. void
  1106. ExaminePERType_GeneralString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1107. {
  1108. uint32_t zero;
  1109. GetStringType(ass, type, &info->NOctets, &zero);
  1110. info->Root.NBits = 8;
  1111. info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String;
  1112. info->Root.Length = ePERSTILength_Length;
  1113. }
  1114. void
  1115. ExaminePERType_GraphicString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1116. {
  1117. uint32_t zero;
  1118. GetStringType(ass, type, &info->NOctets, &zero);
  1119. info->Root.NBits = 8;
  1120. info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String;
  1121. info->Root.Length = ePERSTILength_Length;
  1122. }
  1123. void
  1124. ExaminePERType_IA5String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1125. {
  1126. intx_t up, nchars;
  1127. intx_setuint32(&up, 0x7f);
  1128. intx_setuint32(&nchars, 0x80);
  1129. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1130. NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info);
  1131. }
  1132. void
  1133. ExaminePERType_ISO646String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1134. {
  1135. intx_t up, nchars;
  1136. intx_setuint32(&up, 0x7e);
  1137. intx_setuint32(&nchars, 0x5f);
  1138. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1139. NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info);
  1140. }
  1141. void
  1142. ExaminePERType_NumericString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1143. {
  1144. intx_t up, nchars;
  1145. intx_setuint32(&up, 0x39);
  1146. intx_setuint32(&nchars, 0xb);
  1147. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1148. "ASN1NumericStringTable", 4, per, info);
  1149. }
  1150. void
  1151. ExaminePERType_PrintableString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1152. {
  1153. intx_t up, nchars;
  1154. intx_setuint32(&up, 0x7a);
  1155. intx_setuint32(&nchars, 0x4a);
  1156. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1157. NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info);
  1158. }
  1159. void
  1160. ExaminePERType_TeletexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1161. {
  1162. info->Root.Data = ePERSTIData_MultibyteString;
  1163. info->Root.NBits = 8;
  1164. info->Root.Length = ePERSTILength_Length;
  1165. info->NOctets = 1;
  1166. }
  1167. void
  1168. ExaminePERType_T61String(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1169. {
  1170. info->Root.Data = ePERSTIData_MultibyteString;
  1171. info->Root.NBits = 8;
  1172. info->Root.Length = ePERSTILength_Length;
  1173. info->NOctets = 1;
  1174. }
  1175. void
  1176. ExaminePERType_UniversalString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1177. {
  1178. intx_t up, nchars;
  1179. intx_setuint32(&up, 0xffffffff);
  1180. intx_setuint32(&nchars, 0xffffffff);
  1181. intx_inc(&nchars);
  1182. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1183. NULL, 32, per, info);
  1184. }
  1185. void
  1186. ExaminePERType_VideotexString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1187. {
  1188. info->Root.Data = ePERSTIData_MultibyteString;
  1189. info->Root.NBits = 8;
  1190. info->Root.Length = ePERSTILength_Length;
  1191. info->NOctets = 1;
  1192. }
  1193. void
  1194. ExaminePERType_VisibleString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1195. {
  1196. intx_t up, nchars;
  1197. intx_setuint32(&up, 0x7e);
  1198. intx_setuint32(&nchars, 0x5f);
  1199. ExaminePERType_RestrictedString(ass, type, &up, &nchars,
  1200. NULL, Alignment == eAlignment_Aligned ? 8 : 7, per, info);
  1201. }
  1202. void
  1203. 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)
  1204. {
  1205. EndPoint_t lower, upper;
  1206. uint32_t zero, rangelog2;
  1207. intx_t ix, range;
  1208. char tabbuf[256];
  1209. /* calculate NOctets depending on the used C-Type */
  1210. GetStringType(ass, type, &info->NOctets, &zero);
  1211. /* calculate LConstraint, LLowerVal and LUpperVal if size constraint is */
  1212. /* given */
  1213. if (per->Size.Type != eExtension_Unconstrained) {
  1214. lower.Flags = eEndPoint_Max;
  1215. upper.Flags = eEndPoint_Min;
  1216. GetMinMax(ass, per->Size.Root, &lower, &upper);
  1217. if (upper.Flags & eEndPoint_Min)
  1218. upper.Flags = eEndPoint_Max;
  1219. if (lower.Flags & eEndPoint_Max) {
  1220. lower.Flags = 0;
  1221. lower.Value = Builtin_Value_Integer_0;
  1222. }
  1223. info->Root.LLowerVal =
  1224. intx2uint32(&GetValue(ass, lower.Value)->U.Integer.Value);
  1225. if (!(upper.Flags & eEndPoint_Max)) {
  1226. info->Root.LUpperVal =
  1227. intx2uint32(&GetValue(ass, upper.Value)->U.Integer.Value);
  1228. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  1229. }
  1230. }
  1231. /* get extension type */
  1232. info->Type = per->Size.Type;
  1233. if (info->Type == eExtension_Unconstrained)
  1234. info->Type = eExtension_Unextended;
  1235. /* get string table if permitted alphabet constraint is present */
  1236. /* update extension type if needed */
  1237. if (per->PermittedAlphabet.Type != eExtension_Unconstrained) {
  1238. info->Root.Table = per->PermittedAlphabet.Root;
  1239. if (per->PermittedAlphabet.Type > info->Type)
  1240. info->Type = per->PermittedAlphabet.Type;
  1241. if (CountValues(ass, info->Root.Table, &ix)) {
  1242. nchars = &ix;
  1243. sprintf(tabbuf, "%s_StringTable", info->Identifier);
  1244. tabref = tabbuf;
  1245. } else {
  1246. MyAbort(); /*XXX*/
  1247. }
  1248. }
  1249. /* get bits needed for one character */
  1250. info->Root.NBits = intx_log2(nchars);
  1251. if (Alignment == eAlignment_Aligned) {
  1252. if (info->Root.NBits > 16)
  1253. info->Root.NBits = 32;
  1254. else if (info->Root.NBits > 8)
  1255. info->Root.NBits = 16;
  1256. else if (info->Root.NBits > 4)
  1257. info->Root.NBits = 8;
  1258. else if (info->Root.NBits > 2)
  1259. info->Root.NBits = 4;
  1260. }
  1261. /* set data type */
  1262. info->Root.Data = tabref ?
  1263. (zero ? ePERSTIData_ZeroTableString : ePERSTIData_TableString) :
  1264. (zero ? ePERSTIData_ZeroString : ePERSTIData_String);
  1265. /* check if stringtable is really needed for encoding or extension check */
  1266. intx_dup(&range, up);
  1267. intx_inc(&range);
  1268. rangelog2 = intx_log2(&range);
  1269. if (rangelog2 <= info->Root.NBits) {
  1270. info->Root.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String;
  1271. if (per->PermittedAlphabet.Type < eExtension_Extended)
  1272. tabref = NULL;
  1273. }
  1274. info->Root.TableIdentifier = tabref ? strdup(tabref) : NULL;
  1275. /* calculate Length and Alignment */
  1276. switch (info->Root.LConstraint) {
  1277. case ePERSTIConstraint_Constrained:
  1278. if (info->Root.LUpperVal == 0) {
  1279. info->Root.NBits = 0;
  1280. } else {
  1281. if (info->Root.LLowerVal == info->Root.LUpperVal) {
  1282. if (info->Root.LUpperVal * info->Root.NBits <= 16) {
  1283. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  1284. } else if (info->Root.LUpperVal >= 0x10000) {
  1285. info->Root.Length = ePERSTILength_Length;
  1286. }
  1287. } else {
  1288. if (info->Root.LUpperVal * info->Root.NBits <= 16)
  1289. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  1290. info->Root.Length = ePERSTILength_Length;
  1291. }
  1292. }
  1293. break;
  1294. case ePERSTIConstraint_Semiconstrained:
  1295. info->Root.Length = ePERSTILength_Length;
  1296. break;
  1297. }
  1298. /* set extension informations */
  1299. info->Additional.Data = zero ? ePERSTIData_ZeroString : ePERSTIData_String;
  1300. info->Additional.NBits = enbits;
  1301. }
  1302. /*
  1303. * CHARACTER STRING:
  1304. *
  1305. * Data/NBits/Length used for encoding:
  1306. *
  1307. * UnrestrictedString/8/Length CHARACTER STRING
  1308. *
  1309. * Additional arguments:
  1310. *
  1311. * - Data == ePERSTIData_EmbeddedPdv ||
  1312. * Data == ePERSTIData_UnrestrictedString
  1313. * -> Identification, the identification of the type if the type
  1314. * is constraint to fixed identification or syntaxes identification
  1315. * with single value
  1316. */
  1317. void
  1318. ExaminePERType_UnrestrictedString(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1319. {
  1320. info->Root.Identification = GetFixedIdentification(ass, type->Constraints);
  1321. info->Root.Data = ePERSTIData_UnrestrictedString;
  1322. info->Root.NBits = 8;
  1323. info->Root.Length = ePERSTILength_Length;
  1324. }
  1325. /*
  1326. * GeneralizedTime:
  1327. *
  1328. * Data/NBits/Length used for encoding:
  1329. *
  1330. * GeneralizedTime/n/NoLength GeneralizedTime, encoded in units of
  1331. * n bits
  1332. *
  1333. * Additional arguments:
  1334. *
  1335. * none
  1336. */
  1337. void
  1338. ExaminePERType_GeneralizedTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1339. {
  1340. info->Root.NBits = (Alignment == eAlignment_Aligned) ? 8 : 7;
  1341. info->Root.Data = ePERSTIData_GeneralizedTime;
  1342. }
  1343. /*
  1344. * UTCTime:
  1345. *
  1346. * Data/NBits/Length used for encoding:
  1347. *
  1348. * UTCTime/n/NoLength UTCTime, encoded in units of
  1349. * n bits
  1350. *
  1351. * Additional arguments:
  1352. *
  1353. * none
  1354. */
  1355. void
  1356. ExaminePERType_UTCTime(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1357. {
  1358. info->Root.NBits = (Alignment == eAlignment_Aligned) ? 8 : 7;
  1359. info->Root.Data = ePERSTIData_UTCTime;
  1360. }
  1361. /*
  1362. * ObjectDescriptor:
  1363. *
  1364. * Data/NBits/Length used for encoding:
  1365. *
  1366. * *String/n/Length String of var. length or
  1367. * length >= 64K or semiconstrained
  1368. * length, encoded in units of n bits
  1369. *
  1370. * "Zero" in *String means
  1371. * zero-terminated strings
  1372. *
  1373. * Additional arguments:
  1374. *
  1375. * none
  1376. */
  1377. void
  1378. ExaminePERType_ObjectDescriptor(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1379. {
  1380. info->NOctets = 1;
  1381. info->Root.NBits = 8;
  1382. info->Root.Data = ePERSTIData_ZeroString;
  1383. info->Root.Length = ePERSTILength_Length;
  1384. }
  1385. /*
  1386. * OpenType:
  1387. *
  1388. * Data/NBits/Length used for encoding:
  1389. *
  1390. * Open/8/Length Open type
  1391. *
  1392. * Additional arguments:
  1393. *
  1394. * none
  1395. */
  1396. void
  1397. ExaminePERType_Open(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1398. {
  1399. info->NOctets = 1;
  1400. info->Root.NBits = 8;
  1401. info->Root.Data = ePERSTIData_Open;
  1402. info->Root.Length = ePERSTILength_Length;
  1403. }
  1404. /*
  1405. * SEQUENCE/SET:
  1406. *
  1407. * Data/NBits/Length used for encoding:
  1408. *
  1409. * none
  1410. *
  1411. * Additional arguments:
  1412. *
  1413. * none
  1414. */
  1415. void
  1416. ExaminePERType_SequenceSet(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1417. {
  1418. Component_t *comp;
  1419. NamedType_t *namedType;
  1420. char idebuf[256];
  1421. /* examine types of components */
  1422. for (comp = type->U.SSC.Components; comp; comp = comp->Next) {
  1423. switch (comp->Type) {
  1424. case eComponent_Normal:
  1425. case eComponent_Optional:
  1426. case eComponent_Default:
  1427. namedType = comp->U.NOD.NamedType;
  1428. sprintf(idebuf, "%s_%s", info->Identifier, namedType->Identifier);
  1429. ExaminePERType(ass, namedType->Type, strdup(idebuf));
  1430. break;
  1431. }
  1432. }
  1433. }
  1434. /*
  1435. * SEQUENCE OF/SET OF:
  1436. *
  1437. * Data/NBits/Length used for encoding:
  1438. *
  1439. * SequenceOf/0/NoLength SEQUENCE OF subtype or SET OF subtype
  1440. * SetOf/0/NoLength of zero length
  1441. *
  1442. * SequenceOf/1/NoLength SEQUENCE OF subtype or SET OF subtype
  1443. * SetOf/1/NoLength of fixed length <64K
  1444. *
  1445. * SequenceOf/1/Length SEQUENCE OF subtype or SET OF subtype
  1446. * SetOf/1/Length of var. length or length >= 64K or
  1447. * semiconstrained length
  1448. *
  1449. * Additional arguments:
  1450. *
  1451. * - Data == ePERSTIData_SequenceOf || dat == ePERSTIData_SetOf:
  1452. * -> SubIdentifier, the name of the subtype
  1453. * -> SubType, the subtype itself
  1454. * -> Rule, the encoding directive rules
  1455. */
  1456. void
  1457. ExaminePERType_SequenceSetOf(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1458. {
  1459. EndPoint_t lower, upper;
  1460. char idebuf[256];
  1461. /* calculate LConstraint, LLowerVal and LUpperVal */
  1462. if (per->Size.Type != eExtension_Unconstrained) {
  1463. lower.Flags = eEndPoint_Max;
  1464. upper.Flags = eEndPoint_Min;
  1465. GetMinMax(ass, per->Size.Root, &lower, &upper);
  1466. if (upper.Flags & eEndPoint_Min)
  1467. upper.Flags = eEndPoint_Max;
  1468. info->Root.LLowerVal = intx2uint32(&GetValue(ass, lower.Value)->
  1469. U.Integer.Value);
  1470. if (!(upper.Flags & eEndPoint_Max)) {
  1471. info->Root.LUpperVal = intx2uint32(&GetValue(ass, upper.Value)->
  1472. U.Integer.Value);
  1473. info->Root.LConstraint = ePERSTIConstraint_Constrained;
  1474. }
  1475. }
  1476. /* calculate NBits, Length */
  1477. switch (info->Root.LConstraint) {
  1478. case ePERSTIConstraint_Constrained:
  1479. if (info->Root.LUpperVal == 0) {
  1480. info->Root.NBits = 0;
  1481. } else {
  1482. if (info->Root.LLowerVal != info->Root.LUpperVal)
  1483. info->Root.Length = ePERSTILength_Length;
  1484. }
  1485. break;
  1486. case ePERSTIConstraint_Semiconstrained:
  1487. info->Root.Length = ePERSTILength_Length;
  1488. break;
  1489. }
  1490. /* set data type and Alignment */
  1491. info->Root.Data = (type->Type == eType_SequenceOf ?
  1492. ePERSTIData_SequenceOf : ePERSTIData_SetOf);
  1493. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  1494. /* set SubType, SubIdentifier */
  1495. info->Root.SubType = type->U.SS.Type;
  1496. info->Root.SubIdentifier = GetTypeName(ass, info->Root.SubType);
  1497. /* get extension type */
  1498. info->Type = per->Size.Type;
  1499. if (info->Type == eExtension_Unconstrained)
  1500. info->Type = eExtension_Unextended;
  1501. /* set extension informations */
  1502. info->Additional.Data = info->Root.Data;
  1503. info->Additional.NBits = 1;
  1504. info->Additional.SubType = info->Root.SubType;
  1505. info->Additional.SubIdentifier = info->Root.SubIdentifier;
  1506. /* examine subtype */
  1507. sprintf(idebuf, "%s_%s", info->Identifier,
  1508. type->Type == eType_SequenceOf ? "Sequence" : "Set");
  1509. ExaminePERType(ass, type->U.SS.Type, strdup(idebuf));
  1510. }
  1511. /*
  1512. * CHOICE:
  1513. *
  1514. * Data/NBits/Length used for encoding of the choice selector:
  1515. *
  1516. * Unsigned/0/NoLength constrained whole number of fixed
  1517. * value, stored in an
  1518. * uint{8,16,32}_t/intx_t
  1519. * (noctets == 1/2/4/0)
  1520. *
  1521. * Unsigned/n/NoLength constrained whole number of fixed
  1522. * length < 64K, stored in an
  1523. * uint{8,16,32}_t/intx_t
  1524. * (noctets == 1/2/4/0)
  1525. * encoded in n bits
  1526. *
  1527. * Unsigned/8/Length constrained whole number of var.
  1528. * length or length >= 64K or
  1529. * semiconstrained or unconstrained
  1530. * whole number, stored in an
  1531. * uint{8,16,32}_t/intx_t
  1532. * (noctets == 1/2/4/0)
  1533. * encoded in units of octets
  1534. *
  1535. * NormallySmall/1/NoLength normally small non-negative
  1536. * whole number, stored in an
  1537. * uint{8,16,32}_t
  1538. * (noctets == 1/2/4)
  1539. *
  1540. * Additional arguments:
  1541. *
  1542. * - Data == ePERSTIData_Integer || dat == ePERSTIData_Unsigned ||
  1543. * Data == ePERSTIData_Boolean
  1544. * -> NOctets, the size of the integer type
  1545. *
  1546. */
  1547. void
  1548. ExaminePERType_Choice(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1549. {
  1550. uint32_t nroot, rangelog2;
  1551. intx_t range;
  1552. Component_t *comp;
  1553. NamedType_t *namedType;
  1554. char idebuf[256];
  1555. if (type->Flags & eTypeFlags_ExtensionMarker) {
  1556. info->Type = type->U.Choice.Extensions ?
  1557. eExtension_Extended : eExtension_Extendable;
  1558. }
  1559. nroot = type->U.Choice.Alternatives;
  1560. info->NOctets = GetOctets(GetChoiceType(type));
  1561. info->Root.Constraint = ePERSTIConstraint_Constrained;
  1562. intx_setuint32(&info->Root.UpperVal, nroot - 1);
  1563. intx_setuint32(&range, nroot);
  1564. rangelog2 = intx_log2(&range);
  1565. if (nroot <= 1) {
  1566. info->Root.NBits = 0;
  1567. } else if (nroot < 256) {
  1568. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  1569. info->Root.NBits = rangelog2;
  1570. } else if (nroot == 256) {
  1571. info->Root.NBits = 8;
  1572. } else if (nroot < 65536) {
  1573. info->Root.NBits = 16;
  1574. } else {
  1575. MyAbort();
  1576. }
  1577. info->Root.Data = ePERSTIData_Unsigned;
  1578. info->Additional.Data = ePERSTIData_NormallySmall;
  1579. info->Additional.NBits = 1;
  1580. info->Additional.Alignment = ePERSTIAlignment_BitAligned;
  1581. info->Additional.Length = ePERSTILength_NoLength;
  1582. info->Additional.Constraint = ePERSTIConstraint_Semiconstrained;
  1583. intx_setuint32(&info->Additional.LowerVal, nroot);
  1584. /* examine types of alternatives */
  1585. for (comp = type->U.SSC.Components; comp; comp = comp->Next) {
  1586. switch (comp->Type) {
  1587. case eComponent_Normal:
  1588. namedType = comp->U.NOD.NamedType;
  1589. sprintf(idebuf, "%s_%s", info->Identifier, namedType->Identifier);
  1590. ExaminePERType(ass, namedType->Type, strdup(idebuf));
  1591. break;
  1592. }
  1593. }
  1594. }
  1595. /*
  1596. * Reference:
  1597. *
  1598. * Data/NBits/Length used for encoding:
  1599. *
  1600. * Reference/1/NoLength Reference to a structured subtype
  1601. *
  1602. * Additional arguments:
  1603. *
  1604. * - Data == ePERSTIData_Reference:
  1605. * -> SubIdentifier, the name of the subtype
  1606. * -> SubType, the subtype itself
  1607. */
  1608. void
  1609. ExaminePERType_Reference(AssignmentList_t ass, Type_t *type, PERConstraints_t *per, PERTypeInfo_t *info)
  1610. {
  1611. info->Root.Data = ePERSTIData_Reference;
  1612. info->Root.Alignment = ePERSTIAlignment_BitAligned;
  1613. info->Root.SubIdentifier = GetName(FindAssignment(ass, eAssignment_Type, type->U.Reference.Identifier, type->U.Reference.Module));
  1614. info->Root.SubType = GetAssignment(ass, FindAssignment(ass, eAssignment_Type, type->U.Reference.Identifier, type->U.Reference.Module))->U.Type.Type;
  1615. }