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.

3561 lines
125 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. #include "optcase.h"
  5. void GenPERFuncSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, TypeFunc_e et, char *encref);
  6. void GenPERStringTableSimpleType(AssignmentList_t ass, PERTypeInfo_t *info);
  7. void GenPEREncSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, char *encref);
  8. void GenPEREncGenericUnextended(
  9. AssignmentList_t ass,
  10. PERTypeInfo_t *info,
  11. PERSimpleTypeInfo_t *sinfo,
  12. char *valref,
  13. char *lenref,
  14. char *encref);
  15. void GenPERFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et);
  16. void GenPERFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et);
  17. void GenPERDecSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, char *encref);
  18. void GenPERDecGenericUnextended(
  19. AssignmentList_t ass,
  20. PERTypeInfo_t *info,
  21. PERSimpleTypeInfo_t *sinfo,
  22. char *valref,
  23. char *lenref,
  24. char *encref);
  25. int IsUnconstrainedInteger(PERSimpleTypeInfo_t *sinfo);
  26. extern int g_fDecZeroMemory;
  27. extern int g_nDbgModuleName;
  28. extern unsigned g_cPDUs;
  29. extern int g_fCaseBasedOptimizer;
  30. extern int g_fNoAssert;
  31. /* write header needed for PER encodings */
  32. void
  33. GenPERHeader()
  34. {
  35. // output("#include \"perfnlib.h\"\n");
  36. }
  37. /* set prototypes and function args of PER functions */
  38. void
  39. GetPERPrototype(Arguments_t *args)
  40. {
  41. args->enccast = "ASN1encoding_t, void *";
  42. args->encfunc = "ASN1encoding_t enc, %s *val";
  43. args->Pencfunc = "ASN1encoding_t enc, P%s *val";
  44. args->deccast = "ASN1decoding_t, void *";
  45. args->decfunc = "ASN1decoding_t dec, %s *val";
  46. args->Pdecfunc = "ASN1decoding_t dec, P%s *val";
  47. args->freecast = "void *";
  48. args->freefunc = "%s *val";
  49. args->Pfreefunc = "P%s *val";
  50. args->cmpcast = "void *, void *";
  51. args->cmpfunc = "%s *val1, %s *val2";
  52. args->Pcmpfunc = "P%s *val1, P%s *val2";
  53. }
  54. /* write initialization function needed for PER encodings */
  55. void
  56. GenPERInit(AssignmentList_t ass, char *module)
  57. {
  58. output("%s = ASN1_CreateModule(0x%x, ASN1_PER_RULE_ALIGNED, %s, %d, (const ASN1GenericFun_t *) encfntab, (const ASN1GenericFun_t *) decfntab, freefntab, sizetab, 0x%lx);\n",
  59. module,
  60. ASN1_THIS_VERSION,
  61. g_fNoAssert ? "ASN1FLAGS_NOASSERT" : "ASN1FLAGS_NONE",
  62. g_cPDUs,
  63. g_nDbgModuleName);
  64. }
  65. /* generate function body for a type */
  66. void GenPERFuncType(AssignmentList_t ass, char *module, Assignment_t *at, TypeFunc_e et)
  67. {
  68. Type_t *type;
  69. char *encref;
  70. char *valref;
  71. /* get some informations */
  72. type = at->U.Type.Type;
  73. switch (et) {
  74. case eStringTable:
  75. valref = encref = "";
  76. break;
  77. case eEncode:
  78. encref = "enc";
  79. valref = "val";
  80. break;
  81. case eDecode:
  82. encref = "dec";
  83. valref = "val";
  84. break;
  85. }
  86. /* function body */
  87. switch (type->Type) {
  88. case eType_Boolean:
  89. case eType_Integer:
  90. case eType_Enumerated:
  91. case eType_Real:
  92. case eType_BitString:
  93. case eType_OctetString:
  94. case eType_UTF8String:
  95. case eType_Null:
  96. case eType_EmbeddedPdv:
  97. case eType_External:
  98. case eType_ObjectIdentifier:
  99. case eType_BMPString:
  100. case eType_GeneralString:
  101. case eType_GraphicString:
  102. case eType_IA5String:
  103. case eType_ISO646String:
  104. case eType_NumericString:
  105. case eType_PrintableString:
  106. case eType_TeletexString:
  107. case eType_T61String:
  108. case eType_UniversalString:
  109. case eType_VideotexString:
  110. case eType_VisibleString:
  111. case eType_CharacterString:
  112. case eType_GeneralizedTime:
  113. case eType_UTCTime:
  114. case eType_ObjectDescriptor:
  115. case eType_RestrictedString:
  116. case eType_Open:
  117. case eType_Reference:
  118. GenPERFuncSimpleType(ass, &type->PERTypeInfo, Dereference(valref), et, encref);
  119. break;
  120. case eType_SequenceOf:
  121. case eType_SetOf:
  122. GenPERFuncSimpleType(ass, &type->PERTypeInfo, Dereference(valref), et, encref);
  123. break;
  124. case eType_Sequence:
  125. case eType_Set:
  126. case eType_InstanceOf:
  127. GenPERFuncSequenceSetType(ass, module, at, valref, encref, et);
  128. break;
  129. case eType_Choice:
  130. GenPERFuncChoiceType(ass, module, at, valref, encref, et);
  131. break;
  132. case eType_Selection:
  133. case eType_Undefined:
  134. MyAbort();
  135. /*NOTREACHED*/
  136. }
  137. }
  138. /* generate function body for components */
  139. void
  140. GenPERFuncComponents(AssignmentList_t ass, char *module, uint32_t optindex, ComponentList_t components, char *valref, char *encref, char *oref, TypeFunc_e et, int inextension, int inchoice)
  141. {
  142. Component_t *com;
  143. NamedType_t *namedType;
  144. char *ide;
  145. char valbuf[256];
  146. char typebuf[256];
  147. int conditional, skip;
  148. /* get a parented encoding_t/decoding_t for sequence/set */
  149. if (inextension && !inchoice) {
  150. switch (et) {
  151. case eStringTable:
  152. break;
  153. case eEncode:
  154. outputvar("ASN1encoding_t ee;\n");
  155. output("if (ASN1_CreateEncoder(%s->module, &ee, NULL, 0, %s) < 0)\n",
  156. encref, encref);
  157. output("return 0;\n");
  158. break;
  159. case eDecode:
  160. outputvar("ASN1decoding_t dd;\n");
  161. break;
  162. }
  163. }
  164. /* emit components of extension root */
  165. for (com = components; com; com = com->Next) {
  166. if (com->Type == eComponent_ExtensionMarker)
  167. break;
  168. /* get some information */
  169. namedType = com->U.NOD.NamedType;
  170. ide = Identifier2C(namedType->Identifier);
  171. /* skip unnecessary elements */
  172. skip = (namedType->Type->Flags & eTypeFlags_Null) && !inextension;
  173. /* check if optional/default component is present or choice is */
  174. /* selected */
  175. conditional = 0;
  176. switch (et) {
  177. case eStringTable:
  178. break;
  179. case eEncode:
  180. case eDecode:
  181. if (inchoice) {
  182. // lonchanc: we should not skip any case in Decode
  183. // because we cannot tell skipped cases from extension.
  184. // on the other hand, in Encode, we'd better not either.
  185. // when people put in customization in extension,
  186. // we cannot tell as well.
  187. if (skip)
  188. {
  189. output("case %d:\nbreak;\n", optindex);
  190. }
  191. else
  192. {
  193. output("case %d:\n", optindex);
  194. conditional = 1;
  195. }
  196. optindex++;
  197. } else {
  198. if (com->Type == eComponent_Optional ||
  199. com->Type == eComponent_Default ||
  200. inextension) {
  201. if (!skip) {
  202. output("if (%s[%u] & 0x%x) {\n", oref,
  203. optindex / 8, 0x80 >> (optindex & 7));
  204. conditional = 1;
  205. }
  206. optindex++;
  207. }
  208. }
  209. break;
  210. }
  211. /* get a parented encoding_t/decoding_t for choice */
  212. if (inextension && inchoice) {
  213. /* get a parented encoding_t/decoding_t */
  214. switch (et) {
  215. case eStringTable:
  216. break;
  217. case eEncode:
  218. outputvar("ASN1encoding_t ee;\n");
  219. output("if (ASN1_CreateEncoder(%s->module, &ee, NULL, 0, %s) < 0)\n",
  220. encref, encref);
  221. output("return 0;\n");
  222. break;
  223. case eDecode:
  224. outputvar("ASN1decoding_t dd;\n");
  225. break;
  226. }
  227. }
  228. /* dereference pointer if pointer directive used */
  229. if (inchoice) {
  230. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer)
  231. sprintf(valbuf, "*(%s)->u.%s", valref, ide);
  232. else
  233. sprintf(valbuf, "(%s)->u.%s", valref, ide);
  234. } else {
  235. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer)
  236. sprintf(valbuf, "*(%s)->%s", valref, ide);
  237. else
  238. sprintf(valbuf, "(%s)->%s", valref, ide);
  239. }
  240. /* allocate memory if decoding and pointer directive used */
  241. if (et == eDecode &&
  242. (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer) &&
  243. !(GetType(ass, namedType->Type)->Flags & eTypeFlags_Null)) {
  244. sprintf(typebuf, "%s *",
  245. GetTypeName(ass, namedType->Type));
  246. output("if (!(%s = (%s)ASN1DecAlloc(%s, sizeof(%s))))\n",
  247. Reference(valbuf), typebuf, encref, valbuf);
  248. output("return 0;\n");
  249. }
  250. /* handle subtype value */
  251. if (!skip) {
  252. if (!inextension) {
  253. GenPERFuncSimpleType(ass, &namedType->Type->PERTypeInfo,
  254. valbuf, et, encref);
  255. } else {
  256. switch (et) {
  257. case eStringTable:
  258. GenPERFuncSimpleType(ass, &namedType->Type->PERTypeInfo,
  259. valbuf, et, encref);
  260. break;
  261. case eEncode:
  262. GenPERFuncSimpleType(ass, &namedType->Type->PERTypeInfo,
  263. valbuf, et, "ee");
  264. // lonchanc: added the following API to replace the following
  265. // chunk of code.
  266. output("if (!ASN1PEREncFlushFragmentedToParent(ee))\n");
  267. // output("if (!ASN1PEREncFlush(ee))\n");
  268. // output("return 0;\n");
  269. // output("if (!ASN1PEREncFragmented(%s, ee->len, ee->buf, 8))\n",
  270. // encref);
  271. output("return 0;\n");
  272. break;
  273. case eDecode:
  274. outputvar("ASN1octet_t *db;\n");
  275. outputvar("ASN1uint32_t ds;\n");
  276. output("if (!ASN1PERDecFragmented(%s, &ds, &db, 8))\n",
  277. encref);
  278. output("return 0;\n");
  279. output("if (ASN1_CreateDecoderEx(%s->module, &dd, db, ds, %s, ASN1DECODE_AUTOFREEBUFFER) < 0)\n",
  280. encref, encref);
  281. output("return 0;\n");
  282. GenPERFuncSimpleType(ass, &namedType->Type->PERTypeInfo,
  283. valbuf, et, "dd");
  284. output("ASN1_CloseDecoder(dd);\n");
  285. // output("DecMemFree(%s, db);\n", encref);
  286. break;
  287. }
  288. }
  289. }
  290. /* drop the parented encoding_t/decoding_t for choice */
  291. if (inextension && inchoice) {
  292. if (et == eEncode) {
  293. output("ASN1_CloseEncoder2(ee);\n");
  294. }
  295. }
  296. /* end of check for presence of optional/default component */
  297. if (inchoice) {
  298. if (conditional)
  299. output("break;\n");
  300. } else {
  301. if (conditional)
  302. output("}\n");
  303. }
  304. }
  305. /* drop the parented encoding_t/decoding_t for sequence/set */
  306. if (inextension && !inchoice) {
  307. if (et == eEncode) {
  308. output("ASN1_CloseEncoder2(ee);\n");
  309. }
  310. }
  311. }
  312. /* generate function body for sequence/set type */
  313. void GenPERFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et)
  314. {
  315. uint32_t optionals, extensions;
  316. Component_t *components, *com;
  317. PERTypeInfo_t inf;
  318. Type_t *type;
  319. char valbuf[256];
  320. int conditional;
  321. char obuf[256];
  322. type = at->U.Type.Type;
  323. optionals = type->U.SSC.Optionals;
  324. extensions = type->U.SSC.Extensions;
  325. components = type->U.SSC.Components;
  326. inf.Identifier = NULL;
  327. inf.Flags = 0;
  328. inf.Rules = 0;
  329. inf.EnumerationValues = NULL;
  330. inf.NOctets = 0;
  331. inf.Type = eExtension_Unextended;
  332. inf.Root.TableIdentifier = NULL;
  333. inf.Root.Table = NULL;
  334. inf.Root.Data = ePERSTIData_Extension;
  335. inf.Root.SubType = NULL;
  336. inf.Root.SubIdentifier = NULL;
  337. inf.Root.NBits = 0;
  338. inf.Root.Constraint = ePERSTIConstraint_Unconstrained;
  339. intx_setuint32(&inf.Root.LowerVal, 0);
  340. intx_setuint32(&inf.Root.UpperVal, 0);
  341. inf.Root.Alignment = ePERSTIAlignment_BitAligned;
  342. inf.Root.Length = ePERSTILength_NoLength;
  343. inf.Root.LConstraint = ePERSTIConstraint_Unconstrained;
  344. inf.Root.LLowerVal = 0;
  345. inf.Root.LUpperVal = 0;
  346. inf.Root.LNBits = 0;
  347. inf.Root.LAlignment = ePERSTIAlignment_OctetAligned;
  348. /* set/clear missing bits in optional/default bit field */
  349. GenFuncSequenceSetOptionals(ass, valref, components,
  350. optionals, extensions, obuf, et);
  351. /* emit/get extension bit if needed */
  352. if (type->Flags & eTypeFlags_ExtensionMarker) {
  353. switch (et) {
  354. case eStringTable:
  355. break;
  356. case eEncode:
  357. if (type->Flags & eTypeFlags_ExtensionMarker) {
  358. if (!extensions) {
  359. if (g_fCaseBasedOptimizer)
  360. {
  361. output("if (!ASN1PEREncExtensionBitClear(%s))\n", encref);
  362. }
  363. else
  364. {
  365. output("if (!ASN1PEREncBitVal(%s, 1, 0))\n", encref);
  366. }
  367. output("return 0;\n");
  368. } else {
  369. outputvar("ASN1uint32_t y;\n");
  370. output("y = ASN1PEREncCheckExtensions(%d, %s + %d);\n",
  371. extensions, strcmp(obuf, "o") ? obuf : "(val)->o", (optionals + 7) / 8);
  372. output("if (!ASN1PEREncBitVal(%s, 1, y))\n",
  373. encref);
  374. output("return 0;\n");
  375. }
  376. }
  377. break;
  378. case eDecode:
  379. if (type->Flags & eTypeFlags_ExtensionMarker) {
  380. outputvar("ASN1uint32_t y;\n");
  381. if (g_fCaseBasedOptimizer)
  382. {
  383. output("if (!ASN1PERDecExtensionBit(%s, &y))\n", encref);
  384. }
  385. else
  386. {
  387. output("if (!ASN1PERDecBit(%s, &y))\n", encref);
  388. }
  389. output("return 0;\n");
  390. }
  391. break;
  392. }
  393. }
  394. /* emit/get bit field of optionals */
  395. if (optionals) {
  396. inf.Root.NBits = optionals;
  397. inf.Root.Length = ePERSTILength_NoLength;
  398. if (optionals >= 0x10000)
  399. MyAbort();
  400. GenPERFuncSimpleType(ass, &inf, obuf, et, encref);
  401. }
  402. /* emit components of extension root */
  403. GenPERFuncComponents(ass, module, 0, components,
  404. valref, encref, obuf, et, 0, 0);
  405. /* handle extensions */
  406. if (type->Flags & eTypeFlags_ExtensionMarker) {
  407. conditional = 0;
  408. if (!extensions) {
  409. /* skip unknown extension bit field */
  410. if (et == eDecode) {
  411. output("if (y) {\n");
  412. inf.Root.NBits = 1;
  413. inf.Root.Length = ePERSTILength_SmallLength;
  414. inf.Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  415. inf.Root.LLowerVal = 1;
  416. if (g_fCaseBasedOptimizer)
  417. {
  418. output("if (!ASN1PERDecSkipNormallySmallExtensionFragmented(%s))\n",
  419. encref);
  420. output("return 0;\n");
  421. output("}\n");
  422. goto FinalTouch;
  423. }
  424. else
  425. {
  426. GenPERFuncSimpleType(ass, &inf, NULL, et, encref);
  427. conditional = 1;
  428. }
  429. }
  430. } else {
  431. /* check if extension bit is set */
  432. switch (et) {
  433. case eStringTable:
  434. break;
  435. case eEncode:
  436. output("if (y) {\n");
  437. conditional = 1;
  438. break;
  439. case eDecode:
  440. output("if (!y) {\n");
  441. output("ZeroMemory(%s + %d, %d);\n", obuf,
  442. (optionals + 7) / 8, (extensions + 7) / 8);
  443. output("} else {\n");
  444. conditional = 1;
  445. break;
  446. }
  447. /* emit/get bit field of extensions */
  448. inf.Root.NBits = extensions;
  449. inf.Root.Length = ePERSTILength_SmallLength;
  450. inf.Root.LConstraint = ePERSTIConstraint_Semiconstrained;
  451. inf.Root.LLowerVal = 1;
  452. sprintf(valbuf, "%s + %d", obuf, (optionals + 7) / 8);
  453. GenPERFuncSimpleType(ass, &inf, valbuf, et, encref);
  454. /* get start of extensions */
  455. for (com = components; com; com = com->Next) {
  456. if (com->Type == eComponent_ExtensionMarker) {
  457. com = com->Next;
  458. break;
  459. }
  460. }
  461. /* emit components of extension */
  462. GenPERFuncComponents(ass, module, (optionals + 7) & ~7, com,
  463. valref, encref, obuf, et, 1, 0);
  464. }
  465. /* skip unknown extensions */
  466. if (et == eDecode) {
  467. outputvar("ASN1uint32_t i;\n");
  468. outputvar("ASN1uint32_t e;\n");
  469. output("for (i = 0; i < e; i++) {\n");
  470. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  471. encref);
  472. output("return 0;\n");
  473. output("}\n");
  474. }
  475. /* end of extension handling */
  476. if (conditional)
  477. output("}\n");
  478. }
  479. FinalTouch:
  480. /* some user-friendly assignments for non-present optional/default */
  481. /* components */
  482. GenFuncSequenceSetDefaults(ass, valref, components, obuf, et);
  483. }
  484. /* generate function body for choice type */
  485. void GenPERFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref, char *encref, TypeFunc_e et)
  486. {
  487. Type_t *type;
  488. char valbuf[256];
  489. uint32_t alternatives;
  490. Component_t *components, *com;
  491. int fOptimizeCase = 0;
  492. /* get some informations */
  493. type = at->U.Type.Type;
  494. alternatives = type->U.SSC.Alternatives;
  495. components = type->U.SSC.Components;
  496. /* encode choice selector */
  497. switch (et) {
  498. case eStringTable:
  499. sprintf(valbuf, "(%s)->choice", valref);
  500. break;
  501. case eEncode:
  502. sprintf(valbuf, "(%s)->choice", valref);
  503. if (g_fCaseBasedOptimizer)
  504. {
  505. switch (type->PERTypeInfo.Type)
  506. {
  507. case eExtension_Unconstrained:
  508. break;
  509. case eExtension_Unextended: // no extension mark at all
  510. output("if (!ASN1PEREncSimpleChoice(%s, %s, %u))\n",
  511. encref, valbuf, type->PERTypeInfo.Root.NBits);
  512. output("return 0;\n");
  513. fOptimizeCase = 1;
  514. break;
  515. case eExtension_Extendable: // extension mark exists, but no choice appears after the mark
  516. output("if (!ASN1PEREncSimpleChoiceEx(%s, %s, %u))\n",
  517. encref, valbuf, type->PERTypeInfo.Root.NBits);
  518. output("return 0;\n");
  519. fOptimizeCase = 1;
  520. break;
  521. case eExtension_Extended: // extension mark exists, but some choices appear after the mark
  522. output("if (!ASN1PEREncComplexChoice(%s, %s, %u, %u))\n",
  523. encref, valbuf, type->PERTypeInfo.Root.NBits, intx2uint32(&(type->PERTypeInfo.Additional.LowerVal)));
  524. output("return 0;\n");
  525. fOptimizeCase = 1;
  526. break;
  527. }
  528. }
  529. if (ASN1_CHOICE_BASE)
  530. {
  531. sprintf(valbuf, "(%s)->choice - %d", valref, ASN1_CHOICE_BASE);
  532. }
  533. break;
  534. case eDecode:
  535. sprintf(valbuf, "(%s)->choice", valref);
  536. if (g_fCaseBasedOptimizer)
  537. {
  538. switch (type->PERTypeInfo.Type)
  539. {
  540. case eExtension_Unconstrained:
  541. break;
  542. case eExtension_Unextended: // no extension mark at all
  543. output("if (!ASN1PERDecSimpleChoice(%s, %s, %u))\n",
  544. encref, Reference(valbuf), type->PERTypeInfo.Root.NBits);
  545. output("return 0;\n");
  546. fOptimizeCase = 1;
  547. break;
  548. case eExtension_Extendable: // extension mark exists, but no choice appears after the mark
  549. output("if (!ASN1PERDecSimpleChoiceEx(%s, %s, %u))\n",
  550. encref, Reference(valbuf), type->PERTypeInfo.Root.NBits);
  551. output("return 0;\n");
  552. fOptimizeCase = 1;
  553. break;
  554. case eExtension_Extended: // extension mark exists, but some choices appear after the mark
  555. output("if (!ASN1PERDecComplexChoice(%s, %s, %u, %u))\n",
  556. encref, Reference(valbuf), type->PERTypeInfo.Root.NBits, intx2uint32(&(type->PERTypeInfo.Additional.LowerVal)));
  557. output("return 0;\n");
  558. fOptimizeCase = 1;
  559. break;
  560. }
  561. }
  562. break;
  563. }
  564. if (! fOptimizeCase)
  565. {
  566. if (eDecode == et)
  567. {
  568. output("%s = %d;\n", valbuf, ASN1_CHOICE_INVALID);
  569. }
  570. GenPERFuncSimpleType(ass, &type->PERTypeInfo, valbuf, et, encref);
  571. // lonchanc: in case of decoding, we need to increment choice value
  572. // by the amount of ASN1_CHOICE_BASE
  573. if (et == eDecode && ASN1_CHOICE_BASE)
  574. {
  575. output("(%s)->choice += %d;\n", valref, ASN1_CHOICE_BASE);
  576. }
  577. }
  578. /* finished if choice only contains NULL alternatives or if choice */
  579. /* contains no data to free */
  580. if (type->Flags & eTypeFlags_NullChoice)
  581. return;
  582. /* create switch statement */
  583. switch (et) {
  584. case eStringTable:
  585. break;
  586. case eDecode:
  587. case eEncode:
  588. output("switch ((%s)->choice) {\n", valref);
  589. break;
  590. }
  591. /* generate components of extension root */
  592. GenPERFuncComponents(ass, module, ASN1_CHOICE_BASE, components,
  593. valref, encref, NULL, et, 0, 1);
  594. /* get start of extensions */
  595. for (com = components; com; com = com->Next) {
  596. if (com->Type == eComponent_ExtensionMarker) {
  597. com = com->Next;
  598. break;
  599. }
  600. }
  601. /* generate components of extension */
  602. GenPERFuncComponents(ass, module, ASN1_CHOICE_BASE + alternatives, com,
  603. valref, encref, NULL, et, 1, 1);
  604. /* skip unknown extensions */
  605. if (et == eDecode && (type->Flags & eTypeFlags_ExtensionMarker)) {
  606. output("case %d:\n\t/* extension case */\n", ASN1_CHOICE_INVALID + 1);
  607. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n", encref);
  608. output("return 0;\n");
  609. output("break;\n");
  610. }
  611. // debug purpose
  612. switch (et)
  613. {
  614. case eEncode:
  615. output("default:\n\t/* impossible */\n");
  616. output("ASN1EncSetError(%s, ASN1_ERR_CHOICE);\n", encref);
  617. output("return 0;\n");
  618. break;
  619. case eDecode:
  620. output("default:\n\t/* impossible */\n");
  621. output("ASN1DecSetError(%s, ASN1_ERR_CHOICE);\n", encref);
  622. output("return 0;\n");
  623. break;
  624. }
  625. /* end of switch statement */
  626. switch (et) {
  627. case eStringTable:
  628. break;
  629. case eEncode:
  630. case eDecode:
  631. output("}\n");
  632. break;
  633. }
  634. }
  635. /* generate function body for simple type */
  636. void
  637. GenPERFuncSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, TypeFunc_e et, char *encref)
  638. {
  639. switch (et) {
  640. case eStringTable:
  641. GenPERStringTableSimpleType(ass, info);
  642. break;
  643. case eEncode:
  644. GenPEREncSimpleType(ass, info, valref, encref);
  645. break;
  646. case eDecode:
  647. GenPERDecSimpleType(ass, info, valref, encref);
  648. break;
  649. }
  650. }
  651. /* generate string table for a simple type */
  652. void
  653. GenPERStringTableSimpleType(AssignmentList_t ass, PERTypeInfo_t *info)
  654. {
  655. ValueConstraint_t *pc;
  656. uint32_t i, n, lo, up;
  657. switch (info->Root.Data) {
  658. case ePERSTIData_String:
  659. case ePERSTIData_TableString:
  660. case ePERSTIData_ZeroString:
  661. case ePERSTIData_ZeroTableString:
  662. if (info->Root.TableIdentifier) {
  663. if (!strcmp(info->Root.TableIdentifier, "ASN1NumericStringTable"))
  664. break;
  665. output("static ASN1stringtableentry_t %sEntries[] = {\n",
  666. info->Root.TableIdentifier);
  667. i = n = 0;
  668. for (pc = info->Root.Table; pc; pc = pc->Next) {
  669. lo = GetValue(ass, pc->Lower.Value)->
  670. U.RestrictedString.Value.value[0];
  671. up = GetValue(ass, pc->Upper.Value)->
  672. U.RestrictedString.Value.value[0];
  673. output("{ %u, %u, %u }, ", lo, up, n);
  674. n += (up - lo) + 1;
  675. i++;
  676. if ((i & 3) == 3 || !pc->Next)
  677. output("\n");
  678. }
  679. output("};\n");
  680. output("\n");
  681. output("static ASN1stringtable_t %s = {\n",
  682. info->Root.TableIdentifier);
  683. output("%d, %sEntries\n", i, info->Root.TableIdentifier);
  684. output("};\n");
  685. output("\n");
  686. }
  687. break;
  688. case ePERSTIData_SetOf:
  689. case ePERSTIData_SequenceOf:
  690. GenPERFuncSimpleType(ass, &info->Root.SubType->PERTypeInfo, "", eStringTable, "");
  691. break;
  692. }
  693. }
  694. /* generate encoding statements for a simple value */
  695. void
  696. GenPEREncSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, char *encref)
  697. {
  698. uint32_t i;
  699. char lbbuf[256], ubbuf[256];
  700. char *lenref;
  701. char lenbuf[256], valbuf[256];
  702. char *p;
  703. PERTypeInfo_t inf;
  704. inf = *info;
  705. /* examine type for special handling */
  706. switch (inf.Root.Data) {
  707. case ePERSTIData_BitString:
  708. case ePERSTIData_RZBBitString:
  709. if (inf.Root.cbFixedSizeBitString)
  710. {
  711. sprintf(lenbuf, "%u", inf.Root.LUpperVal);
  712. sprintf(valbuf, "&(%s)", valref);
  713. lenref = lenbuf;
  714. valref = valbuf;
  715. break;
  716. }
  717. // lonchanc: intentionally fall through
  718. case ePERSTIData_OctetString:
  719. if (g_fCaseBasedOptimizer)
  720. {
  721. if (inf.Root.Data == ePERSTIData_OctetString && inf.Type == eExtension_Unextended)
  722. {
  723. switch (inf.Root.Length)
  724. {
  725. case ePERSTILength_NoLength:
  726. if (inf.Root.LConstraint == ePERSTIConstraint_Constrained &&
  727. inf.Root.LLowerVal == inf.Root.LUpperVal &&
  728. inf.Root.LUpperVal < 64 * 1024)
  729. {
  730. // fixed size constraint, eg. OCTET STRING (SIZE (8))
  731. if (inf.pPrivateDirectives->fLenPtr)
  732. {
  733. output("if (!ASN1PEREncOctetString_FixedSizeEx(%s, %s, %u))\n",
  734. encref, Reference(valref), inf.Root.LLowerVal);
  735. }
  736. else
  737. {
  738. output("if (!ASN1PEREncOctetString_FixedSize(%s, (ASN1octetstring2_t *) %s, %u))\n",
  739. encref, Reference(valref), inf.Root.LLowerVal);
  740. }
  741. output("return 0;\n");
  742. return;
  743. }
  744. break;
  745. case ePERSTILength_Length:
  746. break;
  747. case ePERSTILength_BitLength:
  748. if (inf.Root.LConstraint == ePERSTIConstraint_Constrained &&
  749. inf.Root.LLowerVal < inf.Root.LUpperVal &&
  750. inf.Root.LUpperVal < 64 * 1024)
  751. {
  752. // variable size constraint, eg. OCTET STRING (SIZE (4..16))
  753. if (inf.pPrivateDirectives->fLenPtr)
  754. {
  755. output("if (!ASN1PEREncOctetString_VarSizeEx(%s, %s, %u, %u, %u))\n",
  756. encref, Reference(valref), inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  757. }
  758. else
  759. {
  760. output("if (!ASN1PEREncOctetString_VarSize(%s, (ASN1octetstring2_t *) %s, %u, %u, %u))\n",
  761. encref, Reference(valref), inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  762. }
  763. output("return 0;\n");
  764. return;
  765. }
  766. break;
  767. case ePERSTILength_SmallLength:
  768. break;
  769. case ePERSTILength_InfiniteLength: // no size constraint, eg OCTET STRING
  770. /* encode octet string in fragmented format */
  771. output("if (!ASN1PEREncOctetString_NoSize(%s, %s))\n",
  772. encref, Reference(valref));
  773. output("return 0;\n");
  774. return;
  775. } // switch
  776. } // if
  777. }
  778. /* length and value of bit string, octet string and string */
  779. sprintf(lenbuf, "(%s).length", valref);
  780. sprintf(valbuf, "(%s).value", valref);
  781. lenref = lenbuf;
  782. valref = valbuf;
  783. break;
  784. case ePERSTIData_UTF8String:
  785. /* length and value of bit string, octet string and string */
  786. sprintf(lenbuf, "(%s).length", valref);
  787. sprintf(valbuf, "(%s).value", valref);
  788. lenref = lenbuf;
  789. valref = valbuf;
  790. break;
  791. case ePERSTIData_String:
  792. case ePERSTIData_TableString:
  793. /* length and value of bit string, octet string and string */
  794. sprintf(lenbuf, "(%s).length", valref);
  795. sprintf(valbuf, "(%s).value", valref);
  796. lenref = lenbuf;
  797. valref = valbuf;
  798. break;
  799. case ePERSTIData_SequenceOf:
  800. case ePERSTIData_SetOf:
  801. if (inf.Rules & eTypeRules_PointerArrayMask)
  802. {
  803. /* length and value of sequence of/set of value with */
  804. /* length-pointer representation */
  805. if (inf.Rules & eTypeRules_PointerToElement)
  806. {
  807. sprintf(lenbuf, "(%s)->count", valref);
  808. sprintf(valbuf, "(%s)->%s", valref, GetPrivateValueName(inf.pPrivateDirectives, "value"));
  809. }
  810. else
  811. {
  812. sprintf(lenbuf, "(%s)->count", Reference(valref));
  813. sprintf(valbuf, "(%s)->%s", Reference(valref), GetPrivateValueName(inf.pPrivateDirectives, "value"));
  814. }
  815. lenref = lenbuf;
  816. valref = valbuf;
  817. }
  818. else
  819. if (inf.Rules & eTypeRules_LinkedListMask)
  820. {
  821. /* use a loop for sequence of/set of value with */
  822. /* list representation */
  823. if (g_fCaseBasedOptimizer)
  824. {
  825. if (PerOptCase_IsTargetSeqOf(&inf))
  826. {
  827. // generate the iterator
  828. char szElmFn[128];
  829. char szElmFnDecl[256];
  830. sprintf(szElmFn, "ASN1Enc_%s_ElmFn", inf.Identifier);
  831. sprintf(szElmFnDecl, "int ASN1CALL %s(ASN1encoding_t %s, P%s val)",
  832. szElmFn, encref, inf.Identifier);
  833. setoutfile(g_finc);
  834. output("extern %s;\n", szElmFnDecl);
  835. setoutfile(g_fout);
  836. if ((inf.Root.LLowerVal == 0 && inf.Root.LUpperVal == 0) ||
  837. (inf.Root.LUpperVal >= 64 * 1024)
  838. )
  839. {
  840. output("return ASN1PEREncSeqOf_NoSize(%s, (ASN1iterator_t **) %s, (ASN1iterator_encfn) %s);\n",
  841. encref, Reference(valref), szElmFn);
  842. }
  843. else
  844. {
  845. if (inf.Root.LLowerVal == inf.Root.LUpperVal)
  846. MyAbort();
  847. output("return ASN1PEREncSeqOf_VarSize(%s, (ASN1iterator_t **) %s, (ASN1iterator_encfn) %s, %u, %u, %u);\n",
  848. encref, Reference(valref), szElmFn,
  849. inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  850. }
  851. output("}\n\n"); // end of iterator body
  852. // generate the element function
  853. output("static %s\n", szElmFnDecl);
  854. output("{\n");
  855. sprintf(valbuf, "val->%s", GetPrivateValueName(inf.pPrivateDirectives, "value"));
  856. GenPERFuncSimpleType(ass, &inf.Root.SubType->PERTypeInfo, valbuf,
  857. eEncode, encref);
  858. // end of element body
  859. return;
  860. }
  861. }
  862. outputvar("ASN1uint32_t t;\n");
  863. outputvar("P%s f;\n", inf.Identifier);
  864. output("for (t = 0, f = %s; f; f = f->next)\n", valref);
  865. output("t++;\n");
  866. lenref = "t";
  867. } else {
  868. MyAbort();
  869. }
  870. break;
  871. case ePERSTIData_ZeroString:
  872. case ePERSTIData_ZeroTableString:
  873. /* length of a zero-terminated string value */
  874. outputvar("ASN1uint32_t t;\n");
  875. output("t = lstrlenA(%s);\n", valref);
  876. lenref = "t";
  877. break;
  878. case ePERSTIData_Boolean:
  879. /* value of a boolean value */
  880. if (g_fCaseBasedOptimizer)
  881. {
  882. if (PerOptCase_IsBoolean(&inf.Root))
  883. {
  884. lenref = NULL;
  885. break;
  886. }
  887. }
  888. sprintf(valbuf, "(%s) ? 1 : 0", valref);
  889. valref = valbuf;
  890. lenref = NULL;
  891. inf.Root.Data = ePERSTIData_Unsigned;
  892. break;
  893. default:
  894. /* other values have no additional length */
  895. lenref = NULL;
  896. break;
  897. }
  898. /* map enumeration values */
  899. if (inf.EnumerationValues) {
  900. outputvar("ASN1uint32_t u;\n");
  901. output("switch (%s) {\n", valref);
  902. for (i = 0; inf.EnumerationValues[i]; i++) {
  903. output("case %u:\n", intx2uint32(inf.EnumerationValues[i]));
  904. output("u = %u;\n", i);
  905. output("break;\n");
  906. }
  907. output("}\n");
  908. valref = "u";
  909. inf.NOctets = 4;
  910. }
  911. /* check for extended values */
  912. if (inf.Type == eExtension_Extended) {
  913. switch (inf.Root.Data) {
  914. case ePERSTIData_Integer:
  915. case ePERSTIData_Unsigned:
  916. switch (inf.Root.Constraint) {
  917. case ePERSTIConstraint_Unconstrained:
  918. inf.Type = eExtension_Extendable;
  919. break;
  920. case ePERSTIConstraint_Semiconstrained:
  921. if (inf.NOctets == 0) {
  922. sprintf(lbbuf, "%s_lb", inf.Identifier);
  923. outputvarintx(lbbuf, &inf.Root.LowerVal);
  924. output("if (ASN1intx_cmp(%s, &%s) >= 0) {\n",
  925. Reference(valref), lbbuf);
  926. } else if (inf.Root.Data == ePERSTIData_Integer) {
  927. output("if (%s >= %d) {\n",
  928. valref, intx2int32(&inf.Root.LowerVal));
  929. } else {
  930. if (intx2uint32(&inf.Root.LowerVal) > 0) {
  931. output("if (%s >= %u) {\n",
  932. valref, intx2uint32(&inf.Root.LowerVal));
  933. } else {
  934. inf.Type = eExtension_Extendable;
  935. }
  936. }
  937. break;
  938. case ePERSTIConstraint_Upperconstrained:
  939. if (inf.NOctets == 0) {
  940. sprintf(ubbuf, "%s_ub", inf.Identifier);
  941. outputvarintx(ubbuf, &inf.Root.UpperVal);
  942. output("if (ASN1intx_cmp(%s, &%s) <= 0) {\n",
  943. Reference(valref), ubbuf);
  944. } else if (inf.Root.Data == ePERSTIData_Integer) {
  945. output("if (%s <= %d) {\n",
  946. valref, intx2int32(&inf.Root.UpperVal));
  947. } else {
  948. output("if (%s <= %u) {\n",
  949. valref, intx2uint32(&inf.Root.UpperVal));
  950. }
  951. break;
  952. case ePERSTIConstraint_Constrained:
  953. if (inf.NOctets == 0) {
  954. sprintf(lbbuf, "%s_lb", inf.Identifier);
  955. sprintf(ubbuf, "%s_ub", inf.Identifier);
  956. outputvarintx(lbbuf, &inf.Root.LowerVal);
  957. outputvarintx(ubbuf, &inf.Root.UpperVal);
  958. output("if (ASN1intx_cmp(%s, &%s) >= 0 && ASN1intx_cmp(%s, &%s) <= 0) {\n",
  959. Reference(valref), lbbuf, Reference(valref), ubbuf);
  960. } else if (inf.Root.Data == ePERSTIData_Integer) {
  961. output("if (%s >= %d && %s <= %d) {\n",
  962. valref, intx2int32(&inf.Root.LowerVal),
  963. valref, intx2int32(&inf.Root.UpperVal));
  964. } else {
  965. if (intx2uint32(&inf.Root.LowerVal) > 0) {
  966. output("if (%s >= %u && %s <= %u) {\n",
  967. valref, intx2uint32(&inf.Root.LowerVal),
  968. valref, intx2uint32(&inf.Root.UpperVal));
  969. } else {
  970. output("if (%s <= %u) {\n",
  971. valref, intx2uint32(&inf.Root.UpperVal));
  972. }
  973. }
  974. break;
  975. }
  976. break;
  977. case ePERSTIData_SequenceOf:
  978. case ePERSTIData_SetOf:
  979. case ePERSTIData_OctetString:
  980. case ePERSTIData_UTF8String:
  981. case ePERSTIData_BitString:
  982. case ePERSTIData_RZBBitString:
  983. case ePERSTIData_Extension:
  984. switch (inf.Root.LConstraint) {
  985. case ePERSTIConstraint_Semiconstrained:
  986. if (inf.Root.LLowerVal != 0) {
  987. output("if (%s >= %u) {\n",
  988. lenref, inf.Root.LLowerVal);
  989. } else {
  990. inf.Type = eExtension_Extendable;
  991. }
  992. break;
  993. case ePERSTIConstraint_Constrained:
  994. if (inf.Root.LLowerVal != 0) {
  995. output("if (%s >= %u && %s <= %u) {\n",
  996. lenref, inf.Root.LLowerVal, lenref, inf.Root.LUpperVal);
  997. } else {
  998. output("if (%s <= %u) {\n",
  999. lenref, inf.Root.LUpperVal);
  1000. }
  1001. break;
  1002. }
  1003. break;
  1004. case ePERSTIData_String:
  1005. case ePERSTIData_TableString:
  1006. case ePERSTIData_ZeroString:
  1007. case ePERSTIData_ZeroTableString:
  1008. inf.Type = eExtension_Extendable;
  1009. switch (inf.Root.LConstraint) {
  1010. case ePERSTIConstraint_Semiconstrained:
  1011. if (inf.Root.LLowerVal != 0) {
  1012. output("if (%s >= %u",
  1013. lenref, inf.Root.LLowerVal);
  1014. inf.Type = eExtension_Extended;
  1015. }
  1016. break;
  1017. case ePERSTIConstraint_Constrained:
  1018. output("if (%s >= %u && %s <= %u",
  1019. lenref, inf.Root.LLowerVal, lenref, inf.Root.LUpperVal);
  1020. inf.Type = eExtension_Extended;
  1021. break;
  1022. }
  1023. if (inf.Root.TableIdentifier) {
  1024. if (inf.Type == eExtension_Extended)
  1025. output(" && ");
  1026. else
  1027. output("if (");
  1028. if (inf.NOctets == 1) {
  1029. p = "Char";
  1030. } else if (inf.NOctets == 2) {
  1031. p = "Char16";
  1032. } else if (inf.NOctets == 4) {
  1033. p = "Char32";
  1034. } else
  1035. MyAbort();
  1036. output("ASN1PEREncCheckTable%sString(%s, %s, %s)",
  1037. p, lenref, valref, Reference(inf.Root.TableIdentifier));
  1038. inf.Type = eExtension_Extended;
  1039. }
  1040. if (inf.Type == eExtension_Extended)
  1041. output(") {\n");
  1042. break;
  1043. }
  1044. }
  1045. /* encode unset extension bit */
  1046. if (inf.Type > eExtension_Unextended) {
  1047. if (g_fCaseBasedOptimizer)
  1048. {
  1049. output("if (!ASN1PEREncExtensionBitClear(%s))\n", encref);
  1050. }
  1051. else
  1052. {
  1053. output("if (!ASN1PEREncBitVal(%s, 1, 0))\n", encref);
  1054. }
  1055. output("return 0;\n");
  1056. }
  1057. /* encode unextended value (of extension root) */
  1058. GenPEREncGenericUnextended(ass, &inf, &inf.Root, valref, lenref, encref);
  1059. /* type is extended? */
  1060. if (inf.Type == eExtension_Extended) {
  1061. output("} else {\n");
  1062. /* encode set extension bit */
  1063. if (g_fCaseBasedOptimizer)
  1064. {
  1065. output("if (!ASN1PEREncExtensionBitSet(%s))\n", encref);
  1066. }
  1067. else
  1068. {
  1069. output("if (!ASN1PEREncBitVal(%s, 1, 1))\n", encref);
  1070. }
  1071. output("return 0;\n");
  1072. /* encode extended value (of extension addition) */
  1073. GenPEREncGenericUnextended(ass, &inf, &inf.Additional, valref, lenref, encref);
  1074. output("}\n");
  1075. }
  1076. }
  1077. /* generate encoding statements for a simple value (after some special */
  1078. /* handling has been done, esp. the evaluation of the extension) */
  1079. void GenPEREncGenericUnextended(AssignmentList_t ass, PERTypeInfo_t *info, PERSimpleTypeInfo_t *sinfo, char *valref, char *lenref, char *encref)
  1080. {
  1081. char valbuf[256];
  1082. char *lvref, lvbuf[256];
  1083. char lbbuf[256];
  1084. char *p;
  1085. /* check for empty field */
  1086. if (sinfo->NBits == 0)
  1087. return;
  1088. /* initial calculations for value encoding: */
  1089. /* substract lower bound of constraint/semiconstraint value */
  1090. /* for Integer and NormallySmall */
  1091. switch (sinfo->Constraint) {
  1092. case ePERSTIConstraint_Semiconstrained:
  1093. case ePERSTIConstraint_Constrained:
  1094. switch (sinfo->Data) {
  1095. case ePERSTIData_Integer:
  1096. case ePERSTIData_Unsigned:
  1097. case ePERSTIData_NormallySmall:
  1098. if (!info->NOctets) {
  1099. /* calculate value-lowerbound for intx_t values */
  1100. if (intx_cmp(&sinfo->LowerVal, &intx_0) != 0) {
  1101. sprintf(lbbuf, "%s_lb", info->Identifier);
  1102. outputvar("ASN1intx_t newval;\n");
  1103. outputvarintx(lbbuf, &sinfo->LowerVal);
  1104. output("ASN1intx_sub(&newval, %s, &%s);\n",
  1105. Reference(valref), lbbuf);
  1106. valref = "newval";
  1107. }
  1108. } else if (sinfo->Data == ePERSTIData_Integer) {
  1109. /* calculate value-lowerbound for intx_t values */
  1110. if (intx_cmp(&sinfo->LowerVal, &intx_0)) {
  1111. char szLowB[24];
  1112. sprintf(&szLowB[0], "%d", intx2int32(&sinfo->LowerVal));
  1113. if (szLowB[0] == '-')
  1114. sprintf(valbuf, "%s + %s", valref, &szLowB[1]); // minus minus become plus
  1115. else
  1116. sprintf(valbuf, "%s - %s", valref, &szLowB[0]);
  1117. valref = valbuf;
  1118. }
  1119. } else {
  1120. /* calculate value-lowerbound for integer values */
  1121. if (intx_cmp(&sinfo->LowerVal, &intx_0)) {
  1122. sprintf(valbuf, "%s - %u", valref, intx2uint32(&sinfo->LowerVal));
  1123. valref = valbuf;
  1124. }
  1125. }
  1126. /* semiconstraint/constraint values will be encoded as unsigned */
  1127. if (sinfo->Data == ePERSTIData_Integer)
  1128. sinfo->Data = ePERSTIData_Unsigned;
  1129. break;
  1130. }
  1131. break;
  1132. }
  1133. /* general rules */
  1134. if (sinfo->LAlignment == ePERSTIAlignment_OctetAligned &&
  1135. sinfo->Length == ePERSTILength_BitLength &&
  1136. !(sinfo->LNBits & 7))
  1137. sinfo->Alignment = ePERSTIAlignment_BitAligned;
  1138. /* octet alignment will be given by length */
  1139. if (sinfo->Length == ePERSTILength_InfiniteLength &&
  1140. (sinfo->Data == ePERSTIData_Integer && info->NOctets == 0 ||
  1141. sinfo->Data == ePERSTIData_Unsigned && info->NOctets == 0 ||
  1142. sinfo->Data == ePERSTIData_BitString ||
  1143. sinfo->Data == ePERSTIData_RZBBitString ||
  1144. sinfo->Data == ePERSTIData_Extension ||
  1145. sinfo->Data == ePERSTIData_OctetString ||
  1146. sinfo->Data == ePERSTIData_UTF8String ||
  1147. sinfo->Data == ePERSTIData_SequenceOf ||
  1148. sinfo->Data == ePERSTIData_SetOf ||
  1149. sinfo->Data == ePERSTIData_String ||
  1150. sinfo->Data == ePERSTIData_TableString ||
  1151. sinfo->Data == ePERSTIData_ZeroString ||
  1152. sinfo->Data == ePERSTIData_ZeroTableString) ||
  1153. sinfo->Data == ePERSTIData_ObjectIdentifier ||
  1154. sinfo->Data == ePERSTIData_Real ||
  1155. sinfo->Data == ePERSTIData_GeneralizedTime ||
  1156. sinfo->Data == ePERSTIData_UTCTime ||
  1157. sinfo->Data == ePERSTIData_External ||
  1158. sinfo->Data == ePERSTIData_EmbeddedPdv ||
  1159. sinfo->Data == ePERSTIData_MultibyteString ||
  1160. sinfo->Data == ePERSTIData_UnrestrictedString ||
  1161. sinfo->Data == ePERSTIData_Open)
  1162. sinfo->LAlignment = sinfo->Alignment = ePERSTIAlignment_BitAligned;
  1163. /* alignment will be done by encoding fn */
  1164. if (sinfo->Length == ePERSTILength_NoLength ||
  1165. sinfo->Length == ePERSTILength_SmallLength)
  1166. sinfo->LAlignment = ePERSTIAlignment_BitAligned;
  1167. /* no alignment of no/small length */
  1168. /* special initial calculations */
  1169. switch (sinfo->Data) {
  1170. case ePERSTIData_RZBBitString:
  1171. /* remove trailing zero-bits */
  1172. outputvar("ASN1uint32_t r;\n");
  1173. output("r = %s;\n", lenref);
  1174. output("ASN1PEREncRemoveZeroBits(&r, %s, %u);\n",
  1175. valref, sinfo->LLowerVal);
  1176. if (sinfo->LLowerVal) {
  1177. outputvar("ASN1uint32_t s;\n");
  1178. output("s = r < %u ? %u : r;\n", sinfo->LLowerVal, sinfo->LLowerVal);
  1179. lenref = "s";
  1180. } else {
  1181. lenref = "r";
  1182. }
  1183. break;
  1184. }
  1185. if (g_fCaseBasedOptimizer)
  1186. {
  1187. // lonchanc: special handling for macro operations
  1188. if (PerOptCase_IsSignedInteger(sinfo))
  1189. {
  1190. output("if (!ASN1PEREncInteger(%s, %s))\n", encref, valref);
  1191. output("return 0;\n");
  1192. return;
  1193. }
  1194. if (PerOptCase_IsUnsignedInteger(sinfo))
  1195. {
  1196. output("if (!ASN1PEREncUnsignedInteger(%s, %s))\n", encref, valref);
  1197. output("return 0;\n");
  1198. return;
  1199. }
  1200. if (PerOptCase_IsUnsignedShort(sinfo))
  1201. {
  1202. output("if (!ASN1PEREncUnsignedShort(%s, %s))\n", encref, valref);
  1203. output("return 0;\n");
  1204. return;
  1205. }
  1206. if (PerOptCase_IsBoolean(sinfo))
  1207. {
  1208. output("if (!ASN1PEREncBoolean(%s, %s))\n", encref, valref);
  1209. output("return 0;\n");
  1210. return;
  1211. }
  1212. }
  1213. /* initial calculations for length: */
  1214. /* get length of integer numbers if length req. */
  1215. switch (sinfo->Length) {
  1216. case ePERSTILength_BitLength:
  1217. case ePERSTILength_InfiniteLength:
  1218. switch (sinfo->Constraint) {
  1219. case ePERSTIConstraint_Unconstrained:
  1220. case ePERSTIConstraint_Upperconstrained:
  1221. switch (sinfo->Data) {
  1222. case ePERSTIData_Integer:
  1223. case ePERSTIData_Unsigned:
  1224. if (info->NOctets != 0) {
  1225. outputvar("ASN1uint32_t l;\n");
  1226. if (sinfo->Data == ePERSTIData_Integer)
  1227. output("l = ASN1int32_octets(%s);\n", valref);
  1228. else
  1229. output("l = ASN1uint32_octets(%s);\n", valref);
  1230. lenref = "l";
  1231. } else {
  1232. if (sinfo->Length != ePERSTILength_InfiniteLength) {
  1233. outputvar("ASN1uint32_t l;\n");
  1234. output("l = ASN1intx_octets(%s);\n",
  1235. Reference(valref));
  1236. lenref = "l";
  1237. }
  1238. }
  1239. break;
  1240. }
  1241. break;
  1242. case ePERSTIConstraint_Semiconstrained:
  1243. case ePERSTIConstraint_Constrained:
  1244. switch (sinfo->Data) {
  1245. case ePERSTIData_Integer:
  1246. case ePERSTIData_Unsigned:
  1247. if (info->NOctets != 0) {
  1248. outputvar("ASN1uint32_t l;\n");
  1249. output("l = ASN1uint32_uoctets(%s);\n", valref);
  1250. lenref = "l";
  1251. } else {
  1252. if (sinfo->Length != ePERSTILength_InfiniteLength) {
  1253. outputvar("ASN1uint32_t l;\n");
  1254. output("l = ASN1intx_uoctets(%s);\n",
  1255. Reference(valref));
  1256. lenref = "l";
  1257. }
  1258. }
  1259. break;
  1260. }
  1261. break;
  1262. }
  1263. break;
  1264. }
  1265. /* initial settings for length enconding: */
  1266. /* substract lower bound of length from length */
  1267. if (sinfo->LLowerVal != 0 && lenref) {
  1268. sprintf(lvbuf, "%s - %u", lenref, sinfo->LLowerVal);
  1269. lvref = lvbuf;
  1270. } else {
  1271. lvref = lenref;
  1272. }
  1273. /* length encoding */
  1274. if (sinfo->LAlignment == ePERSTIAlignment_OctetAligned) {
  1275. output("ASN1PEREncAlignment(%s);\n", encref);
  1276. }
  1277. switch (sinfo->Length) {
  1278. case ePERSTILength_NoLength:
  1279. /* not length used */
  1280. break;
  1281. case ePERSTILength_BitLength:
  1282. /* length will be encoded in a bit field */
  1283. output("if (!ASN1PEREncBitVal(%s, %u, %s))\n",
  1284. encref, sinfo->LNBits, lvref);
  1285. output("return 0;\n");
  1286. break;
  1287. case ePERSTILength_InfiniteLength:
  1288. /* infinite length case: encode length only for integer values, */
  1289. /* other length encodings will be the encoding function */
  1290. switch (sinfo->Data) {
  1291. case ePERSTIData_Integer:
  1292. case ePERSTIData_Unsigned:
  1293. if (info->NOctets != 0) {
  1294. output("if (!ASN1PEREncBitVal(%s, 8, %s))\n",
  1295. encref, lvref);
  1296. output("return 0;\n");
  1297. }
  1298. break;
  1299. }
  1300. break;
  1301. }
  1302. /* special initial calculations */
  1303. switch (sinfo->Data) {
  1304. case ePERSTIData_RZBBitString:
  1305. /* real length of the bit string */
  1306. lenref = "r";
  1307. break;
  1308. }
  1309. /* value encoding */
  1310. switch (sinfo->Length) {
  1311. case ePERSTILength_NoLength:
  1312. /* encode alignment of the value */
  1313. if (sinfo->Alignment == ePERSTIAlignment_OctetAligned) {
  1314. output("ASN1PEREncAlignment(%s);\n", encref);
  1315. }
  1316. switch (sinfo->Data) {
  1317. case ePERSTIData_Integer:
  1318. case ePERSTIData_Unsigned:
  1319. /* encode the value as bit field */
  1320. if (info->NOctets != 0) {
  1321. output("if (!ASN1PEREncBitVal(%s, %u, %s))\n",
  1322. encref, sinfo->NBits, valref);
  1323. output("return 0;\n");
  1324. } else {
  1325. output("if (!ASN1PEREncBitIntx(%s, %u, %s))\n",
  1326. encref, sinfo->NBits, Reference(valref));
  1327. output("return 0;\n");
  1328. }
  1329. break;
  1330. case ePERSTIData_NormallySmall:
  1331. /* encode the value as normally small number */
  1332. output("if (!ASN1PEREncNormallySmall(%s, %s))\n",
  1333. encref, valref);
  1334. output("return 0;\n");
  1335. break;
  1336. case ePERSTIData_BitString:
  1337. case ePERSTIData_RZBBitString:
  1338. /* encode bit string in a bit field */
  1339. output("if (!ASN1PEREncBits(%s, %s, %s))\n",
  1340. encref, lenref, valref);
  1341. output("return 0;\n");
  1342. break;
  1343. case ePERSTIData_OctetString:
  1344. /* encode octet string in a bit field */
  1345. output("if (!ASN1PEREncBits(%s, %s * 8, %s))\n",
  1346. encref, lenref, valref);
  1347. output("return 0;\n");
  1348. break;
  1349. case ePERSTIData_UTF8String:
  1350. /* encode octet string in a bit field */
  1351. output("if (!ASN1PEREncUTF8String(%s, %s, %s))\n",
  1352. encref, lenref, valref);
  1353. output("return 0;\n");
  1354. break;
  1355. case ePERSTIData_Extension:
  1356. /* encode extension bits in a bit field */
  1357. output("if (!ASN1PEREncBits(%s, %u, %s))\n",
  1358. encref, sinfo->NBits, valref);
  1359. output("return 0;\n");
  1360. break;
  1361. case ePERSTIData_SetOf:
  1362. /* same as BitLength encoding */
  1363. goto SetOfEncoding;
  1364. case ePERSTIData_SequenceOf:
  1365. /* same as BitLength encoding */
  1366. goto SequenceOfEncoding;
  1367. case ePERSTIData_String:
  1368. case ePERSTIData_ZeroString:
  1369. /* same as BitLength encoding */
  1370. goto StringEncoding;
  1371. case ePERSTIData_TableString:
  1372. case ePERSTIData_ZeroTableString:
  1373. /* same as BitLength encoding */
  1374. goto TableStringEncoding;
  1375. case ePERSTIData_Reference:
  1376. /* call encoding function of referenced type */
  1377. output("if (!ASN1Enc_%s(%s, %s))\n",
  1378. Identifier2C(sinfo->SubIdentifier),
  1379. encref, Reference(valref));
  1380. output("return 0;\n");
  1381. break;
  1382. case ePERSTIData_Real:
  1383. /* encode real value */
  1384. if (info->NOctets)
  1385. output("if (!ASN1PEREncDouble(%s, %s))\n",
  1386. encref, valref);
  1387. else
  1388. output("if (!ASN1PEREncReal(%s, %s))\n",
  1389. encref, Reference(valref));
  1390. output("return 0;\n");
  1391. break;
  1392. case ePERSTIData_GeneralizedTime:
  1393. /* encode generalized time value */
  1394. output("if (!ASN1PEREncGeneralizedTime(%s, %s, %d))\n",
  1395. encref, Reference(valref), sinfo->NBits);
  1396. output("return 0;\n");
  1397. break;
  1398. case ePERSTIData_UTCTime:
  1399. /* encode utc time value */
  1400. output("if (!ASN1PEREncUTCTime(%s, %s, %d))\n",
  1401. encref, Reference(valref), sinfo->NBits);
  1402. output("return 0;\n");
  1403. break;
  1404. }
  1405. break;
  1406. case ePERSTILength_BitLength:
  1407. /* encode alignment of the value */
  1408. if (sinfo->Alignment == ePERSTIAlignment_OctetAligned) {
  1409. output("ASN1PEREncAlignment(%s);\n", encref);
  1410. }
  1411. switch (sinfo->Data) {
  1412. case ePERSTIData_Integer:
  1413. case ePERSTIData_Unsigned:
  1414. /* encode the value as bit field */
  1415. if (info->NOctets != 0) {
  1416. output("if (!ASN1PEREncBitVal(%s, %s * 8, %s))\n",
  1417. encref, lenref, valref);
  1418. output("return 0;\n");
  1419. } else {
  1420. output("if (!ASN1PEREncBitIntx(%s, %s * 8, %s))\n",
  1421. encref, lenref, Reference(valref));
  1422. output("return 0;\n");
  1423. }
  1424. break;
  1425. case ePERSTIData_BitString:
  1426. case ePERSTIData_RZBBitString:
  1427. /* encode the value as bit field */
  1428. output("if (!ASN1PEREncBits(%s, %s, %s))\n",
  1429. encref, lenref, valref);
  1430. output("return 0;\n");
  1431. break;
  1432. case ePERSTIData_OctetString:
  1433. /* encode the value as bit field */
  1434. output("if (!ASN1PEREncBits(%s, %s * 8, %s))\n",
  1435. encref, lenref, valref);
  1436. output("return 0;\n");
  1437. break;
  1438. case ePERSTIData_UTF8String:
  1439. /* encode the value as bit field */
  1440. output("if (!ASN1PEREncUTF8String(%s, %s, %s))\n",
  1441. encref, lenref, valref);
  1442. output("return 0;\n");
  1443. break;
  1444. case ePERSTIData_SetOf:
  1445. SetOfEncoding:
  1446. /* skip null set of */
  1447. if (sinfo->SubType->Flags & eTypeFlags_Null)
  1448. break;
  1449. /* canonical PER? */
  1450. if (g_eSubEncodingRule == eSubEncoding_Canonical) {
  1451. /* encode the elements one by one and sort them */
  1452. outputvar("ASN1uint32_t i;\n");
  1453. outputvar("ASN1encoding_t e, *p;\n");
  1454. if (info->Rules &
  1455. (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList))
  1456. MyAbort(); /*XXX*/
  1457. output("if (%s) {\n", lenref);
  1458. output("e = p = (ASN1encoding_t)malloc(%s * sizeof(ASN1encoding_t));\n",
  1459. lenref);
  1460. output("ZeroMemory(b, %s * sizeof(ASN1encoding_t));\n", lenref);
  1461. output("for (i = 0; i < %s; i++, p++) {\n", lenref);
  1462. sprintf(valbuf, "(%s)[i]", valref);
  1463. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf, eEncode, encref);
  1464. output("}\n");
  1465. output("qsort(e, %s, sizeof(ASN1encoding_t), ASN1PEREncCmpEncodings);\n",
  1466. lenref);
  1467. output("}\n");
  1468. /* then dump them */
  1469. output("for (p = e, i = 0; i < %s; i++, p++) {\n", lenref);
  1470. output("if (!ASN1PEREncBits(%s, (p->pos - p->buf) * 8 + p->bit, p->buf))\n",
  1471. encref);
  1472. output("return 0;\n");
  1473. output("}\n");
  1474. break;
  1475. }
  1476. /* again in non-canonical PER: */
  1477. /*FALLTHROUGH*/
  1478. case ePERSTIData_SequenceOf:
  1479. SequenceOfEncoding:
  1480. /* skip null sequence of */
  1481. if (sinfo->SubType->Flags & eTypeFlags_Null)
  1482. break;
  1483. if (info->Rules & eTypeRules_PointerArrayMask)
  1484. {
  1485. /* loop over all elements */
  1486. outputvar("ASN1uint32_t i;\n");
  1487. output("for (i = 0; i < %s; i++) {\n", lenref);
  1488. sprintf(valbuf, "(%s)[i]", valref);
  1489. }
  1490. else
  1491. if (info->Rules & eTypeRules_LinkedListMask)
  1492. {
  1493. /* iterate over all elements */
  1494. outputvar("P%s f;\n", info->Identifier);
  1495. output("for (f = %s; f; f = f->next) {\n", valref);
  1496. sprintf(valbuf, "f->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  1497. }
  1498. /* encode the element */
  1499. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf,
  1500. eEncode, encref);
  1501. /* loop end */
  1502. output("}\n");
  1503. break;
  1504. case ePERSTIData_String:
  1505. case ePERSTIData_ZeroString:
  1506. StringEncoding:
  1507. /* encode string value */
  1508. if (info->NOctets == 1) {
  1509. p = "Char";
  1510. } else if (info->NOctets == 2) {
  1511. p = "Char16";
  1512. } else if (info->NOctets == 4) {
  1513. p = "Char32";
  1514. } else
  1515. MyAbort();
  1516. output("if (!ASN1PEREnc%sString(%s, %s, %s, %u))\n",
  1517. p, encref, lenref, valref, sinfo->NBits);
  1518. output("return 0;\n");
  1519. break;
  1520. case ePERSTIData_TableString:
  1521. case ePERSTIData_ZeroTableString:
  1522. TableStringEncoding:
  1523. /* encode table string value */
  1524. if (info->NOctets == 1) {
  1525. p = "Char";
  1526. } else if (info->NOctets == 2) {
  1527. p = "Char16";
  1528. } else if (info->NOctets == 4) {
  1529. p = "Char32";
  1530. } else
  1531. MyAbort();
  1532. output("if (!ASN1PEREncTable%sString(%s, %s, %s, %u, %s))\n",
  1533. p, encref, lenref, valref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  1534. output("return 0;\n");
  1535. break;
  1536. }
  1537. break;
  1538. case ePERSTILength_InfiniteLength:
  1539. /* infinite length case */
  1540. switch (sinfo->Data) {
  1541. case ePERSTIData_Integer:
  1542. case ePERSTIData_Unsigned:
  1543. /* encode an integer in fragmented format */
  1544. if (info->NOctets != 0) {
  1545. output("if (!ASN1PEREncBitVal(%s, %s * 8, %s))\n",
  1546. encref, lenref, valref);
  1547. output("return 0;\n");
  1548. } else {
  1549. if (sinfo->Data == ePERSTIData_Integer) {
  1550. output("if (!ASN1PEREncFragmentedIntx(%s, %s))\n",
  1551. encref, Reference(valref));
  1552. output("return 0;\n");
  1553. } else {
  1554. output("if (!ASN1PEREncFragmentedUIntx(%s, %s))\n",
  1555. encref, Reference(valref));
  1556. output("return 0;\n");
  1557. }
  1558. }
  1559. break;
  1560. case ePERSTIData_BitString:
  1561. case ePERSTIData_RZBBitString:
  1562. /* encode bit string in fragmented format */
  1563. output("if (!ASN1PEREncFragmented(%s, %s, %s, 1))\n",
  1564. encref, lenref, valref);
  1565. output("return 0;\n");
  1566. break;
  1567. case ePERSTIData_OctetString:
  1568. /* encode octet string in fragmented format */
  1569. output("if (!ASN1PEREncFragmented(%s, %s, %s, 8))\n",
  1570. encref, lenref, valref);
  1571. output("return 0;\n");
  1572. break;
  1573. case ePERSTIData_UTF8String:
  1574. /* encode octet string in fragmented format */
  1575. output("if (!ASN1PEREncUTF8String(%s, %s, %s))\n",
  1576. encref, lenref, valref);
  1577. output("return 0;\n");
  1578. break;
  1579. case ePERSTIData_Extension:
  1580. /* encode extension bits in fragmented format */
  1581. output("if (!ASN1PEREncFragmented(%s, %u, %s, 1))\n",
  1582. encref, sinfo->NBits, valref);
  1583. output("return 0;\n");
  1584. break;
  1585. case ePERSTIData_SetOf:
  1586. /* skip null set of */
  1587. if (sinfo->SubType->Flags & eTypeFlags_Null)
  1588. break;
  1589. /* canonical PER? */
  1590. if (g_eSubEncodingRule == eSubEncoding_Canonical) {
  1591. /* encode the elements one by one and sort them */
  1592. outputvar("ASN1uint32_t i;\n");
  1593. outputvar("ASN1uint32_t j, n = 0x4000;\n");
  1594. outputvar("ASN1encoding_t e, *p;\n");
  1595. if (info->Rules &
  1596. (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList))
  1597. MyAbort(); /*XXX*/
  1598. output("if (%s) {\n", lenref);
  1599. output("e = p = (ASN1encoding_t)malloc(%s * sizeof(ASN1encoding_t));\n",
  1600. lenref);
  1601. output("ZeroMemory(b, %s * sizeof(ASN1encoding_t));\n", lenref);
  1602. output("for (i = 0; i < %s; i++, p++) {\n", lenref);
  1603. sprintf(valbuf, "(%s)[i]", valref);
  1604. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf, eEncode, encref);
  1605. output("}\n");
  1606. output("qsort(e, %s, sizeof(ASN1encoding_t), ASN1PEREncCmpEncodings);\n",
  1607. lenref);
  1608. output("}\n");
  1609. /* then dump them */
  1610. output("for (p = e, i = 0; i < %s; i += n) {\n", lenref);
  1611. output("if (!ASN1PEREncFragmentedLength(&n, %s, %s - i))\n",
  1612. encref, lenref);
  1613. output("return 0;\n");
  1614. output("for (j = 0; j < n; p++, j++) {\n");
  1615. output("if (!ASN1PEREncBits(%s, (p->pos - p->buf) * 8 + p->bit, p->buf))\n",
  1616. encref);
  1617. output("return 0;\n");
  1618. output("}\n");
  1619. output("}\n");
  1620. output("}\n");
  1621. output("if (n >= 0x4000) {\n");
  1622. output("if (!ASN1PEREncFragmentedLength(&n, %s, 0))\n",
  1623. encref);
  1624. output("return 0;\n");
  1625. output("}\n");
  1626. break;
  1627. }
  1628. /* again in non-canonical PER: */
  1629. /*FALLTHROUGH*/
  1630. case ePERSTIData_SequenceOf:
  1631. /* skip null sequence of */
  1632. if (sinfo->SubType->Flags & eTypeFlags_Null)
  1633. break;
  1634. outputvar("ASN1uint32_t i;\n");
  1635. outputvar("ASN1uint32_t j, n = 0x4000;\n");
  1636. if (info->Rules &
  1637. (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList)) {
  1638. /* additional iterator needed */
  1639. outputvar("P%s f;\n", info->Identifier);
  1640. output("f = %s;\n", valref);
  1641. }
  1642. /* encode all elements */
  1643. output("for (i = 0; i < %s;) {\n", lenref);
  1644. /* encode fragmented length */
  1645. output("if (!ASN1PEREncFragmentedLength(&n, %s, %s - i))\n",
  1646. encref, lenref);
  1647. output("return 0;\n");
  1648. /* encode elements of the fragment */
  1649. output("for (j = 0; j < n; i++, j++) {\n");
  1650. if (info->Rules & eTypeRules_PointerArrayMask)
  1651. {
  1652. sprintf(valbuf, "(%s)[i]", valref);
  1653. }
  1654. else if (info->Rules & eTypeRules_LinkedListMask)
  1655. {
  1656. sprintf(valbuf, "f->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  1657. }
  1658. else
  1659. {
  1660. MyAbort();
  1661. }
  1662. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf,
  1663. eEncode, encref);
  1664. /* advance the iterator */
  1665. if (info->Rules & eTypeRules_LinkedListMask)
  1666. {
  1667. output("f = f->next;\n");
  1668. }
  1669. /* end of inner loop */
  1670. output("}\n");
  1671. /* end of outer loop */
  1672. output("}\n");
  1673. /* add an zero-sized fragment if needed */
  1674. output("if (n >= 0x4000) {\n");
  1675. output("if (!ASN1PEREncFragmentedLength(&n, %s, 0))\n",
  1676. encref);
  1677. output("return 0;\n");
  1678. output("}\n");
  1679. break;
  1680. case ePERSTIData_ObjectIdentifier:
  1681. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  1682. {
  1683. /* encode object identifier value */
  1684. output("if (!ASN1PEREncObjectIdentifier2(%s, %s))\n",
  1685. encref, Reference(valref));
  1686. }
  1687. else
  1688. {
  1689. /* encode object identifier value */
  1690. output("if (!ASN1PEREncObjectIdentifier(%s, %s))\n",
  1691. encref, Reference(valref));
  1692. }
  1693. output("return 0;\n");
  1694. break;
  1695. case ePERSTIData_External:
  1696. /* encode external value */
  1697. output("if (!ASN1PEREncExternal(%s, %s))\n",
  1698. encref, Reference(valref));
  1699. output("return 0;\n");
  1700. break;
  1701. case ePERSTIData_EmbeddedPdv:
  1702. /* encode embedded pdv value */
  1703. if (sinfo->Identification) {
  1704. output("if (!ASN1PEREncEmbeddedPdvOpt(%s, %s))\n",
  1705. encref, Reference(valref));
  1706. } else {
  1707. output("if (!ASN1PEREncEmbeddedPdv(%s, %s))\n",
  1708. encref, Reference(valref));
  1709. }
  1710. output("return 0;\n");
  1711. break;
  1712. case ePERSTIData_MultibyteString:
  1713. /* encode multibyte string value */
  1714. output("if (!ASN1PEREncMultibyteString(%s, %s))\n",
  1715. encref, valref);
  1716. output("return 0;\n");
  1717. break;
  1718. case ePERSTIData_UnrestrictedString:
  1719. /* encode character string value */
  1720. if (sinfo->Identification) {
  1721. output("if (!ASN1PEREncCharacterStringOpt(%s, %s))\n",
  1722. encref, Reference(valref));
  1723. } else {
  1724. output("if (!ASN1PEREncCharacterString(%s, %s))\n",
  1725. encref, Reference(valref));
  1726. }
  1727. output("return 0;\n");
  1728. break;
  1729. case ePERSTIData_String:
  1730. case ePERSTIData_ZeroString:
  1731. /* encode string value */
  1732. if (info->NOctets == 1) {
  1733. p = "Char";
  1734. } else if (info->NOctets == 2) {
  1735. p = "Char16";
  1736. } else if (info->NOctets == 4) {
  1737. p = "Char32";
  1738. } else
  1739. MyAbort();
  1740. output("if (!ASN1PEREncFragmented%sString(%s, %s, %s, %u))\n",
  1741. p, encref, lenref, valref, sinfo->NBits);
  1742. output("return 0;\n");
  1743. break;
  1744. case ePERSTIData_TableString:
  1745. case ePERSTIData_ZeroTableString:
  1746. /* encode table string value */
  1747. if (info->NOctets == 1) {
  1748. p = "Char";
  1749. } else if (info->NOctets == 2) {
  1750. p = "Char16";
  1751. } else if (info->NOctets == 4) {
  1752. p = "Char32";
  1753. } else
  1754. MyAbort();
  1755. output("if (!ASN1PEREncFragmentedTable%sString(%s, %s, %s, %u, %s))\n",
  1756. p, encref, lenref, valref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  1757. output("return 0;\n");
  1758. break;
  1759. case ePERSTIData_Open:
  1760. /* encode open type value */
  1761. output("if (!ASN1PEREncOpenType(%s, %s))\n",
  1762. encref, Reference(valref));
  1763. output("return 0;\n");
  1764. break;
  1765. }
  1766. break;
  1767. case ePERSTILength_SmallLength:
  1768. /* small length */
  1769. switch (sinfo->Data) {
  1770. case ePERSTIData_Extension:
  1771. /* encode extension bits with normally small length */
  1772. output("if (!ASN1PEREncNormallySmallBits(%s, %u, %s))\n",
  1773. encref, sinfo->NBits, valref);
  1774. output("return 0;\n");
  1775. break;
  1776. }
  1777. }
  1778. switch (sinfo->Data) {
  1779. case ePERSTIData_RZBBitString:
  1780. /* encode additional zero bits for remove zero bits bit string */
  1781. /* of short length */
  1782. if (sinfo->LLowerVal) {
  1783. output("if (%s < %u) {\n", lenref, sinfo->LLowerVal);
  1784. output("if (!ASN1PEREncZero(%s, %u - %s))\n",
  1785. encref, sinfo->LLowerVal, lenref);
  1786. output("return 0;\n");
  1787. output("}\n");
  1788. }
  1789. }
  1790. /* free calculated intx_t value */
  1791. switch (sinfo->Constraint) {
  1792. case ePERSTIConstraint_Semiconstrained:
  1793. case ePERSTIConstraint_Constrained:
  1794. switch (sinfo->Data) {
  1795. case ePERSTIData_Integer:
  1796. case ePERSTIData_Unsigned:
  1797. case ePERSTIData_NormallySmall:
  1798. if (!info->NOctets) {
  1799. if (intx_cmp(&sinfo->LowerVal, &intx_0) != 0) {
  1800. output("ASN1intx_free(&newval);\n");
  1801. }
  1802. }
  1803. break;
  1804. }
  1805. break;
  1806. }
  1807. }
  1808. /* generate decoding statements for a simple value */
  1809. void
  1810. GenPERDecSimpleType(AssignmentList_t ass, PERTypeInfo_t *info, char *valref, char *encref)
  1811. {
  1812. uint32_t i;
  1813. char *oldvalref;
  1814. char valbuf[256], lenbuf[256];
  1815. char *lenref;
  1816. PERTypeInfo_t inf;
  1817. inf = *info;
  1818. /* examine type for special handling */
  1819. switch (inf.Root.Data) {
  1820. case ePERSTIData_BitString:
  1821. case ePERSTIData_RZBBitString:
  1822. if (inf.Root.cbFixedSizeBitString)
  1823. {
  1824. sprintf(lenbuf, "%u", inf.Root.LUpperVal);
  1825. sprintf(valbuf, "%s", valref);
  1826. lenref = lenbuf;
  1827. valref = valbuf;
  1828. break;
  1829. }
  1830. // lonchanc: intentionally fall through
  1831. case ePERSTIData_OctetString:
  1832. if (g_fCaseBasedOptimizer)
  1833. {
  1834. if (inf.Root.Data == ePERSTIData_OctetString && inf.Type == eExtension_Unextended)
  1835. {
  1836. switch (inf.Root.Length)
  1837. {
  1838. case ePERSTILength_NoLength:
  1839. if (inf.Root.LConstraint == ePERSTIConstraint_Constrained &&
  1840. inf.Root.LLowerVal == inf.Root.LUpperVal &&
  1841. inf.Root.LUpperVal < 64 * 1024)
  1842. {
  1843. // fixed size constraint, eg. OCTET STRING (SIZE (8))
  1844. if (inf.pPrivateDirectives->fLenPtr)
  1845. {
  1846. output("if (!ASN1PERDecOctetString_FixedSizeEx(%s, %s, %u))\n",
  1847. encref, Reference(valref), inf.Root.LLowerVal);
  1848. }
  1849. else
  1850. {
  1851. output("if (!ASN1PERDecOctetString_FixedSize(%s, (ASN1octetstring2_t *) %s, %u))\n",
  1852. encref, Reference(valref), inf.Root.LLowerVal);
  1853. }
  1854. output("return 0;\n");
  1855. return;
  1856. }
  1857. break;
  1858. case ePERSTILength_Length:
  1859. break;
  1860. case ePERSTILength_BitLength:
  1861. if (inf.Root.LConstraint == ePERSTIConstraint_Constrained &&
  1862. inf.Root.LLowerVal < inf.Root.LUpperVal &&
  1863. inf.Root.LUpperVal < 64 * 1024)
  1864. {
  1865. // variable size constraint, eg. OCTET STRING (SIZE (4..16))
  1866. if (inf.pPrivateDirectives->fLenPtr)
  1867. {
  1868. output("if (!ASN1PERDecOctetString_VarSizeEx(%s, %s, %u, %u, %u))\n",
  1869. encref, Reference(valref), inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  1870. }
  1871. else
  1872. {
  1873. output("if (!ASN1PERDecOctetString_VarSize(%s, (ASN1octetstring2_t *) %s, %u, %u, %u))\n",
  1874. encref, Reference(valref), inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  1875. }
  1876. output("return 0;\n");
  1877. return;
  1878. }
  1879. break;
  1880. case ePERSTILength_SmallLength:
  1881. break;
  1882. case ePERSTILength_InfiniteLength: // no size constraint
  1883. /* get octet string as fragmented */
  1884. if (valref)
  1885. {
  1886. output("if (!ASN1PERDecOctetString_NoSize(%s, %s))\n",
  1887. encref, Reference(valref));
  1888. output("return 0;\n");
  1889. return;
  1890. }
  1891. break;
  1892. } // switch
  1893. } // if
  1894. }
  1895. /* length and value of bit string/octet string/string value */
  1896. sprintf(lenbuf, "(%s).length", valref);
  1897. sprintf(valbuf, "(%s).value", valref);
  1898. lenref = lenbuf;
  1899. valref = valbuf;
  1900. break;
  1901. case ePERSTIData_UTF8String:
  1902. /* length and value of bit string/octet string/string value */
  1903. sprintf(lenbuf, "(%s).length", valref);
  1904. sprintf(valbuf, "(%s).value", valref);
  1905. lenref = lenbuf;
  1906. valref = valbuf;
  1907. break;
  1908. case ePERSTIData_String:
  1909. case ePERSTIData_TableString:
  1910. /* length and value of bit string/octet string/string value */
  1911. sprintf(lenbuf, "(%s).length", valref);
  1912. sprintf(valbuf, "(%s).value", valref);
  1913. lenref = lenbuf;
  1914. valref = valbuf;
  1915. break;
  1916. case ePERSTIData_SequenceOf:
  1917. case ePERSTIData_SetOf:
  1918. if (inf.Rules & eTypeRules_PointerArrayMask)
  1919. {
  1920. /* length and value of sequence of/set of value with */
  1921. /* length-pointer representation */
  1922. if (inf.Rules & eTypeRules_PointerToElement)
  1923. {
  1924. sprintf(lenbuf, "(%s)->count", valref);
  1925. sprintf(valbuf, "(%s)->%s", valref, GetPrivateValueName(inf.pPrivateDirectives, "value"));
  1926. }
  1927. else
  1928. {
  1929. sprintf(lenbuf, "(%s)->count", Reference(valref));
  1930. sprintf(valbuf, "(%s)->%s", Reference(valref), GetPrivateValueName(inf.pPrivateDirectives, "value"));
  1931. }
  1932. lenref = lenbuf;
  1933. valref = valbuf;
  1934. }
  1935. else
  1936. if (inf.Rules & eTypeRules_LinkedListMask)
  1937. {
  1938. if (g_fCaseBasedOptimizer)
  1939. {
  1940. if (PerOptCase_IsTargetSeqOf(&inf))
  1941. {
  1942. // generate the iterator
  1943. char szElmFn[128];
  1944. char szElmFnDecl[256];
  1945. sprintf(szElmFn, "ASN1Dec_%s_ElmFn", inf.Identifier);
  1946. sprintf(szElmFnDecl, "int ASN1CALL %s(ASN1decoding_t %s, P%s val)",
  1947. szElmFn, encref, inf.Identifier);
  1948. setoutfile(g_finc);
  1949. output("extern %s;\n", szElmFnDecl);
  1950. setoutfile(g_fout);
  1951. if ((inf.Root.LLowerVal == 0 && inf.Root.LUpperVal == 0) ||
  1952. (inf.Root.LUpperVal >= 64 * 1024)
  1953. )
  1954. {
  1955. output("return ASN1PERDecSeqOf_NoSize(%s, (ASN1iterator_t **) %s, (ASN1iterator_decfn) %s, sizeof(*%s));\n",
  1956. encref, Reference(valref), szElmFn, valref);
  1957. }
  1958. else
  1959. {
  1960. if (inf.Root.LLowerVal == inf.Root.LUpperVal)
  1961. MyAbort();
  1962. output("return ASN1PERDecSeqOf_VarSize(%s, (ASN1iterator_t **) %s, (ASN1iterator_decfn) %s, sizeof(*%s), %u, %u, %u);\n",
  1963. encref, Reference(valref), szElmFn, valref,
  1964. inf.Root.LLowerVal, inf.Root.LUpperVal, inf.Root.LNBits);
  1965. }
  1966. output("}\n\n"); // end of iterator body
  1967. // generate the element function
  1968. output("static %s\n", szElmFnDecl);
  1969. output("{\n");
  1970. sprintf(valbuf, "val->%s", GetPrivateValueName(inf.pPrivateDirectives, "value"));
  1971. GenPERFuncSimpleType(ass, &inf.Root.SubType->PERTypeInfo, valbuf,
  1972. eDecode, encref);
  1973. // end of element body
  1974. return;
  1975. }
  1976. }
  1977. /* use a loop for sequence of/set of value with */
  1978. /* list representation */
  1979. outputvar("P%s *f;\n", inf.Identifier);
  1980. lenref = NULL;
  1981. } else {
  1982. MyAbort();
  1983. }
  1984. break;
  1985. case ePERSTIData_Extension:
  1986. /* length of extension */
  1987. if (inf.Root.Length == ePERSTILength_SmallLength)
  1988. lenref = "e";
  1989. else
  1990. lenref = NULL;
  1991. break;
  1992. case ePERSTIData_Boolean:
  1993. if (g_fCaseBasedOptimizer)
  1994. {
  1995. if (PerOptCase_IsBoolean(&inf.Root))
  1996. {
  1997. lenref = NULL;
  1998. break;
  1999. }
  2000. }
  2001. /* boolean value */
  2002. inf.Root.Data = ePERSTIData_Unsigned;
  2003. lenref = NULL;
  2004. break;
  2005. default:
  2006. /* other values have no additional length */
  2007. lenref = NULL;
  2008. break;
  2009. }
  2010. /* check for extended values */
  2011. if (inf.Type > eExtension_Unextended) {
  2012. outputvar("ASN1uint32_t x;\n");
  2013. if (g_fCaseBasedOptimizer)
  2014. {
  2015. output("if (!ASN1PERDecExtensionBit(%s, &x))\n", encref);
  2016. }
  2017. else
  2018. {
  2019. output("if (!ASN1PERDecBit(%s, &x))\n", encref);
  2020. }
  2021. output("return 0;\n");
  2022. output("if (!x) {\n");
  2023. }
  2024. /* additional variable for enumeraton value mapping */
  2025. oldvalref = valref;
  2026. if (inf.EnumerationValues && valref) {
  2027. outputvar("ASN1uint32_t u;\n");
  2028. valref = "u";
  2029. inf.NOctets = 4;
  2030. }
  2031. /* decode unextended value (of extension root) */
  2032. GenPERDecGenericUnextended(ass, &inf, &inf.Root, valref, lenref, encref);
  2033. /* map enumeration values if type is extendable */
  2034. if (inf.EnumerationValues && oldvalref &&
  2035. inf.Type == eExtension_Extendable) {
  2036. output("switch (u) {\n");
  2037. for (i = 0; inf.EnumerationValues[i]; i++) {
  2038. output("case %u:\n", i);
  2039. output("%s = %u;\n", oldvalref, intx2uint32(inf.EnumerationValues[i]));
  2040. output("break;\n");
  2041. }
  2042. output("}\n");
  2043. }
  2044. /* type is extendable? */
  2045. if (inf.Type > eExtension_Unextended) {
  2046. output("} else {\n");
  2047. if (inf.Type == eExtension_Extendable)
  2048. valref = lenref = NULL;
  2049. /* decode extended value (of extension addition) */
  2050. GenPERDecGenericUnextended(ass, &inf, &inf.Additional, valref, lenref, encref);
  2051. output("}\n");
  2052. }
  2053. /* map enumeration values if type is unextended/extended */
  2054. if (inf.EnumerationValues && oldvalref &&
  2055. inf.Type != eExtension_Extendable) {
  2056. output("switch (u) {\n");
  2057. for (i = 0; inf.EnumerationValues[i]; i++) {
  2058. output("case %u:\n", i);
  2059. output("%s = %u;\n", oldvalref, intx2uint32(inf.EnumerationValues[i]));
  2060. output("break;\n");
  2061. }
  2062. output("}\n");
  2063. }
  2064. }
  2065. /* generate decoding statements for a simple value (after some special */
  2066. /* handling has been done, esp. the evaluation of the extension) */
  2067. void GenPERDecGenericUnextended(
  2068. AssignmentList_t ass,
  2069. PERTypeInfo_t *info,
  2070. PERSimpleTypeInfo_t *sinfo,
  2071. char *valref,
  2072. char *lenref,
  2073. char *encref)
  2074. {
  2075. char valbuf[256];
  2076. char lenbuf[256];
  2077. char lbbuf[256];
  2078. char *p;
  2079. char *oldvalref;
  2080. intx_t ix;
  2081. /* check for empty field */
  2082. if (sinfo->NBits == 0) {
  2083. switch (sinfo->Data) {
  2084. case ePERSTIData_Null:
  2085. return;
  2086. case ePERSTIData_Integer:
  2087. case ePERSTIData_Unsigned:
  2088. if (valref && (sinfo->Constraint == ePERSTIConstraint_Semiconstrained || sinfo->Constraint == ePERSTIConstraint_Constrained)) {
  2089. if (info->NOctets == 0) {
  2090. sprintf(lbbuf, "%s_lb", info->Identifier);
  2091. outputvarintx(lbbuf, &sinfo->LowerVal);
  2092. output("ASN1intx_dup(%s, %s);\n", Reference(valref), lbbuf);
  2093. } else if (sinfo->Data == ePERSTIData_Integer) {
  2094. output("%s = %d;\n", valref, intx2int32(&sinfo->LowerVal));
  2095. } else {
  2096. output("%s = %u;\n", valref, intx2uint32(&sinfo->LowerVal));
  2097. }
  2098. }
  2099. return;
  2100. case ePERSTIData_BitString:
  2101. case ePERSTIData_RZBBitString:
  2102. case ePERSTIData_OctetString:
  2103. case ePERSTIData_UTF8String:
  2104. case ePERSTIData_SequenceOf:
  2105. case ePERSTIData_SetOf:
  2106. case ePERSTIData_String:
  2107. case ePERSTIData_TableString:
  2108. case ePERSTIData_ZeroString:
  2109. case ePERSTIData_ZeroTableString:
  2110. if (lenref)
  2111. output("%s = 0;\n", lenref);
  2112. return;
  2113. case ePERSTIData_Extension:
  2114. if (sinfo->Length == ePERSTILength_SmallLength)
  2115. break;
  2116. return;
  2117. default:
  2118. MyAbort();
  2119. }
  2120. }
  2121. /* check for decoding of non-negative-binary-integer */
  2122. switch (sinfo->Constraint) {
  2123. case ePERSTIConstraint_Semiconstrained:
  2124. case ePERSTIConstraint_Constrained:
  2125. if (sinfo->Data == ePERSTIData_Integer)
  2126. sinfo->Data = ePERSTIData_Unsigned;
  2127. break;
  2128. }
  2129. /* use newval for dec of semiconstraint/constraint intx_t with lb != 0 */
  2130. switch (sinfo->Constraint) {
  2131. case ePERSTIConstraint_Semiconstrained:
  2132. case ePERSTIConstraint_Constrained:
  2133. switch (sinfo->Data) {
  2134. case ePERSTIData_Integer:
  2135. case ePERSTIData_Unsigned:
  2136. case ePERSTIData_NormallySmall:
  2137. if (valref) {
  2138. if (intx_cmp(&sinfo->LowerVal, &intx_0) != 0) {
  2139. if (info->NOctets == 0) {
  2140. outputvar("ASN1intx_t newval;\n");
  2141. oldvalref = valref;
  2142. valref = "newval";
  2143. }
  2144. }
  2145. }
  2146. break;
  2147. }
  2148. break;
  2149. }
  2150. /* general rules */
  2151. if (sinfo->LAlignment == ePERSTIAlignment_OctetAligned && sinfo->Length == ePERSTILength_BitLength &&
  2152. !(sinfo->LNBits & 7))
  2153. sinfo->Alignment = ePERSTIAlignment_BitAligned;
  2154. /* octet alignment will be given my length */
  2155. if (sinfo->Length == ePERSTILength_InfiniteLength &&
  2156. (sinfo->Data == ePERSTIData_Integer && info->NOctets == 0 ||
  2157. sinfo->Data == ePERSTIData_Unsigned && info->NOctets == 0 ||
  2158. sinfo->Data == ePERSTIData_BitString ||
  2159. sinfo->Data == ePERSTIData_RZBBitString ||
  2160. sinfo->Data == ePERSTIData_Extension ||
  2161. sinfo->Data == ePERSTIData_OctetString ||
  2162. sinfo->Data == ePERSTIData_UTF8String ||
  2163. sinfo->Data == ePERSTIData_SequenceOf ||
  2164. sinfo->Data == ePERSTIData_SetOf ||
  2165. sinfo->Data == ePERSTIData_String ||
  2166. sinfo->Data == ePERSTIData_TableString ||
  2167. sinfo->Data == ePERSTIData_ZeroString ||
  2168. sinfo->Data == ePERSTIData_ZeroTableString) ||
  2169. sinfo->Data == ePERSTIData_ObjectIdentifier ||
  2170. sinfo->Data == ePERSTIData_Real ||
  2171. sinfo->Data == ePERSTIData_GeneralizedTime ||
  2172. sinfo->Data == ePERSTIData_UTCTime ||
  2173. sinfo->Data == ePERSTIData_External ||
  2174. sinfo->Data == ePERSTIData_EmbeddedPdv ||
  2175. sinfo->Data == ePERSTIData_MultibyteString ||
  2176. sinfo->Data == ePERSTIData_UnrestrictedString ||
  2177. sinfo->Data == ePERSTIData_Open)
  2178. sinfo->LAlignment = sinfo->Alignment = ePERSTIAlignment_BitAligned;
  2179. /* alignment will be done by encoding fn */
  2180. if (sinfo->Length == ePERSTILength_NoLength ||
  2181. sinfo->Length == ePERSTILength_SmallLength)
  2182. sinfo->LAlignment = ePERSTIAlignment_BitAligned;
  2183. /* no alignment of no length */
  2184. if (g_fCaseBasedOptimizer)
  2185. {
  2186. // lonchanc: special handling for macro operations
  2187. if (PerOptCase_IsSignedInteger(sinfo))
  2188. {
  2189. output("if (!ASN1PERDecInteger(%s, %s))\n", encref, Reference(valref));
  2190. output("return 0;\n");
  2191. goto FinalTouch;
  2192. }
  2193. if (PerOptCase_IsUnsignedInteger(sinfo))
  2194. {
  2195. output("if (!ASN1PERDecUnsignedInteger(%s, %s))\n", encref, Reference(valref));
  2196. output("return 0;\n");
  2197. goto FinalTouch;
  2198. }
  2199. if (PerOptCase_IsUnsignedShort(sinfo))
  2200. {
  2201. output("if (!ASN1PERDecUnsignedShort(%s, %s))\n", encref, Reference(valref));
  2202. output("return 0;\n");
  2203. goto FinalTouch;
  2204. }
  2205. if (PerOptCase_IsBoolean(sinfo))
  2206. {
  2207. output("if (!ASN1PERDecBoolean(%s, %s))\n", encref, Reference(valref));
  2208. output("return 0;\n");
  2209. return;
  2210. }
  2211. }
  2212. /* initial settings for length enconding: */
  2213. /* add lower bound of length to length */
  2214. if (!lenref) {
  2215. if (sinfo->Length == ePERSTILength_NoLength &&
  2216. sinfo->Data != ePERSTIData_Extension) {
  2217. sprintf(lenbuf, "%u", sinfo->LLowerVal);
  2218. lenref = lenbuf;
  2219. } else if (sinfo->Data != ePERSTIData_ObjectIdentifier &&
  2220. sinfo->Data != ePERSTIData_External &&
  2221. sinfo->Data != ePERSTIData_EmbeddedPdv &&
  2222. sinfo->Data != ePERSTIData_MultibyteString &&
  2223. sinfo->Data != ePERSTIData_UnrestrictedString &&
  2224. sinfo->Data != ePERSTIData_Extension &&
  2225. (sinfo->Length != ePERSTILength_InfiniteLength ||
  2226. (sinfo->Data != ePERSTIData_SetOf &&
  2227. sinfo->Data != ePERSTIData_SequenceOf) ||
  2228. !IsStructuredType(GetType(ass, sinfo->SubType))) &&
  2229. ((sinfo->Data != ePERSTIData_SetOf &&
  2230. sinfo->Data != ePERSTIData_SequenceOf) || valref) &&
  2231. (sinfo->Length != ePERSTILength_InfiniteLength ||
  2232. info->NOctets != 0 ||
  2233. (sinfo->Data != ePERSTIData_Integer &&
  2234. sinfo->Data != ePERSTIData_Unsigned)) &&
  2235. ((sinfo->Data != ePERSTIData_ZeroString &&
  2236. sinfo->Data != ePERSTIData_ZeroTableString) ||
  2237. sinfo->Length != ePERSTILength_InfiniteLength) &&
  2238. (sinfo->Data != ePERSTIData_BitString &&
  2239. sinfo->Data != ePERSTIData_UTF8String &&
  2240. sinfo->Data != ePERSTIData_OctetString)) {
  2241. outputvar("ASN1uint32_t l;\n");
  2242. lenref = "l";
  2243. }
  2244. } else if (sinfo->Length == ePERSTILength_NoLength) {
  2245. if ((sinfo->Data == ePERSTIData_BitString ||
  2246. sinfo->Data == ePERSTIData_RZBBitString) &&
  2247. sinfo->cbFixedSizeBitString)
  2248. {
  2249. // lonchanc: doing nothing here because lenref is a constant number
  2250. }
  2251. else
  2252. {
  2253. output("%s = %u;\n", lenref, sinfo->LLowerVal);
  2254. }
  2255. }
  2256. /* length encoding */
  2257. if (sinfo->LAlignment == ePERSTIAlignment_OctetAligned) {
  2258. output("ASN1PERDecAlignment(%s);\n", encref);
  2259. }
  2260. switch (sinfo->Length) {
  2261. case ePERSTILength_NoLength:
  2262. break;
  2263. case ePERSTILength_BitLength:
  2264. /* get length */
  2265. output("if (!ASN1PERDecU32Val(%s, %u, %s))\n",
  2266. encref, sinfo->LNBits, Reference(lenref));
  2267. output("return 0;\n");
  2268. /* add lower bound of length */
  2269. if (sinfo->LLowerVal)
  2270. output("%s += %u;\n", lenref, sinfo->LLowerVal);
  2271. /*
  2272. if (sinfo->LConstraint == ePERSTIConstraint_Constrained) {
  2273. output("if (%s > %u)\n", lenref, sinfo->LUpperVal);
  2274. output("return ASN1DecError(%s, ASN1_ERR_CORRUPT);\n", encref);
  2275. }
  2276. */
  2277. break;
  2278. case ePERSTILength_InfiniteLength:
  2279. /* infinite length case */
  2280. switch (sinfo->Data) {
  2281. case ePERSTIData_Integer:
  2282. case ePERSTIData_Unsigned:
  2283. /* get length of integer value */
  2284. if (info->NOctets != 0) {
  2285. output("if (!ASN1PERDecFragmentedLength(%s, %s))\n",
  2286. encref, Reference(lenref));
  2287. output("return 0;\n");
  2288. if (sinfo->LLowerVal)
  2289. output("%s += %u;\n", lenref, sinfo->LLowerVal);
  2290. /*
  2291. if (sinfo->LConstraint == ePERSTIConstraint_Constrained) {
  2292. output("if (%s > %u)\n", lenref, sinfo->LUpperVal);
  2293. output("return ASN1DecError(%s, ASN1_ERR_CORRUPT);\n",
  2294. encref);
  2295. }
  2296. */
  2297. }
  2298. break;
  2299. }
  2300. break;
  2301. }
  2302. /* value decoding */
  2303. switch (sinfo->Length) {
  2304. case ePERSTILength_NoLength:
  2305. /* decode alignment of the value */
  2306. if (sinfo->Alignment == ePERSTIAlignment_OctetAligned) {
  2307. output("ASN1PERDecAlignment(%s);\n", encref);
  2308. }
  2309. switch (sinfo->Data) {
  2310. case ePERSTIData_Integer:
  2311. /* decode the value as bit field */
  2312. if (valref) {
  2313. if (!info->NOctets) {
  2314. output("if (!ASN1PERDecSXVal(%s, %u, %s))\n",
  2315. info->NOctets * 8, encref, sinfo->NBits, Reference(valref));
  2316. output("return 0;\n");
  2317. } else {
  2318. output("if (!ASN1PERDecS%dVal(%s, %u, %s))\n",
  2319. info->NOctets * 8, encref, sinfo->NBits, Reference(valref));
  2320. output("return 0;\n");
  2321. }
  2322. } else {
  2323. output("if (!ASN1PERDecSkipBits(%s, %u))\n",
  2324. encref, sinfo->NBits);
  2325. output("return 0;\n");
  2326. }
  2327. break;
  2328. case ePERSTIData_Unsigned:
  2329. /* decode the value as bit field */
  2330. if (valref) {
  2331. if (!info->NOctets) {
  2332. output("if (!ASN1PERDecUXVal(%s, %u, %s))\n",
  2333. info->NOctets * 8, encref, sinfo->NBits, Reference(valref));
  2334. output("return 0;\n");
  2335. } else {
  2336. output("if (!ASN1PERDecU%dVal(%s, %u, %s))\n",
  2337. info->NOctets * 8, encref, sinfo->NBits, Reference(valref));
  2338. output("return 0;\n");
  2339. }
  2340. } else {
  2341. output("if (!ASN1PERDecSkipBits(%s, %u))\n",
  2342. encref, sinfo->NBits);
  2343. output("return 0;\n");
  2344. }
  2345. break;
  2346. case ePERSTIData_NormallySmall:
  2347. /* decode the value as normally small number */
  2348. if (valref) {
  2349. if (!info->NOctets) {
  2350. MyAbort();
  2351. } else {
  2352. output("if (!ASN1PERDecN%dVal(%s, %s))\n",
  2353. info->NOctets * 8, encref, Reference(valref));
  2354. output("return 0;\n");
  2355. }
  2356. } else {
  2357. output("if (!ASN1PERDecSkipNormallySmall(%s))\n",
  2358. encref);
  2359. output("return 0;\n");
  2360. }
  2361. break;
  2362. case ePERSTIData_BitString:
  2363. case ePERSTIData_RZBBitString:
  2364. /* decode bit string in a bit field */
  2365. if (valref) {
  2366. if (sinfo->cbFixedSizeBitString)
  2367. {
  2368. output("if (!ASN1PERDecExtension(%s, %s, %s))\n",
  2369. encref, lenref, Reference(valref));
  2370. }
  2371. else
  2372. {
  2373. output("if (!ASN1PERDecBits(%s, %s, %s))\n",
  2374. encref, lenref, Reference(valref));
  2375. }
  2376. output("return 0;\n");
  2377. } else {
  2378. output("if (!ASN1PERDecSkipBits(%s, %s))\n",
  2379. encref, lenref);
  2380. output("return 0;\n");
  2381. }
  2382. break;
  2383. case ePERSTIData_OctetString:
  2384. /* decode octet string in a bit field */
  2385. if (valref) {
  2386. if (sinfo->LConstraint == ePERSTIConstraint_Constrained &&
  2387. (! info->pPrivateDirectives->fLenPtr))
  2388. {
  2389. output("if (!ASN1PERDecExtension(%s, %s * 8, %s))\n",
  2390. encref, lenref, valref);
  2391. }
  2392. else
  2393. {
  2394. output("if (!ASN1PERDecBits(%s, %s * 8, %s))\n",
  2395. encref, lenref, Reference(valref));
  2396. }
  2397. output("return 0;\n");
  2398. } else {
  2399. output("if (!ASN1PERDecSkipBits(%s, %s * 8))\n",
  2400. encref, lenref);
  2401. output("return 0;\n");
  2402. }
  2403. break;
  2404. case ePERSTIData_UTF8String:
  2405. /* decode octet string in a bit field */
  2406. if (valref) {
  2407. output("if (!ASN1PERDecUTF8String(%s, %s, %s))\n",
  2408. encref, lenref, Reference(valref));
  2409. output("return 0;\n");
  2410. } else {
  2411. MyAbort();
  2412. }
  2413. break;
  2414. case ePERSTIData_Extension:
  2415. /* decode extension bits in a bit field */
  2416. if (valref) {
  2417. output("if (!ASN1PERDecExtension(%s, %u, %s))\n",
  2418. encref, sinfo->NBits, valref);
  2419. output("return 0;\n");
  2420. } else {
  2421. output("if (!ASN1PERDecSkipBits(%s, %u))\n",
  2422. encref, sinfo->NBits);
  2423. output("return 0;\n");
  2424. }
  2425. break;
  2426. case ePERSTIData_SetOf:
  2427. /* same as BitLength encoding */
  2428. goto SetOfEncoding;
  2429. case ePERSTIData_SequenceOf:
  2430. /* same as BitLength encoding */
  2431. goto SequenceOfEncoding;
  2432. case ePERSTIData_String:
  2433. /* same as BitLength encoding */
  2434. goto StringEncoding;
  2435. case ePERSTIData_ZeroString:
  2436. /* same as BitLength encoding */
  2437. goto ZeroStringEncoding;
  2438. case ePERSTIData_TableString:
  2439. /* same as BitLength encoding */
  2440. goto TableStringEncoding;
  2441. case ePERSTIData_ZeroTableString:
  2442. /* same as BitLength encoding */
  2443. goto ZeroTableStringEncoding;
  2444. case ePERSTIData_Reference:
  2445. /* call encoding function of referenced type */
  2446. if (valref) {
  2447. output("if (!ASN1Dec_%s(%s, %s))\n",
  2448. Identifier2C(sinfo->SubIdentifier),
  2449. encref, Reference(valref));
  2450. output("return 0;\n");
  2451. } else {
  2452. output("if (!ASN1Dec_%s(%s, NULL))\n",
  2453. Identifier2C(sinfo->SubIdentifier),
  2454. encref);
  2455. output("return 0;\n");
  2456. }
  2457. break;
  2458. case ePERSTIData_Real:
  2459. /* decode real value */
  2460. if (valref) {
  2461. if (info->NOctets)
  2462. output("if (!ASN1PERDecDouble(%s, %s))\n",
  2463. encref, Reference(valref));
  2464. else
  2465. output("if (!ASN1PERDecReal(%s, %s))\n",
  2466. encref, Reference(valref));
  2467. output("return 0;\n");
  2468. } else {
  2469. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  2470. encref);
  2471. output("return 0;\n");
  2472. }
  2473. break;
  2474. case ePERSTIData_GeneralizedTime:
  2475. /* decode generalized time value */
  2476. if (valref) {
  2477. output("if (!ASN1PERDecGeneralizedTime(%s, %s, %d))\n",
  2478. encref, Reference(valref), sinfo->NBits);
  2479. output("return 0;\n");
  2480. } else {
  2481. output("if (!ASN1PERDecSkipFragmented(%s, %d))\n",
  2482. encref, sinfo->NBits);
  2483. output("return 0;\n");
  2484. }
  2485. break;
  2486. case ePERSTIData_UTCTime:
  2487. /* decode utc time value */
  2488. if (valref) {
  2489. output("if (!ASN1PERDecUTCTime(%s, %s, %d))\n",
  2490. encref, Reference(valref), sinfo->NBits);
  2491. output("return 0;\n");
  2492. } else {
  2493. output("if (!ASN1PERDecSkipFragmented(%s, %d))\n",
  2494. encref, sinfo->NBits);
  2495. output("return 0;\n");
  2496. }
  2497. break;
  2498. }
  2499. break;
  2500. case ePERSTILength_BitLength:
  2501. /* decode alignment of the value */
  2502. if (sinfo->Alignment == ePERSTIAlignment_OctetAligned) {
  2503. output("ASN1PERDecAlignment(%s);\n", encref);
  2504. }
  2505. switch (sinfo->Data) {
  2506. case ePERSTIData_Integer:
  2507. case ePERSTIData_Unsigned:
  2508. /* decode the value as bit field */
  2509. if (valref) {
  2510. if (info->NOctets == 0 && sinfo->Data == ePERSTIData_Integer) {
  2511. output("if (!ASN1PERDecSXVal(%s, %s * 8, %s))\n",
  2512. encref, lenref, Reference(valref));
  2513. output("return 0;\n");
  2514. } else if (info->NOctets == 0 && sinfo->Data == ePERSTIData_Unsigned) {
  2515. output("if (!ASN1PERDecUXVal(%s, %s * 8, %s))\n",
  2516. encref, lenref, Reference(valref));
  2517. output("return 0;\n");
  2518. } else if (sinfo->Data == ePERSTIData_Integer) {
  2519. output("if (!ASN1PERDecS%dVal(%s, %s * 8, %s))\n",
  2520. info->NOctets * 8, encref, lenref, Reference(valref));
  2521. output("return 0;\n");
  2522. } else {
  2523. output("if (!ASN1PERDecU%dVal(%s, %s * 8, %s))\n",
  2524. info->NOctets * 8, encref, lenref, Reference(valref));
  2525. output("return 0;\n");
  2526. }
  2527. } else {
  2528. output("if (!ASN1PERDecSkipBits(%s, %s * 8))\n",
  2529. encref, lenref);
  2530. output("return 0;\n");
  2531. }
  2532. break;
  2533. case ePERSTIData_BitString:
  2534. case ePERSTIData_RZBBitString:
  2535. /* decode the value as bit field */
  2536. if (valref) {
  2537. output("if (!ASN1PERDecBits(%s, %s, %s))\n",
  2538. encref, lenref, Reference(valref));
  2539. output("return 0;\n");
  2540. } else {
  2541. output("if (!ASN1PERDecSkipBits(%s, %s))\n",
  2542. encref, lenref);
  2543. output("return 0;\n");
  2544. }
  2545. break;
  2546. case ePERSTIData_OctetString:
  2547. /* decode the value as bit field */
  2548. if (valref) {
  2549. if (sinfo->LConstraint == ePERSTIConstraint_Constrained &&
  2550. (! info->pPrivateDirectives->fLenPtr))
  2551. {
  2552. output("if (!ASN1PERDecExtension(%s, %s * 8, %s))\n",
  2553. encref, lenref, valref);
  2554. }
  2555. else
  2556. {
  2557. output("if (!ASN1PERDecBits(%s, %s * 8, %s))\n",
  2558. encref, lenref, Reference(valref));
  2559. }
  2560. output("return 0;\n");
  2561. } else {
  2562. output("if (!ASN1PERDecSkipBits(%s, %s * 8))\n",
  2563. encref, lenref);
  2564. output("return 0;\n");
  2565. }
  2566. break;
  2567. case ePERSTIData_UTF8String:
  2568. /* decode the value as bit field */
  2569. if (valref) {
  2570. output("if (!ASN1PERDecUTF8String(%s, %s, %s))\n",
  2571. encref, lenref, Reference(valref));
  2572. output("return 0;\n");
  2573. } else {
  2574. MyAbort();
  2575. }
  2576. break;
  2577. case ePERSTIData_SetOf:
  2578. SetOfEncoding:
  2579. /*FALLTHROUGH*/
  2580. case ePERSTIData_SequenceOf:
  2581. SequenceOfEncoding:
  2582. /* skip null sequence of/set of */
  2583. if (sinfo->SubType->Flags & eTypeFlags_Null)
  2584. break;
  2585. outputvar("ASN1uint32_t i;\n");
  2586. if (!valref || (info->Rules & eTypeRules_PointerArrayMask))
  2587. {
  2588. // lonchanc: no need to allocate memory for eTypeRules_FixedArray
  2589. /* allocate memory for elements */
  2590. if (valref && (info->Rules & eTypeRules_LengthPointer))
  2591. {
  2592. output("if (!%s) {\n", lenref);
  2593. output("%s = NULL;\n", valref);
  2594. output("} else {\n");
  2595. output("if (!(%s = (%s *)ASN1DecAlloc(%s, %s * sizeof(%s))))\n",
  2596. valref, sinfo->SubIdentifier, encref,
  2597. lenref, Dereference(valref));
  2598. output("return 0;\n");
  2599. }
  2600. /* decode elements */
  2601. output("for (i = 0; i < %s; i++) {\n", lenref);
  2602. if (valref) {
  2603. sprintf(valbuf, "(%s)[i]", valref);
  2604. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf, eDecode, encref);
  2605. } else {
  2606. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, NULL, eDecode, encref);
  2607. }
  2608. /* loop end */
  2609. output("}\n");
  2610. if (valref && (info->Rules & eTypeRules_LengthPointer))
  2611. output("}\n"); // closing bracket for else
  2612. }
  2613. else if (info->Rules & eTypeRules_SinglyLinkedList)
  2614. {
  2615. char szPrivateValueName[64];
  2616. sprintf(&szPrivateValueName[0], "(*f)->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  2617. /* allocate and decode elements */
  2618. outputvar("P%s *f;\n", info->Identifier);
  2619. output("f = %s;\n", Reference(valref));
  2620. output("for (i = 0; i < %s; i++) {\n", lenref);
  2621. output("if (!(*f = (P%s)ASN1DecAlloc(%s, sizeof(**f))))\n",
  2622. info->Identifier, encref);
  2623. output("return 0;\n");
  2624. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, &szPrivateValueName[0],
  2625. eDecode, encref);
  2626. output("f = &(*f)->next;\n");
  2627. output("}\n");
  2628. output("*f = NULL;\n");
  2629. }
  2630. else
  2631. if (info->Rules & eTypeRules_DoublyLinkedList)
  2632. {
  2633. char szPrivateValueName[64];
  2634. sprintf(&szPrivateValueName[0], "(*f)->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  2635. /* allocate and decode elements */
  2636. outputvar("P%s *f;\n", info->Identifier);
  2637. outputvar("%s b;\n", info->Identifier);
  2638. output("f = %s;\n", Reference(valref));
  2639. output("b = NULL;\n");
  2640. output("for (i = 0; i < %s; i++) {\n", lenref);
  2641. output("if (!(*f = (P%s)ASN1DecAlloc(%s, sizeof(**f))))\n",
  2642. info->Identifier, encref);
  2643. output("return 0;\n");
  2644. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, &szPrivateValueName[0],
  2645. eDecode, encref);
  2646. output("f->prev = b;\n");
  2647. output("b = *f;\n");
  2648. output("f = &b->next;\n");
  2649. output("}\n");
  2650. output("*f = NULL;\n");
  2651. }
  2652. break;
  2653. case ePERSTIData_String:
  2654. StringEncoding:
  2655. /* decode string value */
  2656. if (info->NOctets == 1) {
  2657. p = "Char";
  2658. } else if (info->NOctets == 2) {
  2659. p = "Char16";
  2660. } else if (info->NOctets == 4) {
  2661. p = "Char32";
  2662. } else
  2663. MyAbort();
  2664. if (valref) {
  2665. #ifdef ENABLE_CHAR_STR_SIZE
  2666. if (info->NOctets == 1 &&
  2667. info->Root.LConstraint == ePERSTIConstraint_Constrained)
  2668. {
  2669. output("if (!ASN1PERDec%sStringNoAlloc(%s, %s, %s, %u))\n",
  2670. p, encref, lenref, valref, sinfo->NBits);
  2671. }
  2672. else
  2673. {
  2674. output("if (!ASN1PERDec%sString(%s, %s, %s, %u))\n",
  2675. p, encref, lenref, Reference(valref), sinfo->NBits);
  2676. }
  2677. #else
  2678. output("if (!ASN1PERDec%sString(%s, %s, %s, %u))\n",
  2679. p, encref, lenref, Reference(valref), sinfo->NBits);
  2680. #endif
  2681. output("return 0;\n");
  2682. } else {
  2683. output("if (!ASN1PERDecSkipBits(%s, %s * %u))\n",
  2684. encref, lenref, sinfo->NBits);
  2685. output("return 0;\n");
  2686. }
  2687. break;
  2688. case ePERSTIData_ZeroString:
  2689. ZeroStringEncoding:
  2690. /* decode zero-terminated string value */
  2691. if (info->NOctets == 1) {
  2692. p = "Char";
  2693. } else if (info->NOctets == 2) {
  2694. p = "Char16";
  2695. } else if (info->NOctets == 4) {
  2696. p = "Char32";
  2697. } else
  2698. MyAbort();
  2699. if (valref) {
  2700. #ifdef ENABLE_CHAR_STR_SIZE
  2701. if (info->NOctets == 1 &&
  2702. info->Root.LConstraint == ePERSTIConstraint_Constrained)
  2703. {
  2704. output("if (!ASN1PERDecZero%sStringNoAlloc(%s, %s, %s, %u))\n",
  2705. p, encref, lenref, valref, sinfo->NBits);
  2706. }
  2707. else
  2708. {
  2709. output("if (!ASN1PERDecZero%sString(%s, %s, %s, %u))\n",
  2710. p, encref, lenref, Reference(valref), sinfo->NBits);
  2711. }
  2712. #else
  2713. output("if (!ASN1PERDecZero%sString(%s, %s, %s, %u))\n",
  2714. p, encref, lenref, Reference(valref), sinfo->NBits);
  2715. #endif
  2716. output("return 0;\n");
  2717. } else {
  2718. output("if (!ASN1PERDecSkipBits(%s, %s * %u))\n",
  2719. encref, lenref, sinfo->NBits);
  2720. output("return 0;\n");
  2721. }
  2722. break;
  2723. case ePERSTIData_TableString:
  2724. TableStringEncoding:
  2725. /* decode table string value */
  2726. if (info->NOctets == 1) {
  2727. p = "Char";
  2728. } else if (info->NOctets == 2) {
  2729. p = "Char16";
  2730. } else if (info->NOctets == 4) {
  2731. p = "Char32";
  2732. } else
  2733. MyAbort();
  2734. if (valref) {
  2735. #ifdef ENABLE_CHAR_STR_SIZE
  2736. if (info->NOctets == 1 &&
  2737. info->Root.LConstraint == ePERSTIConstraint_Constrained)
  2738. {
  2739. output("if (!ASN1PERDecTable%sStringNoAlloc(%s, %s, %s, %u, %s))\n",
  2740. p, encref, lenref, valref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  2741. }
  2742. else
  2743. {
  2744. output("if (!ASN1PERDecTable%sString(%s, %s, %s, %u, %s))\n",
  2745. p, encref, lenref, Reference(valref), sinfo->NBits, Reference(sinfo->TableIdentifier));
  2746. }
  2747. #else
  2748. output("if (!ASN1PERDecTable%sString(%s, %s, %s, %u, %s))\n",
  2749. p, encref, lenref, Reference(valref), sinfo->NBits, Reference(sinfo->TableIdentifier));
  2750. #endif
  2751. output("return 0;\n");
  2752. } else {
  2753. output("if (!ASN1PERDecSkipBits(%s, %s * %u, %s))\n",
  2754. encref, lenref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  2755. output("return 0;\n");
  2756. }
  2757. break;
  2758. case ePERSTIData_ZeroTableString:
  2759. ZeroTableStringEncoding:
  2760. /* decode zero-terminated table string value */
  2761. if (info->NOctets == 1) {
  2762. p = "Char";
  2763. } else if (info->NOctets == 2) {
  2764. p = "Char16";
  2765. } else if (info->NOctets == 4) {
  2766. p = "Char32";
  2767. } else
  2768. MyAbort();
  2769. if (valref) {
  2770. #ifdef ENABLE_CHAR_STR_SIZE
  2771. if (info->NOctets == 1 &&
  2772. info->Root.LConstraint == ePERSTIConstraint_Constrained)
  2773. {
  2774. output("if (!ASN1PERDecZeroTable%sStringNoAlloc(%s, %s, %s, %u, %s))\n",
  2775. p, encref, lenref, valref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  2776. }
  2777. else
  2778. {
  2779. output("if (!ASN1PERDecZeroTable%sString(%s, %s, %s, %u, %s))\n",
  2780. p, encref, lenref, Reference(valref), sinfo->NBits, Reference(sinfo->TableIdentifier));
  2781. }
  2782. #else
  2783. output("if (!ASN1PERDecZeroTable%sString(%s, %s, %s, %u, %s))\n",
  2784. p, encref, lenref, Reference(valref), sinfo->NBits, Reference(sinfo->TableIdentifier));
  2785. #endif
  2786. output("return 0;\n");
  2787. } else {
  2788. output("if (!ASN1PERDecSkipBits(%s, %s * %u, %s))\n",
  2789. encref, lenref, sinfo->NBits, Reference(sinfo->TableIdentifier));
  2790. output("return 0;\n");
  2791. }
  2792. break;
  2793. }
  2794. break;
  2795. case ePERSTILength_InfiniteLength:
  2796. /* infinite length case */
  2797. switch (sinfo->Data) {
  2798. case ePERSTIData_Integer:
  2799. case ePERSTIData_Unsigned:
  2800. /* get integer value as fragmented */
  2801. if (valref) {
  2802. if (info->NOctets == 0) {
  2803. if (sinfo->Data == ePERSTIData_Integer) {
  2804. output("if (!ASN1PERDecFragmentedIntx(%s, %s))\n",
  2805. encref, Reference(valref));
  2806. } else {
  2807. output("if (!ASN1PERDecFragmentedUIntx(%s, %s))\n",
  2808. encref, Reference(valref));
  2809. }
  2810. output("return 0;\n");
  2811. } else if (sinfo->Data == ePERSTIData_Integer) {
  2812. output("if (!ASN1PERDecS%dVal(%s, %s * 8, %s))\n",
  2813. info->NOctets * 8, encref, lenref, Reference(valref));
  2814. output("return 0;\n");
  2815. } else {
  2816. output("if (!ASN1PERDecU%dVal(%s, %s * 8, %s))\n",
  2817. info->NOctets * 8, encref, lenref, Reference(valref));
  2818. output("return 0;\n");
  2819. }
  2820. } else {
  2821. if (info->NOctets != 0) {
  2822. output("if (!ASN1PERDecSkipBits(%s, %s * 8))\n",
  2823. encref, lenref);
  2824. output("return 0;\n");
  2825. } else {
  2826. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  2827. encref);
  2828. output("return 0;\n");
  2829. }
  2830. }
  2831. break;
  2832. case ePERSTIData_Extension:
  2833. /* get extension bits as fragmented */
  2834. if (valref) {
  2835. output("if (!ASN1PERDecFragmentedExtension(%s, %u, %s))\n",
  2836. encref, sinfo->NBits, valref);
  2837. output("return 0;\n");
  2838. } else {
  2839. output("if (!ASN1PERDecSkipFragmented(%s, 1))\n",
  2840. encref);
  2841. output("return 0;\n");
  2842. }
  2843. break;
  2844. case ePERSTIData_BitString:
  2845. case ePERSTIData_RZBBitString:
  2846. /* get bit string as fragmented */
  2847. if (valref) {
  2848. output("if (!ASN1PERDecFragmented(%s, %s, %s, 1))\n",
  2849. encref, Reference(lenref), Reference(valref));
  2850. output("return 0;\n");
  2851. } else {
  2852. output("if (!ASN1PERDecSkipFragmented(%s, 1))\n",
  2853. encref);
  2854. output("return 0;\n");
  2855. }
  2856. break;
  2857. case ePERSTIData_OctetString:
  2858. /* get octet string as fragmented */
  2859. if (valref) {
  2860. output("if (!ASN1PERDecFragmented(%s, %s, %s, 8))\n",
  2861. encref, Reference(lenref), Reference(valref));
  2862. output("return 0;\n");
  2863. } else {
  2864. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  2865. encref);
  2866. output("return 0;\n");
  2867. }
  2868. break;
  2869. case ePERSTIData_UTF8String:
  2870. /* get octet string as fragmented */
  2871. if (valref) {
  2872. output("if (!ASN1PERDecUTF8StringEx(%s, %s, %s))\n",
  2873. encref, Reference(lenref), Reference(valref));
  2874. output("return 0;\n");
  2875. } else {
  2876. MyAbort();
  2877. }
  2878. break;
  2879. case ePERSTIData_SetOf:
  2880. case ePERSTIData_SequenceOf:
  2881. /* we need some counters and iterators */
  2882. outputvar("ASN1uint32_t i;\n");
  2883. outputvar("ASN1uint32_t n;\n");
  2884. if (valref)
  2885. {
  2886. if (info->Rules & eTypeRules_LengthPointer)
  2887. {
  2888. output("%s = 0;\n", lenref);
  2889. output("%s = NULL;\n", valref);
  2890. }
  2891. else
  2892. if (info->Rules & eTypeRules_FixedArray)
  2893. {
  2894. output("%s = 0;\n", lenref);
  2895. }
  2896. else
  2897. if (info->Rules & eTypeRules_SinglyLinkedList)
  2898. {
  2899. outputvar("P%s *f;\n", info->Identifier);
  2900. output("f = %s;\n", Reference(valref));
  2901. }
  2902. else
  2903. if (info->Rules & eTypeRules_DoublyLinkedList)
  2904. {
  2905. outputvar("P%s *f;\n", info->Identifier);
  2906. outputvar("%s b;\n", info->Identifier);
  2907. output("f = %s;\n", Reference(valref));
  2908. output("b = NULL;\n");
  2909. }
  2910. }
  2911. /* get all elements of the sequence of/set of */
  2912. output("do {\n");
  2913. /* get length of a fragment */
  2914. output("if (!ASN1PERDecFragmentedLength(%s, &n))\n",
  2915. encref);
  2916. output("return 0;\n");
  2917. if (valref)
  2918. {
  2919. if (info->Rules & eTypeRules_LengthPointer)
  2920. {
  2921. // lonchanc: no need to allocate memory for eTypeRules_FixedArray
  2922. /* resize memory for the element */
  2923. output("if (!(%s = (%s *)ASN1DecRealloc(%s, %s, (%s + n) * sizeof(%s))))\n",
  2924. valref, GetTypeName(ass, sinfo->SubType), encref,
  2925. valref, lenref, Dereference(valref));
  2926. output("return 0;\n");
  2927. }
  2928. }
  2929. /* get the elements of the fragment */
  2930. output("for (i = 0; i < n; i++) {\n");
  2931. if (valref) {
  2932. if (info->Rules & eTypeRules_PointerArrayMask)
  2933. {
  2934. sprintf(valbuf, "(%s)[%s]", valref, lenref);
  2935. }
  2936. else
  2937. if (info->Rules & eTypeRules_LinkedListMask)
  2938. {
  2939. output("if (!(*f = (P%s)ASN1DecAlloc(%s, sizeof(**f))))\n",
  2940. info->Identifier, encref);
  2941. output("return 0;\n");
  2942. sprintf(valbuf, "(*f)->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  2943. }
  2944. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, valbuf, eDecode, encref);
  2945. if (info->Rules & eTypeRules_SinglyLinkedList)
  2946. {
  2947. output("f = &(*f)->next;\n");
  2948. }
  2949. else
  2950. if (info->Rules & eTypeRules_DoublyLinkedList)
  2951. {
  2952. output("(*f)->prev = b;\n");
  2953. output("b = *f;\n");
  2954. output("f = &b->next;\n");
  2955. }
  2956. } else {
  2957. GenPERFuncSimpleType(ass, &sinfo->SubType->PERTypeInfo, NULL, eDecode, encref);
  2958. }
  2959. if ((info->Rules & (eTypeRules_LengthPointer | eTypeRules_FixedArray)) && lenref)
  2960. output("(%s)++;\n", lenref);
  2961. /* end of inner loop */
  2962. output("}\n");
  2963. /* end of outer loop */
  2964. output("} while (n >= 0x4000);\n");
  2965. /* terminate list */
  2966. if (valref && (info->Rules & (eTypeRules_SinglyLinkedList | eTypeRules_DoublyLinkedList)))
  2967. output("*f = NULL;\n");
  2968. break;
  2969. case ePERSTIData_ObjectIdentifier:
  2970. /* decode object identifier value */
  2971. if (valref) {
  2972. if (info->pPrivateDirectives->fOidArray || g_fOidArray)
  2973. {
  2974. output("if (!ASN1PERDecObjectIdentifier2(%s, %s))\n",
  2975. encref, Reference(valref));
  2976. }
  2977. else
  2978. {
  2979. output("if (!ASN1PERDecObjectIdentifier(%s, %s))\n",
  2980. encref, Reference(valref));
  2981. }
  2982. output("return 0;\n");
  2983. } else {
  2984. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  2985. encref);
  2986. output("return 0;\n");
  2987. }
  2988. break;
  2989. case ePERSTIData_External:
  2990. /* decode external value */
  2991. output("if (!ASN1PERDecExternal(%s, %s))\n",
  2992. encref, Reference(valref));
  2993. output("return 0;\n");
  2994. break;
  2995. case ePERSTIData_EmbeddedPdv:
  2996. /* decode embedded pdv value */
  2997. if (sinfo->Identification) {
  2998. if (!strcmp(sinfo->Identification->Identifier, "fixed")) {
  2999. output("if (!ASN1PERDecEmbeddedPdvOpt(%s, %s, NULL, NULL))\n",
  3000. encref, Reference(valref));
  3001. } else {
  3002. output("if (!ASN1PERDecEmbeddedPdvOpt(%s, %s, &%s_identification_syntaxes_abstract, &%s_identification_syntaxes_transfer))\n",
  3003. encref, Reference(valref),
  3004. info->Identifier, info->Identifier);
  3005. }
  3006. } else {
  3007. output("if (!ASN1PERDecEmbeddedPdv(%s, %s))\n",
  3008. encref, Reference(valref));
  3009. }
  3010. output("return 0;\n");
  3011. break;
  3012. case ePERSTIData_MultibyteString:
  3013. /* decode multibyte string value */
  3014. output("if (!ASN1PERDecMultibyteString(%s, %s))\n",
  3015. encref, Reference(valref));
  3016. output("return 0;\n");
  3017. break;
  3018. case ePERSTIData_UnrestrictedString:
  3019. /* decode character string value */
  3020. if (sinfo->Identification) {
  3021. if (!strcmp(sinfo->Identification->Identifier, "fixed")) {
  3022. output("if (!ASN1PERDecCharacterStringOpt(%s, %s, NULL, NULL))\n",
  3023. encref, Reference(valref));
  3024. } else {
  3025. output("if (!ASN1PERDecCharacterStringOpt(%s, %s, &%s_identification_syntaxes_abstract, &%s_identification_syntaxes_transfer))\n",
  3026. encref, Reference(valref),
  3027. info->Identifier, info->Identifier);
  3028. }
  3029. } else {
  3030. output("if (!ASN1PERDecCharacterString(%s, %s))\n",
  3031. encref, Reference(valref));
  3032. }
  3033. output("return 0;\n");
  3034. break;
  3035. case ePERSTIData_String:
  3036. /* decode string value as fragmented */
  3037. if (info->NOctets == 1) {
  3038. p = "Char";
  3039. } else if (info->NOctets == 2) {
  3040. p = "Char16";
  3041. } else if (info->NOctets == 4) {
  3042. p = "Char32";
  3043. } else
  3044. MyAbort();
  3045. if (valref) {
  3046. output("if (!ASN1PERDecFragmented%sString(%s, %s, %s, %u))\n",
  3047. p, encref, Reference(lenref), Reference(valref), sinfo->NBits);
  3048. output("return 0;\n");
  3049. } else {
  3050. output("if (!ASN1PERDecSkipFragmented(%s, %u))\n",
  3051. encref, sinfo->NBits);
  3052. output("return 0;\n");
  3053. }
  3054. break;
  3055. case ePERSTIData_ZeroString:
  3056. /* decode zero-terminated string value as fragmented */
  3057. if (info->NOctets == 1) {
  3058. p = "Char";
  3059. } else if (info->NOctets == 2) {
  3060. p = "Char16";
  3061. } else if (info->NOctets == 4) {
  3062. p = "Char32";
  3063. } else
  3064. MyAbort();
  3065. if (valref) {
  3066. output("if (!ASN1PERDecFragmentedZero%sString(%s, %s, %u))\n",
  3067. p, encref, Reference(valref), sinfo->NBits);
  3068. output("return 0;\n");
  3069. } else {
  3070. output("if (!ASN1PERDecSkipFragmented(%s, %u))\n",
  3071. encref, sinfo->NBits);
  3072. output("return 0;\n");
  3073. }
  3074. break;
  3075. case ePERSTIData_TableString:
  3076. /* decode table string value as fragmented */
  3077. if (info->NOctets == 1) {
  3078. p = "Char";
  3079. } else if (info->NOctets == 2) {
  3080. p = "Char16";
  3081. } else if (info->NOctets == 4) {
  3082. p = "Char32";
  3083. } else
  3084. MyAbort();
  3085. if (valref) {
  3086. output("if (!ASN1PERDecFragmentedTable%sString(%s, %s, %s, %u, %s))\n",
  3087. p, encref, Reference(lenref), Reference(valref), sinfo->NBits,
  3088. Reference(sinfo->TableIdentifier));
  3089. output("return 0;\n");
  3090. } else {
  3091. output("if (!ASN1PERDecSkipFragmented(%s, %u))\n",
  3092. encref, sinfo->NBits);
  3093. output("return 0;\n");
  3094. }
  3095. break;
  3096. case ePERSTIData_ZeroTableString:
  3097. /* decode zero-terminated table-string as fragmented */
  3098. if (info->NOctets == 1) {
  3099. p = "Char";
  3100. } else if (info->NOctets == 2) {
  3101. p = "Char16";
  3102. } else if (info->NOctets == 4) {
  3103. p = "Char32";
  3104. } else
  3105. MyAbort();
  3106. if (valref) {
  3107. output("if (!ASN1PERDecFragmentedZeroTable%sString(%s, %s, %u, %s))\n",
  3108. p, encref, Reference(valref), sinfo->NBits, Reference(sinfo->TableIdentifier));
  3109. output("return 0;\n");
  3110. } else {
  3111. output("if (!ASN1PERDecSkipFragmented(%s, %u))\n",
  3112. encref, sinfo->NBits);
  3113. output("return 0;\n");
  3114. }
  3115. break;
  3116. case ePERSTIData_Open:
  3117. /* decode open type value */
  3118. if (valref) {
  3119. output("if (!ASN1PERDecOpenType(%s, %s))\n",
  3120. encref, Reference(valref));
  3121. output("return 0;\n");
  3122. } else {
  3123. output("if (!ASN1PERDecSkipFragmented(%s, 8))\n",
  3124. encref);
  3125. output("return 0;\n");
  3126. }
  3127. break;
  3128. }
  3129. break;
  3130. case ePERSTILength_SmallLength:
  3131. switch (sinfo->Data) {
  3132. case ePERSTIData_Extension:
  3133. /* decode extension bits with normally small length */
  3134. if (valref) {
  3135. output("if (!ASN1PERDecNormallySmallExtension(%s, %s, %u, %s))\n",
  3136. encref, Reference(lenref), sinfo->NBits, valref);
  3137. output("return 0;\n");
  3138. } else {
  3139. output("if (!ASN1PERDecSkipNormallySmallExtension(%s, %s))\n",
  3140. encref, Reference(lenref));
  3141. output("return 0;\n");
  3142. }
  3143. break;
  3144. }
  3145. }
  3146. FinalTouch:
  3147. /* additional calculations for value decoding: */
  3148. /* add lower bound of constraint/semiconstraint value */
  3149. switch (sinfo->Constraint) {
  3150. case ePERSTIConstraint_Semiconstrained:
  3151. case ePERSTIConstraint_Constrained:
  3152. switch (sinfo->Data) {
  3153. case ePERSTIData_Integer:
  3154. case ePERSTIData_Unsigned:
  3155. case ePERSTIData_NormallySmall:
  3156. if (valref) {
  3157. if (intx_cmp(&sinfo->LowerVal, &intx_0) != 0) {
  3158. if (info->NOctets != 0) {
  3159. if (intx_cmp(&sinfo->LowerVal, &intx_0) > 0) {
  3160. output("%s += %u;\n",
  3161. valref, intx2uint32(&sinfo->LowerVal));
  3162. } else {
  3163. intx_neg(&ix, &sinfo->LowerVal);
  3164. // LONCHANC: to workaround a compiler bug in vc++.
  3165. // output("%s += -%u;\n",
  3166. output("%s += 0 - %u;\n",
  3167. valref, intx2uint32(&ix));
  3168. }
  3169. } else {
  3170. sprintf(lbbuf, "%s_lb", info->Identifier);
  3171. outputvarintx(lbbuf, &sinfo->LowerVal);
  3172. output("ASN1intx_add(%s, %s, &%s);\n",
  3173. Reference(oldvalref), Reference(valref), lbbuf);
  3174. output("ASN1intx_free(%s);\n",
  3175. Reference(valref));
  3176. }
  3177. }
  3178. }
  3179. break;
  3180. }
  3181. break;
  3182. }
  3183. }