svn rev #25616: trunk/src/lib/krb5/asn.1/

ghudson@MIT.EDU ghudson at MIT.EDU
Fri Jan 6 16:13:59 EST 2012


http://src.mit.edu/fisheye/changelog/krb5/?cs=25616
Commit By: ghudson
Log Message:
Add support for CHOICE in ASN.1 encoder

Add a new field type where the length offset indicates a distinguisher
and the data offset indicates a union address.  The field's type is an
atype_choice containing a seq_info indexed by the distinguisher.


Changed Files:
U   trunk/src/lib/krb5/asn.1/asn1_encode.c
U   trunk/src/lib/krb5/asn.1/asn1_encode.h
Modified: trunk/src/lib/krb5/asn.1/asn1_encode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-01-06 21:10:42 UTC (rev 25615)
+++ trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-01-06 21:13:59 UTC (rev 25616)
@@ -504,6 +504,24 @@
             assert(omit_tag == NULL && !field->tag_implicit);
         break;
     }
+    case field_choice:
+    {
+        const void *dataptr = (const char *)val + field->dataoff;
+        unsigned int choice;
+        const struct seq_info *seq;
+
+        assert(omit_tag == NULL);
+        assert(field->atype->type == atype_choice);
+        seq = field->atype->tinfo;
+        retval = get_field_len(val, field, &choice);
+        if (retval)
+            return retval;
+        if (choice > seq->n_fields)
+            return ASN1_MISSING_FIELD;
+        retval = encode_a_field(buf, dataptr, &seq->fields[choice], &length,
+                                NULL);
+        break;
+    }
     default:
         assert(field->ftype > field_min);
         assert(field->ftype < field_max);

Modified: trunk/src/lib/krb5/asn.1/asn1_encode.h
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_encode.h	2012-01-06 21:10:42 UTC (rev 25615)
+++ trunk/src/lib/krb5/asn.1/asn1_encode.h	2012-01-06 21:13:59 UTC (rev 25616)
@@ -194,6 +194,12 @@
     /* Sequence.  tinfo is a struct seq_info *. */
     atype_sequence,
     /*
+     * Choice.  tinfo is a struct seq_info *, with the optional field ignored.
+     * Only usable with the field_choice field type.  Cannot be used with an
+     * implicit context tag.
+     */
+    atype_choice,
+    /*
      * Sequence-of, with pointer to base type descriptor, represented
      * as a null-terminated array of pointers (and thus the "base"
      * type descriptor is actually an atype_ptr node).  tinfo is a
@@ -383,6 +389,15 @@
     const struct atype_info krb5int_asn1type_##DESCNAME = {             \
         atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME      \
     }
+/* A choice, selected from the indicated series of fields. */
+#define DEFCHOICETYPE(DESCNAME, CTYPENAME, FIELDS)                      \
+    typedef CTYPENAME aux_typedefname_##DESCNAME;                       \
+    static const struct seq_info aux_seqinfo_##DESCNAME = {             \
+        NULL, FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0])                  \
+    };                                                                  \
+    const struct atype_info krb5int_asn1type_##DESCNAME = {             \
+        atype_choice, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME        \
+    }
 /* Integer types.  */
 #define DEFINTTYPE(DESCNAME, CTYPENAME)                                 \
     typedef CTYPENAME aux_typedefname_##DESCNAME;                       \
@@ -574,6 +589,12 @@
      * described by ATYPE.
      */
     field_sequenceof_len,
+    /*
+     * LENOFF indicates a distinguisher and DATAOFF indicates a union base
+     * address.  ATYPE is an atype_choice type pointing to a seq_info
+     * containing a field type for each choice element.
+     */
+    field_choice,
     /* Unused except for range checking.  */
     field_max
 };
@@ -711,6 +732,17 @@
 #define FIELDOF_SEQOF_INT32(STYPE,DESC,PTRFIELD,LENFIELD,TAG,IMPLICIT)  \
     FIELDOF_SEQOF_LEN(STYPE,DESC,PTRFIELD,LENFIELD,int32,TAG,IMPLICIT)
 
+#define FIELDOF_OPTCHOICE(STYPE,DESC,PTRFIELD,CHOICEFIELD,LENTYPE,TAG,OPT) \
+    { \
+        field_choice,                                                   \
+            OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC),             \
+            OFFOF(STYPE, CHOICEFIELD, aux_typedefname_##LENTYPE),       \
+            TAG, 0, OPT,                                                \
+            &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENTYPE       \
+            }
+#define FIELDOF_CHOICE(STYPE,DESC,PTRFIELD,CHOICEFIELD,LENTYPE,TAG)     \
+    FIELDOF_OPTCHOICE(STYPE,DESC,PTRFIELD,CHOICEFIELD,LENTYPE,TAG,-1)
+
 struct seq_info {
     /*
      * If present, returns a bitmask indicating which fields are



More information about the cvs-krb5 mailing list