2  * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
 
   3  * Redistribution and modifications are permitted subject to BSD license.
 
   5 #include <asn_internal.h>
 
   6 #include <asn_codecs_prim.h>
 
  10  * BOOLEAN basic type description.
 
  12 static const ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
 
  13         (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
 
  15 asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
 
  20         asn_generic_no_constraint,
 
  25         BOOLEAN_decode_uper,    /* Unaligned PER decoder */
 
  26         BOOLEAN_encode_uper,    /* Unaligned PER encoder */
 
  27         0, /* Use generic outmost tag fetcher */
 
  29         sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
 
  30         asn_DEF_BOOLEAN_tags,   /* Same as above */
 
  31         sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
 
  32         0,      /* No PER visible constraints */
 
  33         0, 0,   /* No members */
 
  38  * Decode BOOLEAN type.
 
  41 BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 
  42                 asn_TYPE_descriptor_t *td,
 
  43                 void **bool_value, const void *buf_ptr, size_t size,
 
  45         BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
 
  51                 st = (BOOLEAN_t *)(*bool_value = CALLOC(1, sizeof(*st)));
 
  59         ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
 
  65         rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
 
  66                 tag_mode, 0, &length, 0);
 
  67         if(rval.code != RC_OK)
 
  70         ASN_DEBUG("Boolean length is %d bytes", (int)length);
 
  72         buf_ptr = ((const char *)buf_ptr) + rval.consumed;
 
  73         size -= rval.consumed;
 
  74         if(length > (ber_tlv_len_t)size) {
 
  81          * Compute boolean value.
 
  83         for(*st = 0, lidx = 0;
 
  84                 (lidx < length) && *st == 0; lidx++) {
 
  86                  * Very simple approach: read bytes until the end or
 
  87                  * value is already TRUE.
 
  88                  * BOOLEAN is not supposed to contain meaningful data anyway.
 
  90                 *st |= ((const uint8_t *)buf_ptr)[lidx];
 
  94         rval.consumed += length;
 
  96         ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
 
  97                 (long)rval.consumed, (long)length,
 
 104 BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 
 105         int tag_mode, ber_tlv_tag_t tag,
 
 106         asn_app_consume_bytes_f *cb, void *app_key) {
 
 107         asn_enc_rval_t erval;
 
 108         BOOLEAN_t *st = (BOOLEAN_t *)sptr;
 
 110         erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key);
 
 111         if(erval.encoded == -1) {
 
 112                 erval.failed_type = td;
 
 113                 erval.structure_ptr = sptr;
 
 120                 bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */
 
 122                 if(cb(&bool_value, 1, app_key) < 0) {
 
 124                         erval.failed_type = td;
 
 125                         erval.structure_ptr = sptr;
 
 132         ASN__ENCODED_OK(erval);
 
 137  * Decode the chunk of XML text encoding INTEGER.
 
 139 static enum xer_pbd_rval
 
 140 BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
 
 141         BOOLEAN_t *st = (BOOLEAN_t *)sptr;
 
 142         const char *p = (const char *)chunk_buf;
 
 146         if(chunk_size && p[0] == 0x3c /* '<' */) {
 
 147                 switch(xer_check_tag(chunk_buf, chunk_size, "false")) {
 
 153                         if(xer_check_tag(chunk_buf, chunk_size, "true")
 
 155                                 return XPBD_BROKEN_ENCODING;
 
 157                         *st = 1;        /* Or 0xff as in DER?.. */
 
 160                         return XPBD_BROKEN_ENCODING;
 
 162                 return XPBD_BODY_CONSUMED;
 
 164                 return XPBD_BROKEN_ENCODING;
 
 170 BOOLEAN_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
 
 171         asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
 
 172                 const void *buf_ptr, size_t size) {
 
 174         return xer_decode_primitive(opt_codec_ctx, td,
 
 175                 sptr, sizeof(BOOLEAN_t), opt_mname, buf_ptr, size,
 
 176                 BOOLEAN__xer_body_decode);
 
 180 BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 
 181         int ilevel, enum xer_encoder_flags_e flags,
 
 182                 asn_app_consume_bytes_f *cb, void *app_key) {
 
 183         const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
 
 189         if(!st) ASN__ENCODE_FAILED;
 
 192                 ASN__CALLBACK("<true/>", 7);
 
 195                 ASN__CALLBACK("<false/>", 8);
 
 205 BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 
 206         asn_app_consume_bytes_f *cb, void *app_key) {
 
 207         const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
 
 211         (void)td;       /* Unused argument */
 
 212         (void)ilevel;   /* Unused argument */
 
 227         return (cb(buf, buflen, app_key) < 0) ? -1 : 0;
 
 231 BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
 
 232         if(td && ptr && !contents_only) {
 
 238 BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 239         asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
 
 241         BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
 
 247                 st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
 
 248                 if(!st) ASN__DECODE_FAILED;
 
 252          * Extract a single bit
 
 254         switch(per_get_few_bits(pd, 1)) {
 
 255         case 1: *st = 1; break;
 
 256         case 0: *st = 0; break;
 
 257         case -1: default: ASN__DECODE_STARVED;
 
 260         ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
 
 269 BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
 
 270         asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
 
 271         const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
 
 272         asn_enc_rval_t er = { 0, 0, 0 };
 
 276         if(!st) ASN__ENCODE_FAILED;
 
 278         if(per_put_few_bits(po, *st ? 1 : 0, 1))