constr_SET.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. /*
  2. * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
  3. * All rights reserved.
  4. * Redistribution and modifications are permitted subject to BSD license.
  5. */
  6. #include <asn_internal.h>
  7. #include <constr_SET.h>
  8. /* Check that all the mandatory members are present */
  9. static int _SET_is_populated(const asn_TYPE_descriptor_t *td, const void *st);
  10. /*
  11. * Number of bytes left for this structure.
  12. * (ctx->left) indicates the number of bytes _transferred_ for the structure.
  13. * (size) contains the number of bytes in the buffer passed.
  14. */
  15. #define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
  16. /*
  17. * If the subprocessor function returns with an indication that it wants
  18. * more data, it may well be a fatal decoding problem, because the
  19. * size is constrained by the <TLV>'s L, even if the buffer size allows
  20. * reading more data.
  21. * For example, consider the buffer containing the following TLVs:
  22. * <T:5><L:1><V> <T:6>...
  23. * The TLV length clearly indicates that one byte is expected in V, but
  24. * if the V processor returns with "want more data" even if the buffer
  25. * contains way more data than the V processor have seen.
  26. */
  27. #define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
  28. /*
  29. * This macro "eats" the part of the buffer which is definitely "consumed",
  30. * i.e. was correctly converted into local representation or rightfully skipped.
  31. */
  32. #undef ADVANCE
  33. #define ADVANCE(num_bytes) do { \
  34. size_t num = num_bytes; \
  35. ptr = ((const char *)ptr) + num;\
  36. size -= num; \
  37. if(ctx->left >= 0) \
  38. ctx->left -= num; \
  39. consumed_myself += num; \
  40. } while(0)
  41. /*
  42. * Switch to the next phase of parsing.
  43. */
  44. #undef NEXT_PHASE
  45. #define NEXT_PHASE(ctx) do { \
  46. ctx->phase++; \
  47. ctx->step = 0; \
  48. } while(0)
  49. /*
  50. * Return a standardized complex structure.
  51. */
  52. #undef RETURN
  53. #define RETURN(_code) do { \
  54. rval.code = _code; \
  55. rval.consumed = consumed_myself;\
  56. return rval; \
  57. } while(0)
  58. /*
  59. * Tags are canonically sorted in the tag2element map.
  60. */
  61. static int
  62. _t2e_cmp(const void *ap, const void *bp) {
  63. const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
  64. const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
  65. int a_class = BER_TAG_CLASS(a->el_tag);
  66. int b_class = BER_TAG_CLASS(b->el_tag);
  67. if(a_class == b_class) {
  68. ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
  69. ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
  70. if(a_value == b_value)
  71. return 0;
  72. else if(a_value < b_value)
  73. return -1;
  74. else
  75. return 1;
  76. } else if(a_class < b_class) {
  77. return -1;
  78. } else {
  79. return 1;
  80. }
  81. }
  82. /*
  83. * The decoder of the SET type.
  84. */
  85. asn_dec_rval_t
  86. SET_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
  87. const asn_TYPE_descriptor_t *td, void **struct_ptr,
  88. const void *ptr, size_t size, int tag_mode) {
  89. /*
  90. * Bring closer parts of structure description.
  91. */
  92. const asn_SET_specifics_t *specs = (const asn_SET_specifics_t *)td->specifics;
  93. const asn_TYPE_member_t *elements = td->elements;
  94. /*
  95. * Parts of the structure being constructed.
  96. */
  97. void *st = *struct_ptr; /* Target structure. */
  98. asn_struct_ctx_t *ctx; /* Decoder context */
  99. ber_tlv_tag_t tlv_tag; /* T from TLV */
  100. asn_dec_rval_t rval; /* Return code from subparsers */
  101. ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
  102. size_t edx; /* SET element's index */
  103. ASN_DEBUG("Decoding %s as SET", td->name);
  104. if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
  105. ASN__DECODE_FAILED;
  106. /*
  107. * Create the target structure if it is not present already.
  108. */
  109. if(st == 0) {
  110. st = *struct_ptr = CALLOC(1, specs->struct_size);
  111. if(st == 0) {
  112. RETURN(RC_FAIL);
  113. }
  114. }
  115. /*
  116. * Restore parsing context.
  117. */
  118. ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
  119. /*
  120. * Start to parse where left previously
  121. */
  122. switch(ctx->phase) {
  123. case 0:
  124. /*
  125. * PHASE 0.
  126. * Check that the set of tags associated with given structure
  127. * perfectly fits our expectations.
  128. */
  129. rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
  130. tag_mode, 1, &ctx->left, 0);
  131. if(rval.code != RC_OK) {
  132. ASN_DEBUG("%s tagging check failed: %d",
  133. td->name, rval.code);
  134. return rval;
  135. }
  136. if(ctx->left >= 0)
  137. ctx->left += rval.consumed; /* ?Substracted below! */
  138. ADVANCE(rval.consumed);
  139. NEXT_PHASE(ctx);
  140. ASN_DEBUG("Structure advertised %ld bytes, "
  141. "buffer contains %ld", (long)ctx->left, (long)size);
  142. /* Fall through */
  143. case 1:
  144. /*
  145. * PHASE 1.
  146. * From the place where we've left it previously,
  147. * try to decode the next member from the list of
  148. * this structure's elements.
  149. * Note that elements in BER may arrive out of
  150. * order, yet DER mandates that they shall arive in the
  151. * canonical order of their tags. So, there is a room
  152. * for optimization.
  153. */
  154. for(;; ctx->step = 0) {
  155. const asn_TYPE_tag2member_t *t2m;
  156. asn_TYPE_tag2member_t key;
  157. void *memb_ptr; /* Pointer to the member */
  158. void **memb_ptr2; /* Pointer to that pointer */
  159. ssize_t tag_len; /* Length of TLV's T */
  160. if(ctx->step & 1) {
  161. edx = ctx->step >> 1;
  162. goto microphase2;
  163. }
  164. /*
  165. * MICROPHASE 1: Synchronize decoding.
  166. */
  167. if(ctx->left == 0)
  168. /*
  169. * No more things to decode.
  170. * Exit out of here and check whether all mandatory
  171. * elements have been received (in the next phase).
  172. */
  173. break;
  174. /*
  175. * Fetch the T from TLV.
  176. */
  177. tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
  178. switch(tag_len) {
  179. case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
  180. /* Fall through */
  181. case -1: RETURN(RC_FAIL);
  182. }
  183. if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
  184. if(LEFT < 2) {
  185. if(SIZE_VIOLATION)
  186. RETURN(RC_FAIL);
  187. else
  188. RETURN(RC_WMORE);
  189. } else if(((const uint8_t *)ptr)[1] == 0) {
  190. /*
  191. * Found the terminator of the
  192. * indefinite length structure.
  193. * Invoke the generic finalization function.
  194. */
  195. goto phase3;
  196. }
  197. }
  198. key.el_tag = tlv_tag;
  199. t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
  200. specs->tag2el, specs->tag2el_count,
  201. sizeof(specs->tag2el[0]), _t2e_cmp);
  202. if(t2m) {
  203. /*
  204. * Found the element corresponding to the tag.
  205. */
  206. edx = t2m->el_no;
  207. ctx->step = (edx << 1) + 1;
  208. ASN_DEBUG("Got tag %s (%s), edx %" ASN_PRI_SSIZE "",
  209. ber_tlv_tag_string(tlv_tag), td->name, edx);
  210. } else if(specs->extensible == 0) {
  211. ASN_DEBUG("Unexpected tag %s "
  212. "in non-extensible SET %s",
  213. ber_tlv_tag_string(tlv_tag), td->name);
  214. RETURN(RC_FAIL);
  215. } else {
  216. /* Skip this tag */
  217. ssize_t skip;
  218. ASN_DEBUG("Skipping unknown tag %s",
  219. ber_tlv_tag_string(tlv_tag));
  220. skip = ber_skip_length(opt_codec_ctx,
  221. BER_TLV_CONSTRUCTED(ptr),
  222. (const char *)ptr + tag_len, LEFT - tag_len);
  223. switch(skip) {
  224. case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
  225. /* Fall through */
  226. case -1: RETURN(RC_FAIL);
  227. }
  228. ADVANCE(skip + tag_len);
  229. continue; /* Try again with the next tag */
  230. }
  231. /*
  232. * MICROPHASE 2: Invoke the member-specific decoder.
  233. */
  234. microphase2:
  235. /*
  236. * Check for duplications: must not overwrite
  237. * already decoded elements.
  238. */
  239. if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, edx)) {
  240. ASN_DEBUG("SET %s: Duplicate element %s (%" ASN_PRI_SSIZE ")",
  241. td->name, elements[edx].name, edx);
  242. RETURN(RC_FAIL);
  243. }
  244. /*
  245. * Compute the position of the member inside a structure,
  246. * and also a type of containment (it may be contained
  247. * as pointer or using inline inclusion).
  248. */
  249. if(elements[edx].flags & ATF_POINTER) {
  250. /* Member is a pointer to another structure */
  251. memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
  252. } else {
  253. /*
  254. * A pointer to a pointer
  255. * holding the start of the structure
  256. */
  257. memb_ptr = (char *)st + elements[edx].memb_offset;
  258. memb_ptr2 = &memb_ptr;
  259. }
  260. /*
  261. * Invoke the member fetch routine according to member's type
  262. */
  263. rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
  264. elements[edx].type,
  265. memb_ptr2, ptr, LEFT,
  266. elements[edx].tag_mode);
  267. switch(rval.code) {
  268. case RC_OK:
  269. ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx);
  270. break;
  271. case RC_WMORE: /* More data expected */
  272. if(!SIZE_VIOLATION) {
  273. ADVANCE(rval.consumed);
  274. RETURN(RC_WMORE);
  275. }
  276. /* Fall through */
  277. case RC_FAIL: /* Fatal error */
  278. RETURN(RC_FAIL);
  279. } /* switch(rval) */
  280. ADVANCE(rval.consumed);
  281. } /* for(all structure members) */
  282. phase3:
  283. ctx->phase = 3;
  284. /* Fall through */
  285. case 3:
  286. case 4: /* Only 00 is expected */
  287. ASN_DEBUG("SET %s Leftover: %ld, size = %ld",
  288. td->name, (long)ctx->left, (long)size);
  289. /*
  290. * Skip everything until the end of the SET.
  291. */
  292. while(ctx->left) {
  293. ssize_t tl, ll;
  294. tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
  295. switch(tl) {
  296. case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
  297. /* Fall through */
  298. case -1: RETURN(RC_FAIL);
  299. }
  300. /*
  301. * If expected <0><0>...
  302. */
  303. if(ctx->left < 0
  304. && ((const uint8_t *)ptr)[0] == 0) {
  305. if(LEFT < 2) {
  306. if(SIZE_VIOLATION)
  307. RETURN(RC_FAIL);
  308. else
  309. RETURN(RC_WMORE);
  310. } else if(((const uint8_t *)ptr)[1] == 0) {
  311. /*
  312. * Correctly finished with <0><0>.
  313. */
  314. ADVANCE(2);
  315. ctx->left++;
  316. ctx->phase = 4;
  317. continue;
  318. }
  319. }
  320. if(specs->extensible == 0 || ctx->phase == 4) {
  321. ASN_DEBUG("Unexpected continuation "
  322. "of a non-extensible type %s "
  323. "(ptr=%02x)",
  324. td->name, *(const uint8_t *)ptr);
  325. RETURN(RC_FAIL);
  326. }
  327. ll = ber_skip_length(opt_codec_ctx,
  328. BER_TLV_CONSTRUCTED(ptr),
  329. (const char *)ptr + tl, LEFT - tl);
  330. switch(ll) {
  331. case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
  332. /* Fall through */
  333. case -1: RETURN(RC_FAIL);
  334. }
  335. ADVANCE(tl + ll);
  336. }
  337. ctx->phase = 5;
  338. /* Fall through */
  339. case 5:
  340. /* Check that all mandatory elements are present. */
  341. if(!_SET_is_populated(td, st))
  342. RETURN(RC_FAIL);
  343. NEXT_PHASE(ctx);
  344. }
  345. RETURN(RC_OK);
  346. }
  347. static int
  348. _SET_is_populated(const asn_TYPE_descriptor_t *td, const void *st) {
  349. const asn_SET_specifics_t *specs = (const asn_SET_specifics_t *)td->specifics;
  350. size_t edx;
  351. /*
  352. * Check that all mandatory elements are present.
  353. */
  354. for(edx = 0; edx < td->elements_count;
  355. edx += (8 * sizeof(specs->_mandatory_elements[0]))) {
  356. unsigned int midx, pres, must;
  357. midx = edx/(8 * sizeof(specs->_mandatory_elements[0]));
  358. pres = ((const unsigned int *)((const char *)st
  359. + specs->pres_offset))[midx];
  360. must = sys_ntohl(specs->_mandatory_elements[midx]);
  361. if((pres & must) == must) {
  362. /*
  363. * Yes, everything seems to be in place.
  364. */
  365. } else {
  366. ASN_DEBUG("One or more mandatory elements "
  367. "of a SET %s %d (%08x.%08x)=%08x "
  368. "are not present",
  369. td->name,
  370. midx,
  371. pres,
  372. must,
  373. (~(pres & must) & must)
  374. );
  375. return 0;
  376. }
  377. }
  378. return 1;
  379. }
  380. /*
  381. * The DER encoder of the SET type.
  382. */
  383. asn_enc_rval_t
  384. SET_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, int tag_mode,
  385. ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
  386. const asn_SET_specifics_t *specs = (const asn_SET_specifics_t *)td->specifics;
  387. size_t computed_size = 0;
  388. asn_enc_rval_t er;
  389. int t2m_build_own = (specs->tag2el_count != td->elements_count);
  390. const asn_TYPE_tag2member_t *t2m;
  391. asn_TYPE_tag2member_t *t2m_build;
  392. size_t t2m_count;
  393. ssize_t ret;
  394. size_t edx;
  395. /*
  396. * Use existing, or build our own tags map.
  397. */
  398. if(t2m_build_own) {
  399. t2m_build = (asn_TYPE_tag2member_t *)CALLOC(td->elements_count,
  400. sizeof(t2m_build[0]));
  401. if(!t2m_build) ASN__ENCODE_FAILED;
  402. t2m_count = 0;
  403. } else {
  404. t2m_build = NULL;
  405. /*
  406. * There is no untagged CHOICE in this SET.
  407. * Employ existing table.
  408. */
  409. }
  410. /*
  411. * Gather the length of the underlying members sequence.
  412. */
  413. for(edx = 0; edx < td->elements_count; edx++) {
  414. asn_TYPE_member_t *elm = &td->elements[edx];
  415. asn_enc_rval_t tmper;
  416. const void *memb_ptr_dontuse; /* Pointer to the member */
  417. const void *const *memb_ptr2; /* Pointer to that pointer */
  418. /*
  419. * Compute the length of the encoding of this member.
  420. */
  421. if(elm->flags & ATF_POINTER) {
  422. memb_ptr2 =
  423. (const void *const *)((const char *)sptr + elm->memb_offset);
  424. if(!*memb_ptr2) {
  425. if(!elm->optional) {
  426. /* Mandatory elements missing */
  427. FREEMEM(t2m_build);
  428. ASN__ENCODE_FAILED;
  429. }
  430. if(t2m_build) {
  431. t2m_build[t2m_count].el_no = edx;
  432. t2m_build[t2m_count].el_tag = 0;
  433. t2m_count++;
  434. }
  435. continue;
  436. }
  437. } else {
  438. memb_ptr_dontuse =
  439. (const void *)((const char *)sptr + elm->memb_offset);
  440. memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
  441. }
  442. /* Eliminate default values */
  443. if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0) {
  444. if(t2m_build) {
  445. t2m_build[t2m_count].el_no = edx;
  446. t2m_build[t2m_count].el_tag = 0;
  447. t2m_count++;
  448. }
  449. continue;
  450. }
  451. tmper = elm->type->op->der_encoder(elm->type, *memb_ptr2,
  452. elm->tag_mode, elm->tag,
  453. 0, 0);
  454. if(tmper.encoded == -1)
  455. return tmper;
  456. computed_size += tmper.encoded;
  457. /*
  458. * Remember the outmost tag of this member.
  459. */
  460. if(t2m_build) {
  461. t2m_build[t2m_count].el_no = edx;
  462. t2m_build[t2m_count].el_tag = asn_TYPE_outmost_tag(
  463. elm->type, *memb_ptr2, elm->tag_mode, elm->tag);
  464. t2m_count++;
  465. } else {
  466. /*
  467. * No dynamic sorting is necessary.
  468. */
  469. }
  470. }
  471. /*
  472. * Finalize order of the components.
  473. */
  474. if(t2m_build) {
  475. /*
  476. * Sort the underlying members according to their
  477. * canonical tags order. DER encoding mandates it.
  478. */
  479. qsort(t2m_build, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp);
  480. t2m = t2m_build;
  481. } else {
  482. /*
  483. * Tags are already sorted by the compiler.
  484. */
  485. t2m = specs->tag2el;
  486. t2m_count = specs->tag2el_count;
  487. }
  488. assert(t2m_count == td->elements_count);
  489. /*
  490. * Encode the TLV for the sequence itself.
  491. */
  492. ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
  493. if(ret == -1) {
  494. FREEMEM(t2m_build);
  495. ASN__ENCODE_FAILED;
  496. }
  497. er.encoded = computed_size + ret;
  498. if(!cb) {
  499. FREEMEM(t2m_build);
  500. ASN__ENCODED_OK(er);
  501. }
  502. /*
  503. * Encode all members.
  504. */
  505. for(edx = 0; edx < td->elements_count; edx++) {
  506. asn_TYPE_member_t *elm;
  507. asn_enc_rval_t tmper;
  508. const void *memb_ptr_dontuse; /* Pointer to the member */
  509. const void *const *memb_ptr2; /* Pointer to that pointer */
  510. /* Encode according to the tag order */
  511. elm = &td->elements[t2m[edx].el_no];
  512. if(elm->flags & ATF_POINTER) {
  513. memb_ptr2 =
  514. (const void *const *)((const char *)sptr + elm->memb_offset);
  515. if(!*memb_ptr2) continue;
  516. } else {
  517. memb_ptr_dontuse =
  518. (const void *)((const char *)sptr + elm->memb_offset);
  519. memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
  520. }
  521. /* Eliminate default values */
  522. if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
  523. continue;
  524. tmper = elm->type->op->der_encoder(elm->type, *memb_ptr2,
  525. elm->tag_mode, elm->tag, cb, app_key);
  526. if(tmper.encoded == -1)
  527. return tmper;
  528. computed_size -= tmper.encoded;
  529. }
  530. if(computed_size != 0) {
  531. /*
  532. * Encoded size is not equal to the computed size.
  533. */
  534. FREEMEM(t2m_build);
  535. ASN__ENCODE_FAILED;
  536. }
  537. FREEMEM(t2m_build);
  538. ASN__ENCODED_OK(er);
  539. }
  540. #undef XER_ADVANCE
  541. #define XER_ADVANCE(num_bytes) do { \
  542. size_t num = num_bytes; \
  543. buf_ptr = ((const char *)buf_ptr) + num;\
  544. size -= num; \
  545. consumed_myself += num; \
  546. } while(0)
  547. /*
  548. * Decode the XER (XML) data.
  549. */
  550. asn_dec_rval_t
  551. SET_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
  552. const asn_TYPE_descriptor_t *td, void **struct_ptr,
  553. const char *opt_mname, const void *buf_ptr, size_t size) {
  554. /*
  555. * Bring closer parts of structure description.
  556. */
  557. const asn_SET_specifics_t *specs = (const asn_SET_specifics_t *)td->specifics;
  558. const asn_TYPE_member_t *elements = td->elements;
  559. const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
  560. /*
  561. * ... and parts of the structure being constructed.
  562. */
  563. void *st = *struct_ptr; /* Target structure. */
  564. asn_struct_ctx_t *ctx; /* Decoder context */
  565. asn_dec_rval_t rval; /* Return value from a decoder */
  566. ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
  567. size_t edx; /* Element index */
  568. /*
  569. * Create the target structure if it is not present already.
  570. */
  571. if(st == 0) {
  572. st = *struct_ptr = CALLOC(1, specs->struct_size);
  573. if(st == 0) RETURN(RC_FAIL);
  574. }
  575. /*
  576. * Restore parsing context.
  577. */
  578. ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
  579. /*
  580. * Phases of XER/XML processing:
  581. * Phase 0: Check that the opening tag matches our expectations.
  582. * Phase 1: Processing body and reacting on closing tag.
  583. * Phase 2: Processing inner type.
  584. * Phase 3: Skipping unknown extensions.
  585. * Phase 4: PHASED OUT
  586. */
  587. for(edx = ctx->step; ctx->phase <= 3;) {
  588. pxer_chunk_type_e ch_type; /* XER chunk type */
  589. ssize_t ch_size; /* Chunk size */
  590. xer_check_tag_e tcv; /* Tag check value */
  591. const asn_TYPE_member_t *elm;
  592. /*
  593. * Go inside the inner member of a set.
  594. */
  595. if(ctx->phase == 2) {
  596. asn_dec_rval_t tmprval;
  597. void *memb_ptr_dontuse; /* Pointer to the member */
  598. void **memb_ptr2; /* Pointer to that pointer */
  599. if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset,
  600. edx)) {
  601. ASN_DEBUG("SET %s: Duplicate element %s (%" ASN_PRI_SSIZE ")",
  602. td->name, elements[edx].name, edx);
  603. RETURN(RC_FAIL);
  604. }
  605. elm = &elements[edx];
  606. if(elm->flags & ATF_POINTER) {
  607. /* Member is a pointer to another structure */
  608. memb_ptr2 = (void **)((char *)st + elm->memb_offset);
  609. } else {
  610. memb_ptr_dontuse = (char *)st + elm->memb_offset;
  611. memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
  612. }
  613. /* Invoke the inner type decoder, m.b. multiple times */
  614. tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
  615. elm->type, memb_ptr2, elm->name,
  616. buf_ptr, size);
  617. XER_ADVANCE(tmprval.consumed);
  618. if(tmprval.code != RC_OK)
  619. RETURN(tmprval.code);
  620. ctx->phase = 1; /* Back to body processing */
  621. ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx);
  622. ASN_DEBUG("XER/SET phase => %d", ctx->phase);
  623. /* Fall through */
  624. }
  625. /*
  626. * Get the next part of the XML stream.
  627. */
  628. ch_size = xer_next_token(&ctx->context,
  629. buf_ptr, size, &ch_type);
  630. if(ch_size == -1) {
  631. RETURN(RC_FAIL);
  632. } else {
  633. switch(ch_type) {
  634. case PXER_WMORE:
  635. RETURN(RC_WMORE);
  636. case PXER_COMMENT: /* Got XML comment */
  637. case PXER_TEXT: /* Ignore free-standing text */
  638. XER_ADVANCE(ch_size); /* Skip silently */
  639. continue;
  640. case PXER_TAG:
  641. break; /* Check the rest down there */
  642. }
  643. }
  644. tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
  645. ASN_DEBUG("XER/SET: tcv = %d, ph=%d", tcv, ctx->phase);
  646. /* Skip the extensions section */
  647. if(ctx->phase == 3) {
  648. switch(xer_skip_unknown(tcv, &ctx->left)) {
  649. case -1:
  650. ctx->phase = 4;
  651. RETURN(RC_FAIL);
  652. case 1:
  653. ctx->phase = 1;
  654. /* Fall through */
  655. case 0:
  656. XER_ADVANCE(ch_size);
  657. continue;
  658. case 2:
  659. ctx->phase = 1;
  660. break;
  661. }
  662. }
  663. switch(tcv) {
  664. case XCT_CLOSING:
  665. if(ctx->phase == 0) break;
  666. ctx->phase = 0;
  667. /* Fall through */
  668. case XCT_BOTH:
  669. if(ctx->phase == 0) {
  670. if(_SET_is_populated(td, st)) {
  671. XER_ADVANCE(ch_size);
  672. ctx->phase = 4; /* Phase out */
  673. RETURN(RC_OK);
  674. } else {
  675. ASN_DEBUG("Premature end of XER SET");
  676. RETURN(RC_FAIL);
  677. }
  678. }
  679. /* Fall through */
  680. case XCT_OPENING:
  681. if(ctx->phase == 0) {
  682. XER_ADVANCE(ch_size);
  683. ctx->phase = 1; /* Processing body phase */
  684. continue;
  685. }
  686. /* Fall through */
  687. case XCT_UNKNOWN_OP:
  688. case XCT_UNKNOWN_BO:
  689. ASN_DEBUG("XER/SET: tcv=%d, ph=%d", tcv, ctx->phase);
  690. if(ctx->phase != 1)
  691. break; /* Really unexpected */
  692. /*
  693. * Search which member corresponds to this tag.
  694. */
  695. for(edx = 0; edx < td->elements_count; edx++) {
  696. switch(xer_check_tag(buf_ptr, ch_size,
  697. elements[edx].name)) {
  698. case XCT_BOTH:
  699. case XCT_OPENING:
  700. /*
  701. * Process this member.
  702. */
  703. ctx->step = edx;
  704. ctx->phase = 2;
  705. break;
  706. case XCT_UNKNOWN_OP:
  707. case XCT_UNKNOWN_BO:
  708. continue;
  709. default:
  710. edx = td->elements_count;
  711. break; /* Phase out */
  712. }
  713. break;
  714. }
  715. if(edx != td->elements_count)
  716. continue;
  717. /* It is expected extension */
  718. if(specs->extensible) {
  719. ASN_DEBUG("Got anticipated extension");
  720. /*
  721. * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
  722. * By using a mask. Only record a pure
  723. * <opening> tags.
  724. */
  725. if(tcv & XCT_CLOSING) {
  726. /* Found </extension> without body */
  727. } else {
  728. ctx->left = 1;
  729. ctx->phase = 3; /* Skip ...'s */
  730. }
  731. XER_ADVANCE(ch_size);
  732. continue;
  733. }
  734. /* Fall through */
  735. default:
  736. break;
  737. }
  738. ASN_DEBUG("Unexpected XML tag in SET, expected \"%s\"",
  739. xml_tag);
  740. break;
  741. }
  742. ctx->phase = 4; /* "Phase out" on hard failure */
  743. RETURN(RC_FAIL);
  744. }
  745. asn_enc_rval_t
  746. SET_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
  747. enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
  748. void *app_key) {
  749. const asn_SET_specifics_t *specs = (const asn_SET_specifics_t *)td->specifics;
  750. asn_enc_rval_t er;
  751. int xcan = (flags & XER_F_CANONICAL);
  752. const asn_TYPE_tag2member_t *t2m = specs->tag2el_cxer;
  753. size_t t2m_count = specs->tag2el_cxer_count;
  754. size_t edx;
  755. if(!sptr)
  756. ASN__ENCODE_FAILED;
  757. assert(t2m_count == td->elements_count);
  758. er.encoded = 0;
  759. for(edx = 0; edx < t2m_count; edx++) {
  760. asn_enc_rval_t tmper;
  761. asn_TYPE_member_t *elm;
  762. const void *memb_ptr;
  763. const char *mname;
  764. size_t mlen;
  765. elm = &td->elements[t2m[edx].el_no];
  766. mname = elm->name;
  767. mlen = strlen(elm->name);
  768. if(elm->flags & ATF_POINTER) {
  769. memb_ptr =
  770. *(const void *const *)((const char *)sptr + elm->memb_offset);
  771. if(!memb_ptr) {
  772. if(elm->optional)
  773. continue;
  774. /* Mandatory element missing */
  775. ASN__ENCODE_FAILED;
  776. }
  777. } else {
  778. memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
  779. }
  780. if(!xcan)
  781. ASN__TEXT_INDENT(1, ilevel);
  782. ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
  783. /* Print the member itself */
  784. tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
  785. ilevel + 1, flags, cb, app_key);
  786. if(tmper.encoded == -1) return tmper;
  787. er.encoded += tmper.encoded;
  788. ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
  789. }
  790. if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
  791. ASN__ENCODED_OK(er);
  792. cb_failed:
  793. ASN__ENCODE_FAILED;
  794. }
  795. int
  796. SET_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
  797. asn_app_consume_bytes_f *cb, void *app_key) {
  798. size_t edx;
  799. int ret;
  800. if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
  801. /* Dump preamble */
  802. if(cb(td->name, strlen(td->name), app_key) < 0
  803. || cb(" ::= {", 6, app_key) < 0)
  804. return -1;
  805. for(edx = 0; edx < td->elements_count; edx++) {
  806. asn_TYPE_member_t *elm = &td->elements[edx];
  807. const void *memb_ptr;
  808. if(elm->flags & ATF_POINTER) {
  809. memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
  810. if(!memb_ptr) {
  811. if(elm->optional) continue;
  812. /* Print <absent> line */
  813. /* Fall through */
  814. }
  815. } else {
  816. memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
  817. }
  818. _i_INDENT(1);
  819. /* Print the member's name and stuff */
  820. if(cb(elm->name, strlen(elm->name), app_key) < 0
  821. || cb(": ", 2, app_key) < 0)
  822. return -1;
  823. /* Print the member itself */
  824. ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1,
  825. cb, app_key);
  826. if(ret) return ret;
  827. }
  828. ilevel--;
  829. _i_INDENT(1);
  830. return (cb("}", 1, app_key) < 0) ? -1 : 0;
  831. }
  832. void
  833. SET_free(const asn_TYPE_descriptor_t *td, void *ptr,
  834. enum asn_struct_free_method method) {
  835. size_t edx;
  836. if(!td || !ptr)
  837. return;
  838. ASN_DEBUG("Freeing %s as SET", td->name);
  839. for(edx = 0; edx < td->elements_count; edx++) {
  840. asn_TYPE_member_t *elm = &td->elements[edx];
  841. void *memb_ptr;
  842. if(elm->flags & ATF_POINTER) {
  843. memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
  844. if(memb_ptr)
  845. ASN_STRUCT_FREE(*elm->type, memb_ptr);
  846. } else {
  847. memb_ptr = (void *)((char *)ptr + elm->memb_offset);
  848. ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
  849. }
  850. }
  851. switch(method) {
  852. case ASFM_FREE_EVERYTHING:
  853. FREEMEM(ptr);
  854. break;
  855. case ASFM_FREE_UNDERLYING:
  856. break;
  857. case ASFM_FREE_UNDERLYING_AND_RESET:
  858. memset(ptr, 0,
  859. ((const asn_SET_specifics_t *)(td->specifics))->struct_size);
  860. break;
  861. }
  862. }
  863. int
  864. SET_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
  865. asn_app_constraint_failed_f *ctfailcb, void *app_key) {
  866. size_t edx;
  867. if(!sptr) {
  868. ASN__CTFAIL(app_key, td, sptr,
  869. "%s: value not given (%s:%d)",
  870. td->name, __FILE__, __LINE__);
  871. return -1;
  872. }
  873. /*
  874. * Iterate over structure members and check their validity.
  875. */
  876. for(edx = 0; edx < td->elements_count; edx++) {
  877. asn_TYPE_member_t *elm = &td->elements[edx];
  878. const void *memb_ptr;
  879. if(elm->flags & ATF_POINTER) {
  880. memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
  881. if(!memb_ptr) {
  882. if(elm->optional)
  883. continue;
  884. ASN__CTFAIL(app_key, td, sptr,
  885. "%s: mandatory element %s absent (%s:%d)",
  886. td->name, elm->name, __FILE__, __LINE__);
  887. return -1;
  888. }
  889. } else {
  890. memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
  891. }
  892. if(elm->encoding_constraints.general_constraints) {
  893. return elm->encoding_constraints.general_constraints(
  894. elm->type, memb_ptr, ctfailcb, app_key);
  895. } else {
  896. return elm->type->encoding_constraints.general_constraints(
  897. elm->type, memb_ptr, ctfailcb, app_key);
  898. }
  899. }
  900. return 0;
  901. }
  902. int
  903. SET_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
  904. const void *bptr) {
  905. size_t edx;
  906. for(edx = 0; edx < td->elements_count; edx++) {
  907. asn_TYPE_member_t *elm = &td->elements[edx];
  908. const void *amemb;
  909. const void *bmemb;
  910. int ret;
  911. if(elm->flags & ATF_POINTER) {
  912. amemb =
  913. *(const void *const *)((const char *)aptr + elm->memb_offset);
  914. bmemb =
  915. *(const void *const *)((const char *)bptr + elm->memb_offset);
  916. if(!amemb) {
  917. if(!bmemb) continue;
  918. return -1;
  919. } else if(!bmemb) {
  920. return 1;
  921. }
  922. } else {
  923. amemb = (const void *)((const char *)aptr + elm->memb_offset);
  924. bmemb = (const void *)((const char *)bptr + elm->memb_offset);
  925. }
  926. ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
  927. if(ret != 0) return ret;
  928. }
  929. return 0;
  930. }
  931. asn_TYPE_operation_t asn_OP_SET = {
  932. SET_free,
  933. SET_print,
  934. SET_compare,
  935. SET_decode_ber,
  936. SET_encode_der,
  937. SET_decode_xer,
  938. SET_encode_xer,
  939. 0, /* SET_decode_oer */
  940. 0, /* SET_encode_oer */
  941. 0, /* SET_decode_uper */
  942. 0, /* SET_encode_uper */
  943. SET_random_fill,
  944. 0 /* Use generic outmost tag fetcher */
  945. };
  946. asn_random_fill_result_t
  947. SET_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
  948. const asn_encoding_constraints_t *constr,
  949. size_t max_length) {
  950. const asn_SET_specifics_t *specs =
  951. (const asn_SET_specifics_t *)td->specifics;
  952. asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
  953. asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
  954. asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
  955. void *st = *sptr;
  956. size_t edx;
  957. if(max_length == 0) return result_skipped;
  958. (void)constr;
  959. if(st == NULL) {
  960. st = CALLOC(1, specs->struct_size);
  961. if(st == NULL) {
  962. return result_failed;
  963. }
  964. }
  965. for(edx = 0; edx < td->elements_count; edx++) {
  966. const asn_TYPE_member_t *elm = &td->elements[edx];
  967. void *memb_ptr; /* Pointer to the member */
  968. void **memb_ptr2; /* Pointer to that pointer */
  969. asn_random_fill_result_t tmpres;
  970. if(elm->optional && asn_random_between(0, 4) == 2) {
  971. /* Sometimes decide not to fill the optional value */
  972. continue;
  973. }
  974. if(elm->flags & ATF_POINTER) {
  975. /* Member is a pointer to another structure */
  976. memb_ptr2 = (void **)((char *)st + elm->memb_offset);
  977. } else {
  978. memb_ptr = (char *)st + elm->memb_offset;
  979. memb_ptr2 = &memb_ptr;
  980. }
  981. tmpres = elm->type->op->random_fill(
  982. elm->type, memb_ptr2, &elm->encoding_constraints,
  983. max_length > result_ok.length ? max_length - result_ok.length : 0);
  984. switch(tmpres.code) {
  985. case ARFILL_OK:
  986. result_ok.length += tmpres.length;
  987. continue;
  988. case ARFILL_SKIPPED:
  989. assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
  990. continue;
  991. case ARFILL_FAILED:
  992. if(st == *sptr) {
  993. ASN_STRUCT_RESET(*td, st);
  994. } else {
  995. ASN_STRUCT_FREE(*td, st);
  996. }
  997. return tmpres;
  998. }
  999. }
  1000. *sptr = st;
  1001. return result_ok;
  1002. }