diff --git a/ChangeLog b/ChangeLog index c9268e28..763edb49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ * ber_dec_rval_t renamed into asn_dec_rval_t: more generality. * Removed order dependency in DEFAULT references to ENUMERATED identifiers (./tests/68-*-OK.asn1). + * Implemented der_encode_to_buffer() procedure. 0.9.7.1: 2004-Oct-12 diff --git a/skeletons/der_encoder.c b/skeletons/der_encoder.c index 3523cb12..b2763c7c 100644 --- a/skeletons/der_encoder.c +++ b/skeletons/der_encoder.c @@ -28,6 +28,50 @@ der_encode(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr, consume_bytes, app_key); } +/* + * Argument type and callback necessary for der_encode_to_buffer(). + */ +typedef struct enc_to_buf_arg { + void *buffer; + size_t left; +} enc_to_buf_arg; +static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) { + enc_to_buf_arg *arg = key; + + if(arg->left < size) + return -1; /* Data exceeds the available buffer size */ + + memcpy(arg->buffer, buffer, size); + arg->buffer = ((char *)arg->buffer) + size; + arg->left -= size; + + return 0; +} + +/* + * A variant of the der_encode() which encodes the data into the provided buffer + */ +asn_enc_rval_t +der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr, + void *buffer, size_t *buffer_size) { + enc_to_buf_arg arg; + asn_enc_rval_t ec; + + arg.buffer = buffer; + arg.left = *buffer_size; + + ec = type_descriptor->der_encoder(type_descriptor, + struct_ptr, /* Pointer to the destination structure */ + 0, 0, encode_to_buffer_cb, &arg); + if(ec.encoded != -1) { + assert(ec.encoded == (*buffer_size - arg.left)); + /* Return the encoded contents size */ + *buffer_size = ec.encoded; + } + return ec; +} + + /* * Write out leading TL[v] sequence according to the type definition. */ diff --git a/skeletons/der_encoder.h b/skeletons/der_encoder.h index 62aafa7a..cb784d19 100644 --- a/skeletons/der_encoder.h +++ b/skeletons/der_encoder.h @@ -18,6 +18,14 @@ asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor, void *app_key /* Arbitrary callback argument */ ); +/* A variant of der_encode() which encodes data into the pre-allocated buffer */ +asn_enc_rval_t der_encode_to_buffer( + struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t *buffer_size /* Initial buffer size (max) */ + ); + /* * Type of the generic DER encoder. */