static asn1_error_code encode_nullterm_sequence_of(asn1buf *buf, const void *val, const struct atype_info *type, int can_be_empty, unsigned int *retlen) { int length = get_nullterm_sequence_len(val, type); if (!can_be_empty && length == 0) return ASN1_MISSING_FIELD; return encode_sequence_of(buf, length, val, type, retlen); }
static asn1_error_code encode_nullterm_sequence_of(asn1buf *buf, const void *val, const struct atype_info *type, int can_be_empty, size_t *len_out) { size_t len = get_nullterm_sequence_len(val, type); if (!can_be_empty && len == 0) return ASN1_MISSING_FIELD; return encode_sequence_of(buf, len, val, type, len_out); }
/* * Free a C object according to a type description. Do not free pointers at * the first level; they may be referenced by other fields of a sequence, and * will be freed by free_atype_ptr in a second pass. */ static void free_atype(const struct atype_info *a, void *val) { switch (a->type) { case atype_fn: { const struct fn_info *fn = a->tinfo; if (fn->free_func != NULL) fn->free_func(val); break; } case atype_sequence: free_sequence(a->tinfo, val); break; case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; void *ptr = LOADPTR(val, ptrinfo); if (ptr != NULL) { free_atype(ptrinfo->basetype, ptr); free_atype_ptr(ptrinfo->basetype, ptr); } break; } case atype_offset: { const struct offset_info *off = a->tinfo; assert(off->basetype != NULL); free_atype(off->basetype, (char *)val + off->dataoff); break; } case atype_optional: { const struct optional_info *opt = a->tinfo; free_atype(opt->basetype, val); break; } case atype_counted: { const struct counted_info *counted = a->tinfo; void *dataptr = (char *)val + counted->dataoff; size_t count; if (load_count(val, counted, &count) == 0) free_cntype(counted->basetype, dataptr, count); break; } case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: { size_t count = get_nullterm_sequence_len(val, a->tinfo); free_sequence_of(a->tinfo, val, count); break; } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; free_atype(tag->basetype, val); break; } case atype_bool: case atype_int: case atype_uint: case atype_int_immediate: break; default: abort(); } }