Simplify integer loading in ASN.1 encoding
authorGreg Hudson <ghudson@mit.edu>
Fri, 13 Jan 2012 17:35:30 +0000 (17:35 +0000)
committerGreg Hudson <ghudson@mit.edu>
Fri, 13 Jan 2012 17:35:30 +0000 (17:35 +0000)
Instead of defining an auxiliary load function for each integer
type, just use its size and signedness to decide how to load it.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25651 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/asn.1/asn1_encode.c
src/lib/krb5/asn.1/asn1_encode.h

index ba71add15a5006c269656987a444a145068dd665..e579bb007aa11a61acd0cd2e4246acc24ac5e57b 100644 (file)
@@ -231,6 +231,30 @@ encode_nullterm_sequence_of(asn1buf *buf, const void *val,
     return encode_sequence_of(buf, length, val, type, retlen);
 }
 
+static asn1_intmax
+load_int(const void *val, size_t size)
+{
+    switch (size) {
+    case 1: return *(signed char *)val;
+    case 2: return *(krb5_int16 *)val;
+    case 4: return *(krb5_int32 *)val;
+    case 8: return *(INT64_TYPE *)val;
+    default: abort();
+    }
+}
+
+static asn1_uintmax
+load_uint(const void *val, size_t size)
+{
+    switch (size) {
+    case 1: return *(unsigned char *)val;
+    case 2: return *(krb5_ui_2 *)val;
+    case 4: return *(krb5_ui_4 *)val;
+    case 8: return *(UINT64_TYPE *)val;
+    default: abort();
+    }
+}
+
 static asn1_error_code
 just_encode_sequence(asn1buf *buf, const void *val,
                      const struct seq_info *seq,
@@ -314,9 +338,7 @@ krb5int_asn1_encode_type(asn1buf *buf, const void *val,
         break;
     }
     case atype_int: {
-        const struct int_info *tinfo = a->tinfo;
-        assert(tinfo->loadint != NULL);
-        retval = asn1_encode_integer(buf, tinfo->loadint(val),
+        retval = asn1_encode_integer(buf, load_int(val, a->size),
                                      &rettag->length);
         if (retval)
             return retval;
@@ -326,9 +348,7 @@ krb5int_asn1_encode_type(asn1buf *buf, const void *val,
         break;
     }
     case atype_uint: {
-        const struct uint_info *tinfo = a->tinfo;
-        assert(tinfo->loaduint != NULL);
-        retval = asn1_encode_unsigned_integer(buf, tinfo->loaduint(val),
+        retval = asn1_encode_unsigned_integer(buf, load_uint(val, a->size),
                                               &rettag->length);
         if (retval)
             return retval;
@@ -385,8 +405,7 @@ get_field_len(const void *val, const struct field_info *field,
     assert(sizeof(int) <= sizeof(asn1_intmax));
     assert(sizeof(unsigned int) <= sizeof(asn1_uintmax));
     if (field->lentype->type == atype_int) {
-        const struct int_info *tinfo = field->lentype->tinfo;
-        asn1_intmax xlen = tinfo->loadint(lenptr);
+        asn1_intmax xlen = load_int(lenptr, field->lentype->size);
         if (xlen < 0)
             return EINVAL;
         if ((unsigned int)xlen != (asn1_uintmax)xlen)
@@ -395,8 +414,7 @@ get_field_len(const void *val, const struct field_info *field,
             return EINVAL;
         *retlen = (unsigned int)xlen;
     } else {
-        const struct uint_info *tinfo = field->lentype->tinfo;
-        asn1_uintmax xlen = tinfo->loaduint(lenptr);
+        asn1_uintmax xlen = load_uint(lenptr, field->lentype->size);
         if ((unsigned int)xlen != xlen)
             return EINVAL;
         if (xlen > UINT_MAX)
index 77d34f4250932517e753cc3a1c665c66bbea2d10..cd7983ac78be9f2dbdc0677148a4fec5fd488d89 100644 (file)
@@ -223,9 +223,8 @@ enum atype_type {
     atype_field,
     /* Tagged version of another type.  tinfo is a struct tagged_info *. */
     atype_tagged_thing,
-    /* Integer.  tinfo is a struct int_info. */
+    /* Signed or unsigned integer.  tinfo is NULL. */
     atype_int,
-    /* Unsigned integer.  tinfo is a struct uint_info. */
     atype_uint,
     /* Unused except for bounds checking.  */
     atype_max
@@ -263,14 +262,6 @@ struct tagged_info {
     const struct atype_info *basetype;
 };
 
-struct int_info {
-    asn1_intmax (*loadint)(const void *);
-};
-
-struct uint_info {
-    asn1_uintmax (*loaduint)(const void *);
-};
-
 /*
  * The various DEF*TYPE macros must:
  *
@@ -399,31 +390,15 @@ struct uint_info {
         atype_choice, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME        \
     }
 /* Integer types.  */
-#define DEFINTTYPE(DESCNAME, CTYPENAME)                                 \
-    typedef CTYPENAME aux_typedefname_##DESCNAME;                       \
-    static asn1_intmax loadint_##DESCNAME(const void *p)                \
-    {                                                                   \
-        assert(sizeof(CTYPENAME) <= sizeof(asn1_intmax));               \
-        return *(const aux_typedefname_##DESCNAME *)p;                  \
-    }                                                                   \
-    static const struct int_info aux_info_##DESCNAME = {                \
-        loadint_##DESCNAME                                              \
-    };                                                                  \
-    const struct atype_info krb5int_asn1type_##DESCNAME = {             \
-        atype_int, sizeof(CTYPENAME), &aux_info_##DESCNAME              \
+#define DEFINTTYPE(DESCNAME, CTYPENAME)                         \
+    typedef CTYPENAME aux_typedefname_##DESCNAME;               \
+    const struct atype_info krb5int_asn1type_##DESCNAME = {     \
+        atype_int, sizeof(CTYPENAME), NULL                      \
     }
 #define DEFUINTTYPE(DESCNAME, CTYPENAME)                        \
     typedef CTYPENAME aux_typedefname_##DESCNAME;               \
-    static asn1_uintmax loaduint_##DESCNAME(const void *p)      \
-    {                                                           \
-        assert(sizeof(CTYPENAME) <= sizeof(asn1_uintmax));      \
-        return *(const aux_typedefname_##DESCNAME *)p;          \
-    }                                                           \
-    static const struct uint_info aux_info_##DESCNAME = {       \
-        loaduint_##DESCNAME                                     \
-    };                                                          \
     const struct atype_info krb5int_asn1type_##DESCNAME = {     \
-        atype_uint, sizeof(CTYPENAME), &aux_info_##DESCNAME     \
+        atype_uint, sizeof(CTYPENAME), NULL                     \
     }
 /* Pointers to other types, to be encoded as those other types.  */
 #ifdef POINTERS_ARE_ALL_THE_SAME