Permalink
Browse files

Simplify integer loading in ASN.1 encoding

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
  • Loading branch information...
1 parent b4d08be commit 5c5a9790bc98f729d31cb4e3321f487e4c4fd5f7 ghudson committed Jan 13, 2012
Showing with 34 additions and 41 deletions.
  1. +28 −10 src/lib/krb5/asn.1/asn1_encode.c
  2. +6 −31 src/lib/krb5/asn.1/asn1_encode.h
@@ -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)
@@ -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

0 comments on commit 5c5a979

Please sign in to comment.