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.

1162 lines
35 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 "util.h"
  5. #include "error.h"
  6. static void GetAllPERFromConstraints(AssignmentList_t ass,
  7. Constraint_t *constraints,
  8. Extension_e *evalue,
  9. ValueConstraintList_t *valueConstraints,
  10. ValueConstraintList_t *evalueConstraints,
  11. Extension_e *esize,
  12. ValueConstraintList_t *sizeConstraints,
  13. ValueConstraintList_t *esizeConstraints,
  14. Extension_e *epermittedAlphabet,
  15. ValueConstraintList_t *permittedAlphabetConstraints,
  16. ValueConstraintList_t *epermittedAlphabetConstraints,
  17. int inPermAlpha);
  18. static void GetAllPERFromElementSetSpecs(AssignmentList_t ass,
  19. ElementSetSpec_t *element,
  20. Extension_e *evalue,
  21. ValueConstraintList_t *valueConstraints,
  22. ValueConstraintList_t *evalueConstraints,
  23. Extension_e *esize,
  24. ValueConstraintList_t *sizeConstraints,
  25. ValueConstraintList_t *esizeConstraints,
  26. Extension_e *epermittedAlphabet,
  27. ValueConstraintList_t *permittedAlphabetConstraints,
  28. ValueConstraintList_t *epermittedAlphabetConstraints,
  29. int inPermAlpha);
  30. static void GetAllPERFromSubtypeElements(AssignmentList_t ass,
  31. SubtypeElement_t *element,
  32. Extension_e *evalue,
  33. ValueConstraintList_t *valueConstraints,
  34. ValueConstraintList_t *evalueConstraints,
  35. Extension_e *esize,
  36. ValueConstraintList_t *sizeConstraints,
  37. ValueConstraintList_t *esizeConstraints,
  38. Extension_e *epermittedAlphabet,
  39. ValueConstraintList_t *permittedAlphabetConstraints,
  40. ValueConstraintList_t *epermittedAlphabetConstraints,
  41. int inPermAlpha);
  42. static void IntersectValueConstraints(AssignmentList_t ass,
  43. ValueConstraintList_t *result,
  44. ValueConstraintList_t val1, ValueConstraintList_t val2);
  45. static void UniteValueConstraints(ValueConstraintList_t *result,
  46. ValueConstraintList_t val1, ValueConstraintList_t val2);
  47. static void ExcludeValueConstraints(AssignmentList_t ass, ValueConstraintList_t *result,
  48. ValueConstraintList_t val1, ValueConstraintList_t val2);
  49. static void NegateValueConstraints(AssignmentList_t ass, ValueConstraintList_t *result,
  50. ValueConstraintList_t val);
  51. static void IntersectPERConstraints(AssignmentList_t ass,
  52. Extension_e *rtype,
  53. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  54. Extension_e type1,
  55. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  56. Extension_e type2,
  57. ValueConstraintList_t val2, ValueConstraintList_t eval2);
  58. static void UnitePERConstraints(Extension_e *rtype,
  59. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  60. Extension_e type1,
  61. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  62. Extension_e type2,
  63. ValueConstraintList_t val2, ValueConstraintList_t eval2);
  64. static void NegatePERConstraints(AssignmentList_t ass,
  65. Extension_e *rtype,
  66. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  67. Extension_e type1,
  68. ValueConstraintList_t val1, ValueConstraintList_t eval1);
  69. static void ExcludePERConstraints(AssignmentList_t ass,
  70. Extension_e *rtype,
  71. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  72. Extension_e type1,
  73. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  74. Extension_e type2,
  75. ValueConstraintList_t val2, ValueConstraintList_t eval2);
  76. static void ReduceValueConstraints(AssignmentList_t ass, ValueConstraintList_t *valueConstraints);
  77. #if 0
  78. ValueConstraint_t *EmptyValueConstraint();
  79. ValueConstraint_t *EmptySizeConstraint();
  80. ValueConstraint_t *EmptyPermittedAlphabetConstraint();
  81. #endif
  82. static NamedValue_t *GetFixedIdentificationFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements);
  83. static NamedValue_t *GetFixedAbstractAndTransfer(AssignmentList_t ass, Constraint_t *constraints);
  84. static NamedValue_t *GetFixedAbstractAndTransferFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements);
  85. static NamedValue_t *GetFixedSyntaxes(AssignmentList_t ass, Constraint_t *constraints);
  86. static NamedValue_t *GetFixedSyntaxesFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements);
  87. /* extract per-visible constraints from a type constraint */
  88. void
  89. GetPERConstraints(AssignmentList_t ass, Constraint_t *constraints, PERConstraints_t *per)
  90. {
  91. GetAllPERFromConstraints(ass,
  92. constraints,
  93. &per->Value.Type,
  94. &per->Value.Root,
  95. &per->Value.Additional,
  96. &per->Size.Type,
  97. &per->Size.Root,
  98. &per->Size.Additional,
  99. &per->PermittedAlphabet.Type,
  100. &per->PermittedAlphabet.Root,
  101. &per->PermittedAlphabet.Additional,
  102. 0);
  103. if (per->Value.Type > eExtension_Unconstrained)
  104. ReduceValueConstraints(ass, &per->Value.Root);
  105. if (per->Value.Type == eExtension_Extended)
  106. ReduceValueConstraints(ass, &per->Value.Additional);
  107. if (per->Size.Type > eExtension_Unconstrained)
  108. ReduceValueConstraints(ass, &per->Size.Root);
  109. if (per->Size.Type == eExtension_Extended)
  110. ReduceValueConstraints(ass, &per->Size.Additional);
  111. if (per->PermittedAlphabet.Type > eExtension_Unconstrained)
  112. ReduceValueConstraints(ass, &per->PermittedAlphabet.Root);
  113. /* permitted alphabet extensions are not PER-visible */
  114. if (per->PermittedAlphabet.Type > eExtension_Unextended)
  115. per->PermittedAlphabet.Type = eExtension_Unextended;
  116. /* we do not support complex value sets for the size */
  117. if (per->Size.Type == eExtension_Extended && per->Size.Root->Next)
  118. error(E_constraint_too_complex, NULL);
  119. }
  120. /* extract per-visible constraints from a type constraint */
  121. static void
  122. GetAllPERFromConstraints(AssignmentList_t ass,
  123. Constraint_t *constraints,
  124. Extension_e *evalue,
  125. ValueConstraintList_t *valueConstraints,
  126. ValueConstraintList_t *evalueConstraints,
  127. Extension_e *esize,
  128. ValueConstraintList_t *sizeConstraints,
  129. ValueConstraintList_t *esizeConstraints,
  130. Extension_e *epermAlpha,
  131. ValueConstraintList_t *permAlphaConstraints,
  132. ValueConstraintList_t *epermAlphaConstraints,
  133. int inPermAlpha)
  134. {
  135. ValueConstraint_t *vc, *sc, *pc;
  136. /* initialize */
  137. if (evalue)
  138. *evalue = eExtension_Unconstrained;
  139. if (valueConstraints)
  140. *valueConstraints = NULL;
  141. if (evalueConstraints)
  142. *evalueConstraints = NULL;
  143. if (esize)
  144. *esize = eExtension_Unconstrained;
  145. if (sizeConstraints)
  146. *sizeConstraints = NULL;
  147. if (esizeConstraints)
  148. *esizeConstraints = NULL;
  149. if (epermAlpha)
  150. *epermAlpha = eExtension_Unconstrained;
  151. if (permAlphaConstraints)
  152. *permAlphaConstraints = NULL;
  153. if (epermAlphaConstraints)
  154. *epermAlphaConstraints = NULL;
  155. vc = sc = pc = NULL;
  156. /* examine constraint */
  157. if (constraints) {
  158. switch (constraints->Type) {
  159. case eExtension_Unextended:
  160. /* get constraints of the extension root */
  161. GetAllPERFromElementSetSpecs(ass,
  162. constraints->Root,
  163. evalue, valueConstraints, evalueConstraints,
  164. esize, sizeConstraints, esizeConstraints,
  165. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  166. inPermAlpha);
  167. break;
  168. case eExtension_Extendable:
  169. /* get constraints of the extension root */
  170. GetAllPERFromElementSetSpecs(ass,
  171. constraints->Root,
  172. evalue, valueConstraints, evalueConstraints,
  173. esize, sizeConstraints, esizeConstraints,
  174. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  175. inPermAlpha);
  176. /* mark as extendable */
  177. if (valueConstraints && *valueConstraints &&
  178. *evalue < eExtension_Extendable)
  179. *evalue = eExtension_Extendable;
  180. if (sizeConstraints && *sizeConstraints &&
  181. *esize < eExtension_Extendable)
  182. *esize = eExtension_Extendable;
  183. if (permAlphaConstraints && *permAlphaConstraints &&
  184. *epermAlpha < eExtension_Extendable)
  185. *epermAlpha = eExtension_Extendable;
  186. break;
  187. case eExtension_Extended:
  188. /* get constraints of the extension root and of the extension */
  189. /* addition and mark them as extended */
  190. GetAllPERFromElementSetSpecs(ass,
  191. constraints->Root,
  192. evalue, valueConstraints, evalueConstraints,
  193. esize, sizeConstraints, esizeConstraints,
  194. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  195. inPermAlpha);
  196. GetAllPERFromElementSetSpecs(ass,
  197. constraints->Additional,
  198. NULL, &vc, NULL,
  199. NULL, &sc, NULL,
  200. NULL, &pc, NULL,
  201. inPermAlpha);
  202. /* extension additions given twice? */
  203. if ((vc && evalueConstraints && *evalueConstraints) ||
  204. (sc && esizeConstraints && *esizeConstraints) ||
  205. (pc && epermAlphaConstraints && *epermAlphaConstraints))
  206. error(E_constraint_too_complex, NULL);
  207. /* mark as extended */
  208. if (vc) {
  209. *evalueConstraints = vc;
  210. *evalue = eExtension_Extended;
  211. }
  212. if (sc) {
  213. *esizeConstraints = sc;
  214. *esize = eExtension_Extended;
  215. }
  216. if (pc) {
  217. *epermAlphaConstraints = pc;
  218. *epermAlpha = eExtension_Extended;
  219. }
  220. break;
  221. default:
  222. MyAbort();
  223. }
  224. }
  225. }
  226. /* get per-visible constraints from an element set spec */
  227. static void
  228. GetAllPERFromElementSetSpecs(AssignmentList_t ass,
  229. ElementSetSpec_t *element,
  230. Extension_e *evalue,
  231. ValueConstraintList_t *valueConstraints,
  232. ValueConstraintList_t *evalueConstraints,
  233. Extension_e *esize,
  234. ValueConstraintList_t *sizeConstraints,
  235. ValueConstraintList_t *esizeConstraints,
  236. Extension_e *epermAlpha,
  237. ValueConstraintList_t *permAlphaConstraints,
  238. ValueConstraintList_t *epermAlphaConstraints,
  239. int inPermAlpha)
  240. {
  241. ValueConstraint_t *vc1, *vc2, *evc1, *evc2;
  242. ValueConstraint_t *sc1, *sc2, *esc1, *esc2;
  243. ValueConstraint_t *pc1, *pc2, *epc1, *epc2;
  244. Extension_e ev1, ev2, es1, es2, ep1, ep2;
  245. /* initialize */
  246. ev1 = ev2 = es1 = es2 = ep1 = ep2 = eExtension_Unconstrained;
  247. vc1 = vc2 = evc1 = evc2 = NULL;
  248. sc1 = sc2 = esc1 = esc2 = NULL;
  249. pc1 = pc2 = epc1 = epc2 = NULL;
  250. /* examine element set spec */
  251. switch (element->Type) {
  252. case eElementSetSpec_Intersection:
  253. /* intersection: get the constraints of the sub-element set specs */
  254. /* and intersect them */
  255. GetAllPERFromElementSetSpecs(ass,
  256. element->U.Intersection.Elements1,
  257. &ev1, &vc1, &evc1,
  258. &es1, &sc1, &esc1,
  259. &ep1, &pc1, &epc1,
  260. inPermAlpha);
  261. GetAllPERFromElementSetSpecs(ass,
  262. element->U.Intersection.Elements2,
  263. &ev2, &vc2, &evc2,
  264. &es2, &sc2, &esc2,
  265. &ep2, &pc2, &epc2,
  266. inPermAlpha);
  267. IntersectPERConstraints(ass, evalue,
  268. valueConstraints, evalueConstraints,
  269. ev1, vc1, evc1, ev2, vc2, evc2);
  270. IntersectPERConstraints(ass, esize,
  271. sizeConstraints, esizeConstraints,
  272. es1, sc1, esc1, es2, sc2, esc2);
  273. IntersectPERConstraints(ass, epermAlpha,
  274. permAlphaConstraints, epermAlphaConstraints,
  275. ep1, pc1, epc1, ep2, pc2, epc2);
  276. break;
  277. case eElementSetSpec_Union:
  278. /* union: get the constraints of the sub-element set specs */
  279. /* and unite them */
  280. GetAllPERFromElementSetSpecs(ass,
  281. element->U.Union.Elements1,
  282. &ev1, &vc1, &evc1,
  283. &es1, &sc1, &esc1,
  284. &ep1, &pc1, &epc1,
  285. inPermAlpha);
  286. GetAllPERFromElementSetSpecs(ass,
  287. element->U.Union.Elements2,
  288. &ev2, &vc2, &evc2,
  289. &es2, &sc2, &esc2,
  290. &ep2, &pc2, &epc2,
  291. inPermAlpha);
  292. UnitePERConstraints(evalue,
  293. valueConstraints, evalueConstraints,
  294. ev1, vc1, evc1, ev2, vc2, evc2);
  295. UnitePERConstraints(esize,
  296. sizeConstraints, esizeConstraints,
  297. es1, sc1, esc1, es2, sc2, esc2);
  298. UnitePERConstraints(epermAlpha,
  299. permAlphaConstraints, epermAlphaConstraints,
  300. ep1, pc1, epc1, ep2, pc2, epc2);
  301. break;
  302. case eElementSetSpec_AllExcept:
  303. /* all-except: get the constraints of the sub-element set specs */
  304. /* and negate them */
  305. GetAllPERFromElementSetSpecs(ass,
  306. element->U.AllExcept.Elements,
  307. &ev1, &vc1, &evc1,
  308. &es1, &sc1, &esc1,
  309. &ep1, &pc1, &epc1,
  310. inPermAlpha);
  311. NegatePERConstraints(ass, evalue,
  312. valueConstraints, evalueConstraints,
  313. ev1, vc1, evc1);
  314. NegatePERConstraints(ass, esize,
  315. sizeConstraints, esizeConstraints,
  316. es1, sc1, esc1);
  317. NegatePERConstraints(ass, epermAlpha,
  318. permAlphaConstraints, epermAlphaConstraints,
  319. ep1, pc1, epc1);
  320. break;
  321. case eElementSetSpec_Exclusion:
  322. /* exclusion: get the constraints of the sub-element set specs */
  323. /* and substract them */
  324. GetAllPERFromElementSetSpecs(ass,
  325. element->U.Exclusion.Elements1,
  326. &ev1, &vc1, &evc1,
  327. &es1, &sc1, &esc1,
  328. &ep1, &pc1, &epc1,
  329. inPermAlpha);
  330. GetAllPERFromElementSetSpecs(ass,
  331. element->U.Exclusion.Elements2,
  332. &ev2, &vc2, &evc2,
  333. &es2, &sc2, &esc2,
  334. &ep2, &pc2, &epc2,
  335. inPermAlpha);
  336. ExcludePERConstraints(ass, evalue,
  337. valueConstraints, evalueConstraints,
  338. ev1, vc1, evc1, ev2, vc2, evc2);
  339. ExcludePERConstraints(ass, esize,
  340. sizeConstraints, esizeConstraints,
  341. es1, sc1, esc1, es2, sc2, esc2);
  342. ExcludePERConstraints(ass, epermAlpha,
  343. permAlphaConstraints, epermAlphaConstraints,
  344. ep1, pc1, epc1, ep2, pc2, epc2);
  345. break;
  346. case eElementSetSpec_SubtypeElement:
  347. /* subtype element: get the constraints of the subtype element */
  348. GetAllPERFromSubtypeElements(ass,
  349. element->U.SubtypeElement.SubtypeElement,
  350. evalue, valueConstraints, evalueConstraints,
  351. esize, sizeConstraints, esizeConstraints,
  352. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  353. inPermAlpha);
  354. break;
  355. default:
  356. MyAbort();
  357. /*NOTREACHED*/
  358. }
  359. }
  360. /* get per-visible constraints from a subtype element */
  361. static void
  362. GetAllPERFromSubtypeElements(AssignmentList_t ass,
  363. SubtypeElement_t *element,
  364. Extension_e *evalue,
  365. ValueConstraintList_t *valueConstraints,
  366. ValueConstraintList_t *evalueConstraints,
  367. Extension_e *esize,
  368. ValueConstraintList_t *sizeConstraints,
  369. ValueConstraintList_t *esizeConstraints,
  370. Extension_e *epermAlpha,
  371. ValueConstraintList_t *permAlphaConstraints,
  372. ValueConstraintList_t *epermAlphaConstraints,
  373. int inPermAlpha)
  374. {
  375. unsigned i;
  376. Value_t *v;
  377. ValueConstraint_t **p;
  378. ValueConstraint_t *vc, *evc;
  379. ValueConstraint_t *sc, *esc;
  380. Extension_e ev, es;
  381. /* examine the subtype element */
  382. switch (element->Type) {
  383. case eSubtypeElement_ValueRange:
  384. /* value range: create a value constraint containing the bounds */
  385. if (evalue)
  386. *evalue = eExtension_Unextended;
  387. if (!valueConstraints)
  388. error(E_constraint_too_complex, NULL);
  389. *valueConstraints = NewValueConstraint();
  390. (*valueConstraints)->Lower = element->U.ValueRange.Lower;
  391. (*valueConstraints)->Upper = element->U.ValueRange.Upper;
  392. break;
  393. case eSubtypeElement_SingleValue:
  394. /* single value: create a value constraint containing the element */
  395. if (evalue)
  396. *evalue = eExtension_Unextended;
  397. if (!valueConstraints)
  398. error(E_constraint_too_complex, NULL);
  399. v = GetValue(ass, element->U.SingleValue.Value);
  400. switch (GetTypeType(ass, v->Type)) {
  401. case eType_Integer:
  402. *valueConstraints = NewValueConstraint();
  403. (*valueConstraints)->Lower.Flags =
  404. (*valueConstraints)->Upper.Flags = 0;
  405. (*valueConstraints)->Lower.Value =
  406. (*valueConstraints)->Upper.Value = v;
  407. break;
  408. case eType_NumericString:
  409. case eType_PrintableString:
  410. case eType_TeletexString:
  411. case eType_T61String:
  412. case eType_VideotexString:
  413. case eType_IA5String:
  414. case eType_GraphicString:
  415. case eType_VisibleString:
  416. case eType_ISO646String:
  417. case eType_GeneralString:
  418. case eType_UniversalString:
  419. case eType_BMPString:
  420. case eType_RestrictedString:
  421. if (inPermAlpha) {
  422. /* single value of a string is used for permitted alphabet */
  423. /* the characters of the string shall be interpreted as a */
  424. /* union of the characters */
  425. p = valueConstraints;
  426. for (i = 0; i < v->U.RestrictedString.Value.length; i++) {
  427. *p = NewValueConstraint();
  428. (*p)->Lower.Flags = (*p)->Upper.Flags = 0;
  429. (*p)->Lower.Value = (*p)->Upper.Value =
  430. NewValue(ass, GetType(ass, v->Type));
  431. (*p)->Lower.Value->U.RestrictedString.Value.length = 1;
  432. (*p)->Lower.Value->U.RestrictedString.Value.value =
  433. (char32_t *)malloc(sizeof(char32_t));
  434. (*p)->Lower.Value->U.RestrictedString.Value.value[0] =
  435. v->U.RestrictedString.Value.value[i];
  436. p = &(*p)->Next;
  437. }
  438. *p = 0;
  439. }
  440. break;
  441. default:
  442. /* value element of other types may be ignored for per */
  443. break;
  444. }
  445. break;
  446. case eSubtypeElement_Size:
  447. /* size: get the size constraint */
  448. if (!sizeConstraints || inPermAlpha)
  449. error(E_constraint_too_complex, NULL);
  450. GetAllPERFromConstraints(ass,
  451. element->U.Size.Constraints,
  452. esize, sizeConstraints, esizeConstraints,
  453. NULL, NULL, NULL,
  454. NULL, NULL, NULL,
  455. inPermAlpha);
  456. break;
  457. case eSubtypeElement_PermittedAlphabet:
  458. /* permitted alphabet: get the permitted alphabet constraint */
  459. if (!permAlphaConstraints || inPermAlpha)
  460. error(E_constraint_too_complex, NULL);
  461. GetAllPERFromConstraints(ass,
  462. element->U.PermittedAlphabet.Constraints,
  463. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  464. NULL, NULL, NULL,
  465. NULL, NULL, NULL,
  466. 1);
  467. break;
  468. case eSubtypeElement_ContainedSubtype:
  469. /* contained subtype: */
  470. if (inPermAlpha) {
  471. /* get the permitted alphabet of the referenced type */
  472. GetAllPERFromConstraints(ass, GetType(ass,
  473. element->U.ContainedSubtype.Type)->Constraints,
  474. &ev, &vc, &evc,
  475. &es, &sc, &esc,
  476. evalue, valueConstraints, evalueConstraints,
  477. inPermAlpha);
  478. /* drop extensions for contained subtype constraints */
  479. if (evalue && *evalue > eExtension_Unextended) {
  480. *evalue = eExtension_Unextended;
  481. if (evalueConstraints)
  482. *evalueConstraints = NULL;
  483. }
  484. } else {
  485. /* get the constraints of the referenced type */
  486. GetAllPERFromConstraints(ass, GetType(ass,
  487. element->U.ContainedSubtype.Type)->Constraints,
  488. evalue, valueConstraints, evalueConstraints,
  489. esize, sizeConstraints, esizeConstraints,
  490. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  491. inPermAlpha);
  492. /* drop extensions for contained subtype constraints */
  493. if (evalue && *evalue > eExtension_Unextended) {
  494. *evalue = eExtension_Unextended;
  495. if (evalueConstraints)
  496. *evalueConstraints = NULL;
  497. }
  498. if (esize && *esize > eExtension_Unextended) {
  499. *esize = eExtension_Unextended;
  500. if (esizeConstraints)
  501. *esizeConstraints = NULL;
  502. }
  503. if (epermAlpha && *epermAlpha > eExtension_Unextended) {
  504. *epermAlpha = eExtension_Unextended;
  505. if (epermAlphaConstraints)
  506. *epermAlphaConstraints = NULL;
  507. }
  508. }
  509. break;
  510. case eSubtypeElement_Type:
  511. case eSubtypeElement_SingleType:
  512. case eSubtypeElement_FullSpecification:
  513. case eSubtypeElement_PartialSpecification:
  514. /* not PER-visible constraints */
  515. break;
  516. case eSubtypeElement_ElementSetSpec:
  517. /* get the constraints of the element set spec */
  518. GetAllPERFromElementSetSpecs(ass,
  519. element->U.ElementSetSpec.ElementSetSpec,
  520. evalue, valueConstraints, evalueConstraints,
  521. esize, sizeConstraints, esizeConstraints,
  522. epermAlpha, permAlphaConstraints, epermAlphaConstraints,
  523. inPermAlpha);
  524. break;
  525. default:
  526. MyAbort();
  527. }
  528. }
  529. /* intersect two value constraints */
  530. static void
  531. IntersectValueConstraints(AssignmentList_t ass,
  532. ValueConstraintList_t *result,
  533. ValueConstraintList_t val1, ValueConstraintList_t val2)
  534. {
  535. ValueConstraint_t *v1, *v2;
  536. EndPoint_t lo, up;
  537. /*XXX may be optimized for better results */
  538. /* unite intersection of each pair of value ranges */
  539. for (v1 = val1; v1; v1 = v1->Next) {
  540. for (v2 = val2; v2; v2 = v2->Next) {
  541. /* get bigger lower bound */
  542. if (CmpLowerEndPoint(ass, &v1->Lower, &v2->Lower) >= 0)
  543. lo = v1->Lower;
  544. else
  545. lo = v2->Lower;
  546. /* get smaller upper bound */
  547. if (CmpUpperEndPoint(ass, &v1->Upper, &v2->Upper) <= 0)
  548. up = v1->Upper;
  549. else
  550. up = v2->Upper;
  551. /* add intersection if it is not empty */
  552. if ((lo.Flags & eEndPoint_Min) ||
  553. (up.Flags & eEndPoint_Max) ||
  554. CmpLowerUpperEndPoint(ass, &lo, &up) <= 0) {
  555. *result = NewValueConstraint();
  556. (*result)->Lower = lo;
  557. (*result)->Upper = up;
  558. result = &(*result)->Next;
  559. }
  560. }
  561. }
  562. *result = NULL;
  563. }
  564. /* unite two value constraints */
  565. static void
  566. UniteValueConstraints(ValueConstraintList_t *result,
  567. ValueConstraintList_t val1, ValueConstraintList_t val2)
  568. {
  569. /*XXX may be optimized for better results */
  570. for (; val1; val1 = val1->Next) {
  571. *result = NewValueConstraint();
  572. (*result)->Lower = val1->Lower;
  573. (*result)->Upper = val1->Upper;
  574. result = &(*result)->Next;
  575. }
  576. for (; val2; val2 = val2->Next) {
  577. *result = NewValueConstraint();
  578. (*result)->Lower = val2->Lower;
  579. (*result)->Upper = val2->Upper;
  580. result = &(*result)->Next;
  581. }
  582. *result = NULL;
  583. }
  584. /* negate a value constraint */
  585. static void
  586. NegateValueConstraints(AssignmentList_t ass, ValueConstraintList_t *result,
  587. ValueConstraintList_t val)
  588. {
  589. ValueConstraint_t *vc, *lvc, *uvc;
  590. EndPoint_t *lower, *upper;
  591. *result = NewValueConstraint();
  592. (*result)->Lower.Flags = eEndPoint_Min;
  593. (*result)->Upper.Flags = eEndPoint_Max;
  594. for (; val; val = val->Next) {
  595. lower = &val->Lower;
  596. upper = &val->Upper;
  597. if (!(upper->Flags & eEndPoint_Max)) {
  598. uvc = NewValueConstraint();
  599. uvc->Lower.Flags = (upper->Flags & eEndPoint_Open) ^ eEndPoint_Open;
  600. uvc->Lower.Value = upper->Value;
  601. uvc->Upper.Flags = eEndPoint_Max;
  602. } else {
  603. uvc = NULL;
  604. }
  605. if (!(lower->Flags & eEndPoint_Min)) {
  606. lvc = NewValueConstraint();
  607. lvc->Lower.Flags = eEndPoint_Min;
  608. lvc->Upper.Flags = (lower->Flags & eEndPoint_Open) ^ eEndPoint_Open;
  609. lvc->Upper.Value = lower->Value;
  610. } else {
  611. lvc = NULL;
  612. }
  613. if (!lvc && !uvc) {
  614. *result = NULL;
  615. return;
  616. }
  617. if (lvc) {
  618. vc = lvc;
  619. if (uvc)
  620. vc->Next = uvc;
  621. } else {
  622. vc = uvc;
  623. }
  624. IntersectValueConstraints(ass, result, *result, vc);
  625. }
  626. }
  627. /* substract two value constraints */
  628. static void
  629. ExcludeValueConstraints(AssignmentList_t ass, ValueConstraintList_t *result,
  630. ValueConstraintList_t val1, ValueConstraintList_t val2)
  631. {
  632. ValueConstraint_t *notval2;
  633. NegateValueConstraints(ass, &notval2, val2);
  634. IntersectValueConstraints(ass, result, val1, notval2);
  635. }
  636. /* intersect two constraints */
  637. static void
  638. IntersectPERConstraints(AssignmentList_t ass,
  639. Extension_e *rtype,
  640. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  641. Extension_e type1,
  642. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  643. Extension_e type2,
  644. ValueConstraintList_t val2, ValueConstraintList_t eval2)
  645. {
  646. if (type1 == eExtension_Unconstrained) {
  647. if (rtype)
  648. *rtype = type2;
  649. if (result)
  650. *result = val2;
  651. if (eresult)
  652. *eresult = eval2;
  653. } else if (type2 == eExtension_Unconstrained) {
  654. if (rtype)
  655. *rtype = type1;
  656. if (result)
  657. *result = val1;
  658. if (eresult)
  659. *eresult = eval1;
  660. } else {
  661. if (rtype)
  662. *rtype = type1 < type2 ? type1 : type2;
  663. if (result)
  664. IntersectValueConstraints(ass, result, val1, val2);
  665. if (rtype && *rtype == eExtension_Extended && eresult)
  666. IntersectValueConstraints(ass, eresult, eval1, eval2);
  667. }
  668. }
  669. /* unite two constraints */
  670. static void
  671. UnitePERConstraints(Extension_e *rtype,
  672. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  673. Extension_e type1,
  674. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  675. Extension_e type2,
  676. ValueConstraintList_t val2, ValueConstraintList_t eval2)
  677. {
  678. if (type1 == eExtension_Unconstrained) {
  679. if (rtype)
  680. *rtype = type2;
  681. if (result)
  682. *result = val2;
  683. if (eresult)
  684. *eresult = eval2;
  685. } else if (type2 == eExtension_Unconstrained) {
  686. if (rtype)
  687. *rtype = type1;
  688. if (result)
  689. *result = val1;
  690. if (eresult)
  691. *eresult = eval1;
  692. } else {
  693. if (rtype)
  694. *rtype = type1 > type2 ? type1 : type2;
  695. if (result)
  696. UniteValueConstraints(result, val1, val2);
  697. if (rtype && *rtype == eExtension_Extended && eresult)
  698. UniteValueConstraints(eresult,
  699. eval1 ? eval1 : val1, eval2 ? eval2 : val2);
  700. }
  701. }
  702. /* negate a constraint */
  703. static void
  704. NegatePERConstraints(AssignmentList_t ass,
  705. Extension_e *rtype,
  706. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  707. Extension_e type1,
  708. ValueConstraintList_t val1, ValueConstraintList_t eval1)
  709. {
  710. if (rtype)
  711. *rtype = type1;
  712. if (result)
  713. NegateValueConstraints(ass, result, val1);
  714. if (rtype && *rtype == eExtension_Extended && eresult)
  715. NegateValueConstraints(ass, eresult, eval1);
  716. }
  717. /* substract two constraints */
  718. static void
  719. ExcludePERConstraints(AssignmentList_t ass,
  720. Extension_e *rtype,
  721. ValueConstraintList_t *result, ValueConstraintList_t *eresult,
  722. Extension_e type1,
  723. ValueConstraintList_t val1, ValueConstraintList_t eval1,
  724. Extension_e type2,
  725. ValueConstraintList_t val2, ValueConstraintList_t eval2)
  726. {
  727. if (type1 == eExtension_Unconstrained) {
  728. if (rtype)
  729. *rtype = type2;
  730. if (result)
  731. *result = val2;
  732. if (eresult)
  733. *eresult = eval2;
  734. } else if (type2 == eExtension_Unconstrained) {
  735. if (rtype)
  736. *rtype = type1;
  737. if (result)
  738. *result = val1;
  739. if (eresult)
  740. *eresult = eval1;
  741. } else {
  742. if (rtype)
  743. *rtype = type1 < type2 ? type1 : type2;
  744. if (result)
  745. ExcludeValueConstraints(ass, result, val1, val2);
  746. if (rtype && *rtype == eExtension_Extended && eresult)
  747. ExcludeValueConstraints(ass, eresult, eval1, eval2);
  748. }
  749. }
  750. /* compare two value constraints */
  751. static int
  752. CmpValueConstraints(const void *v1, const void *v2, void *ctx)
  753. {
  754. ValueConstraint_t *vc1 = (ValueConstraint_t *)v1;
  755. ValueConstraint_t *vc2 = (ValueConstraint_t *)v2;
  756. Assignment_t *ass = (Assignment_t *)ctx;
  757. int r;
  758. r = CmpLowerEndPoint(ass, &vc1->Lower, &vc2->Lower);
  759. if (r)
  760. return r;
  761. return CmpUpperEndPoint(ass, &vc1->Upper, &vc2->Upper);
  762. }
  763. /* reduce a value constraint by concatenation of value ranges (if possible) */
  764. void
  765. ReduceValueConstraints(AssignmentList_t ass, ValueConstraintList_t *valueConstraints)
  766. {
  767. ValueConstraint_t *p;
  768. EndPoint_t lower, upper, lower2, upper2;
  769. int flg;
  770. if (!*valueConstraints)
  771. return;
  772. qsortSL((void **)valueConstraints, offsetof(ValueConstraint_t, Next),
  773. CmpValueConstraints, ass);
  774. flg = 0;
  775. for (p = *valueConstraints; p; p = p->Next) {
  776. if (flg) {
  777. lower2 = p->Lower;
  778. upper2 = p->Upper;
  779. if (CheckEndPointsJoin(ass, &upper, &lower2)) {
  780. upper = upper2;
  781. continue;
  782. }
  783. *valueConstraints = NewValueConstraint();
  784. /*LINTED*/
  785. (*valueConstraints)->Lower = lower;
  786. (*valueConstraints)->Upper = upper;
  787. valueConstraints = &(*valueConstraints)->Next;
  788. }
  789. lower = p->Lower;
  790. upper = p->Upper;
  791. flg = 1;
  792. }
  793. *valueConstraints = NewValueConstraint();
  794. (*valueConstraints)->Lower = lower;
  795. (*valueConstraints)->Upper = upper;
  796. (*valueConstraints)->Next = NULL;
  797. }
  798. /* count the values of a value constraint */
  799. int
  800. CountValues(AssignmentList_t ass, ValueConstraintList_t v, intx_t *n) {
  801. intx_t ix;
  802. intx_setuint32(n, 0);
  803. for (; v; v = v->Next) {
  804. if ((v->Lower.Flags & eEndPoint_Min) ||
  805. (v->Upper.Flags & eEndPoint_Max))
  806. return 0;
  807. if (!SubstractValues(ass, &ix, v->Lower.Value, v->Upper.Value))
  808. return 0;
  809. intx_add(n, n, &ix);
  810. intx_inc(n);
  811. }
  812. return 1;
  813. }
  814. /* check if the value constraint of a value is empty */
  815. int
  816. HasNoValueConstraint(ValueConstraintList_t v)
  817. {
  818. EndPoint_t *p1, *p2;
  819. if (!v)
  820. return 1;
  821. if (!v->Next) {
  822. p1 = &v->Lower;
  823. p2 = &v->Upper;
  824. if ((p1->Flags & eEndPoint_Min) &&
  825. (p2->Flags & eEndPoint_Max)) {
  826. return 1;
  827. }
  828. }
  829. return 0;
  830. }
  831. /* check if the value constraint of a size is empty */
  832. int
  833. HasNoSizeConstraint(AssignmentList_t ass, ValueConstraintList_t v)
  834. {
  835. EndPoint_t *p1, *p2;
  836. if (!v)
  837. return 1;
  838. if (!v->Next) {
  839. p1 = &v->Lower;
  840. p2 = &v->Upper;
  841. if (!(p1->Flags & eEndPoint_Min) &&
  842. !intx_cmp(&GetValue(ass, p1->Value)->U.Integer.Value,
  843. &intx_0) && (p2->Flags & eEndPoint_Max)) {
  844. return 1;
  845. }
  846. }
  847. return 0;
  848. }
  849. /* check if the value constraint of a permitted alphabet is empty */
  850. int
  851. HasNoPermittedAlphabetConstraint(AssignmentList_t ass, ValueConstraintList_t v)
  852. {
  853. EndPoint_t *p1, *p2;
  854. if (!v)
  855. return 1;
  856. if (!v->Next) {
  857. p1 = &v->Lower;
  858. p2 = &v->Upper;
  859. if (!(p1->Flags & eEndPoint_Min) &&
  860. GetValue(ass, p1->Value)->U.RestrictedString.Value.length == 1 &&
  861. GetValue(ass, p1->Value)->U.RestrictedString.Value.value[0] == 0 &&
  862. !(p2->Flags & eEndPoint_Max) &&
  863. GetValue(ass, p2->Value)->U.RestrictedString.Value.length == 1 &&
  864. GetValue(ass, p2->Value)->U.RestrictedString.Value.value[0]
  865. == 0xffffffff) {
  866. return 1;
  867. }
  868. }
  869. return 0;
  870. }
  871. /* get the fixed identification */
  872. /* this is needed for embedded pdv/character string types who are encoded */
  873. /* in an "optimized" manner if the identification is fixed */
  874. NamedValue_t *
  875. GetFixedIdentification(AssignmentList_t ass, Constraint_t *constraints)
  876. {
  877. if (!constraints)
  878. return NULL;
  879. return GetFixedIdentificationFromElementSetSpec(ass, constraints->Root);
  880. }
  881. /* get the fixed identification from an element set spec */
  882. static NamedValue_t *
  883. GetFixedIdentificationFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements)
  884. {
  885. NamedConstraint_t *named;
  886. NamedValue_t *nv1, *nv2;
  887. SubtypeElement_t *se;
  888. if (!elements)
  889. return NULL;
  890. switch (elements->Type) {
  891. case eElementSetSpec_AllExcept:
  892. return NULL;
  893. case eElementSetSpec_Union:
  894. nv1 = GetFixedIdentificationFromElementSetSpec(ass,
  895. elements->U.Union.Elements1);
  896. nv2 = GetFixedIdentificationFromElementSetSpec(ass,
  897. elements->U.Union.Elements2);
  898. return nv1 && nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  899. case eElementSetSpec_Intersection:
  900. nv1 = GetFixedIdentificationFromElementSetSpec(ass,
  901. elements->U.Union.Elements1);
  902. nv2 = GetFixedIdentificationFromElementSetSpec(ass,
  903. elements->U.Union.Elements2);
  904. return nv1 ? nv1 : nv2; /*XXX conflicts ignored */
  905. case eElementSetSpec_Exclusion:
  906. nv1 = GetFixedIdentificationFromElementSetSpec(ass,
  907. elements->U.Exclusion.Elements1);
  908. nv2 = GetFixedIdentificationFromElementSetSpec(ass,
  909. elements->U.Exclusion.Elements2);
  910. return nv1 && !nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  911. case eElementSetSpec_SubtypeElement:
  912. se = elements->U.SubtypeElement.SubtypeElement;
  913. switch (se->Type) {
  914. case eSubtypeElement_FullSpecification:
  915. case eSubtypeElement_PartialSpecification:
  916. for (named = se->U.FP.NamedConstraints; named;
  917. named = named->Next) {
  918. if (!strcmp(named->Identifier, "identification"))
  919. return GetFixedSyntaxes(ass, named->Constraint);
  920. }
  921. break;
  922. }
  923. return NULL;
  924. default:
  925. MyAbort();
  926. /*NOTREACHED*/
  927. }
  928. return NULL;
  929. }
  930. /* get the fixed syntaxes from a constraint */
  931. static NamedValue_t *
  932. GetFixedSyntaxes(AssignmentList_t ass, Constraint_t *constraints)
  933. {
  934. if (!constraints)
  935. return NULL;
  936. return GetFixedSyntaxesFromElementSetSpec(ass, constraints->Root);
  937. }
  938. /* get the fixed syntaxes from an element set spec */
  939. static NamedValue_t *
  940. GetFixedSyntaxesFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements)
  941. {
  942. int present, absent, bit;
  943. Constraint_t *presentconstraints[6];
  944. NamedConstraint_t *named;
  945. NamedValue_t *nv1, *nv2;
  946. SubtypeElement_t *se;
  947. if (!elements)
  948. return NULL;
  949. switch (elements->Type) {
  950. case eElementSetSpec_AllExcept:
  951. return NULL;
  952. case eElementSetSpec_Union:
  953. nv1 = GetFixedSyntaxesFromElementSetSpec(ass,
  954. elements->U.Union.Elements1);
  955. nv2 = GetFixedSyntaxesFromElementSetSpec(ass,
  956. elements->U.Union.Elements2);
  957. return nv1 && nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  958. case eElementSetSpec_Intersection:
  959. nv1 = GetFixedSyntaxesFromElementSetSpec(ass,
  960. elements->U.Intersection.Elements1);
  961. nv2 = GetFixedSyntaxesFromElementSetSpec(ass,
  962. elements->U.Intersection.Elements2);
  963. return nv1 ? nv1 : nv2; /*XXX conflicts ignored */
  964. case eElementSetSpec_Exclusion:
  965. nv1 = GetFixedSyntaxesFromElementSetSpec(ass,
  966. elements->U.Exclusion.Elements1);
  967. nv2 = GetFixedSyntaxesFromElementSetSpec(ass,
  968. elements->U.Exclusion.Elements2);
  969. return nv1 && !nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  970. case eElementSetSpec_SubtypeElement:
  971. se = elements->U.SubtypeElement.SubtypeElement;
  972. switch (se->Type) {
  973. case eSubtypeElement_FullSpecification:
  974. case eSubtypeElement_PartialSpecification:
  975. present = absent = 0;
  976. for (named = se->U.FP.NamedConstraints; named;
  977. named = named->Next) {
  978. if (!strcmp(named->Identifier, "syntaxes")) {
  979. bit = 0;
  980. } else if (!strcmp(named->Identifier, "syntax")) {
  981. bit = 1;
  982. } else if (!strcmp(named->Identifier,
  983. "presentation-context-id")) {
  984. bit = 2;
  985. } else if (!strcmp(named->Identifier, "context-negotiation")) {
  986. bit = 3;
  987. } else if (!strcmp(named->Identifier, "transfer-syntax")) {
  988. bit = 4;
  989. } else if (!strcmp(named->Identifier, "fixed")) {
  990. bit = 5;
  991. }
  992. switch (named->Presence) {
  993. case ePresence_Normal:
  994. if (se->Type == eSubtypeElement_PartialSpecification)
  995. break;
  996. /*FALLTHROUGH*/
  997. case ePresence_Present:
  998. present |= (1 << bit);
  999. presentconstraints[bit] = named->Constraint;
  1000. break;
  1001. case ePresence_Absent:
  1002. absent |= (1 << bit);
  1003. break;
  1004. case ePresence_Optional:
  1005. break;
  1006. }
  1007. }
  1008. if (se->Type == eSubtypeElement_FullSpecification)
  1009. absent |= (0x3f & ~present);
  1010. if (present == 0x20 && absent == 0x1f)
  1011. return NewNamedValue("fixed", Builtin_Value_Null);
  1012. if (present == 0x01 && absent == 0x3e)
  1013. return GetFixedAbstractAndTransfer(ass, presentconstraints[0]);
  1014. return NULL;
  1015. }
  1016. return NULL;
  1017. default:
  1018. MyAbort();
  1019. /*NOTREACHED*/
  1020. }
  1021. return NULL;
  1022. }
  1023. /* get the fixed abstract and transfer from a constraint */
  1024. static NamedValue_t *
  1025. GetFixedAbstractAndTransfer(AssignmentList_t ass, Constraint_t *constraints)
  1026. {
  1027. if (!constraints)
  1028. return NULL;
  1029. return GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1030. constraints->Root);
  1031. }
  1032. /* get the fixed abstract and transfer from an element set spec */
  1033. static NamedValue_t *
  1034. GetFixedAbstractAndTransferFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elements)
  1035. {
  1036. NamedValue_t *nv1, *nv2;
  1037. SubtypeElement_t *se;
  1038. if (!elements)
  1039. return NULL;
  1040. switch (elements->Type) {
  1041. case eElementSetSpec_AllExcept:
  1042. return NULL;
  1043. case eElementSetSpec_Union:
  1044. nv1 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1045. elements->U.Union.Elements1);
  1046. nv2 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1047. elements->U.Union.Elements2);
  1048. return nv1 && nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  1049. case eElementSetSpec_Intersection:
  1050. nv1 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1051. elements->U.Intersection.Elements1);
  1052. nv2 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1053. elements->U.Intersection.Elements2);
  1054. return nv1 ? nv1 : nv2; /*XXX conflicts ignored */
  1055. case eElementSetSpec_Exclusion:
  1056. nv1 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1057. elements->U.Exclusion.Elements1);
  1058. nv2 = GetFixedAbstractAndTransferFromElementSetSpec(ass,
  1059. elements->U.Exclusion.Elements2);
  1060. return nv1 && !nv2 ? nv1 : NULL; /*XXX conflicts ignored */
  1061. case eElementSetSpec_SubtypeElement:
  1062. se = elements->U.SubtypeElement.SubtypeElement;
  1063. switch (se->Type) {
  1064. case eSubtypeElement_SingleValue:
  1065. return NewNamedValue("syntaxes", se->U.SingleValue.Value);
  1066. }
  1067. return NULL;
  1068. default:
  1069. MyAbort();
  1070. /*NOTREACHED*/
  1071. }
  1072. return NULL;
  1073. }