📄 asn1c_c.c
字号:
*/ if(arg->embed && etd_spec == ETD_NO_SPECIFICS) { REDIR(OT_TYPE_DECLS); return 0; } if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS)) && (arg->embed || expr->tag.tag_class == TC_NOCLASS) && etd_spec == ETD_NO_SPECIFICS && 0 /* This shortcut is incompatible with XER */ ) { char *type_name; REDIR(OT_FUNC_DECLS); type_name = asn1c_type_name(arg, expr, TNF_SAFE); OUT("/* This type is equivalent to %s */\n", type_name); if(HIDE_INNER_DEFS) OUT("/* "); OUT("#define\tasn_DEF_%s\t", MKID(expr->Identifier)); type_name = asn1c_type_name(arg, expr, TNF_SAFE); OUT("asn_DEF_%s", type_name); if(HIDE_INNER_DEFS) OUT("\t// (Use -fall-defs-global to expose) */"); OUT("\n"); REDIR(OT_CODE); OUT("/* This type is equivalent to %s */\n", type_name); OUT("\n"); REDIR(OT_TYPE_DECLS); return 0; } REDIR(OT_STAT_DEFS); /* * Print out asn_DEF_<type>_[all_]tags[] vectors. */ tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count); emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, 0, etd_spec); REDIR(OT_CODE); /* * Constraint checking. */ if(!(arg->flags & A1C_NO_CONSTRAINTS)) { p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("int\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_constraint(asn_TYPE_descriptor_t *td, const void *sptr,\n"); INDENT(+1); OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {"); OUT("\n"); if(asn1c_emit_constraint_checking_code(arg) == 1) { OUT("/* Replace with underlying type checker */\n"); OUT("td->check_constraints " "= asn_DEF_%s.check_constraints;\n", asn1c_type_name(arg, expr, TNF_SAFE)); OUT("return td->check_constraints" "(td, sptr, app_errlog, app_key);\n"); } INDENT(-1); OUT("}\n"); OUT("\n"); } /* * Emit suicidal functions. */ /* * This function replaces certain fields from the definition * of a type with the corresponding fields from the basic type * (from which the current type is inherited). */ OUT("/*\n"); OUT(" * This type is implemented using %s,\n", asn1c_type_name(arg, expr, TNF_SAFE)); OUT(" * so here we adjust the DEF accordingly.\n"); OUT(" */\n"); OUT("static void\n"); OUT("%s_%d_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {\n", MKID(expr->Identifier), expr->_type_unique_index); INDENT(+1); { asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr); char *type_name = asn1c_type_name(arg, expr, TNF_SAFE); OUT("td->free_struct = asn_DEF_%s.free_struct;\n", type_name); OUT("td->print_struct = asn_DEF_%s.print_struct;\n", type_name); OUT("td->ber_decoder = asn_DEF_%s.ber_decoder;\n", type_name); OUT("td->der_encoder = asn_DEF_%s.der_encoder;\n", type_name); OUT("td->xer_decoder = asn_DEF_%s.xer_decoder;\n", type_name); OUT("td->xer_encoder = asn_DEF_%s.xer_encoder;\n", type_name); if(!terminal && !tags_count) { OUT("/* The next four lines are here because of -fknown-extern-type */\n"); OUT("td->tags = asn_DEF_%s.tags;\n", type_name); OUT("td->tags_count = asn_DEF_%s.tags_count;\n", type_name); OUT("td->all_tags = asn_DEF_%s.all_tags;\n", type_name); OUT("td->all_tags_count = asn_DEF_%s.all_tags_count;\n",type_name); OUT("/* End of these lines */\n"); } OUT("td->elements = asn_DEF_%s.elements;\n", type_name); OUT("td->elements_count = asn_DEF_%s.elements_count;\n", type_name); if(etd_spec != ETD_NO_SPECIFICS) { INDENT(-1); OUT(" /* "); } OUT("td->specifics = asn_DEF_%s.specifics;", type_name); if(etd_spec == ETD_NO_SPECIFICS) { INDENT(-1); OUT("\n"); } else { OUT("\t// Defined explicitly */\n"); } } OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("void\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_free(asn_TYPE_descriptor_t *td,\n"); INDENTED( OUT("\tvoid *struct_ptr, int contents_only) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("td->free_struct(td, struct_ptr, contents_only);\n"); ); OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("int\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,\n"); INDENTED( OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n"); ); OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_dec_rval_t\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n"); INDENTED( OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);\n"); ); OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_enc_rval_t\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_encode_der(asn_TYPE_descriptor_t *td,\n"); INDENTED( OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n"); OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n"); ); OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_dec_rval_t\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n"); INDENTED( OUT("\tvoid **structure, const char *opt_mname, void *bufptr, size_t size) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);\n"); ); OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_enc_rval_t\n"); OUT("%s", p); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT("_encode_xer(asn_TYPE_descriptor_t *td, void *structure,\n"); INDENTED( OUT("\tint ilevel, enum xer_encoder_flags_e flags,\n"); OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n"); OUT("%s_%d_inherit_TYPE_descriptor(td);\n", p, expr->_type_unique_index); OUT("return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);\n"); ); OUT("}\n"); OUT("\n"); REDIR(OT_FUNC_DECLS); p = MKID(expr->Identifier); if(HIDE_INNER_DEFS) { OUT("/* extern asn_TYPE_descriptor_t asn_DEF_%s_%d;" "\t// (Use -fall-defs-global to expose) */\n", p, expr->_type_unique_index); } else { OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p); OUT("asn_struct_free_f %s_free;\n", p); OUT("asn_struct_print_f %s_print;\n", p); OUT("asn_constr_check_f %s_constraint;\n", p); OUT("ber_type_decoder_f %s_decode_ber;\n", p); OUT("der_type_encoder_f %s_encode_der;\n", p); OUT("xer_type_decoder_f %s_decode_xer;\n", p); OUT("xer_type_encoder_f %s_encode_xer;\n", p); } REDIR(OT_TYPE_DECLS); return 0;}intasn1c_lang_C_type_EXTENSIBLE(arg_t *arg) { OUT("/*\n"); OUT(" * This type is extensible,\n"); OUT(" * possible extensions are below.\n"); OUT(" */\n"); return 0;}static int check_if_extensible(asn1p_expr_t *expr) { asn1p_expr_t *v; TQ_FOR(v, &(expr->members), next) { if(v->expr_type == A1TC_EXTENSIBLE) return 1; } return 0;}static int_print_tag(arg_t *arg, struct asn1p_type_tag_s *tag) { OUT("("); switch(tag->tag_class) { case TC_UNIVERSAL: OUT("ASN_TAG_CLASS_UNIVERSAL"); break; case TC_APPLICATION: OUT("ASN_TAG_CLASS_APPLICATION"); break; case TC_CONTEXT_SPECIFIC: OUT("ASN_TAG_CLASS_CONTEXT"); break; case TC_PRIVATE: OUT("ASN_TAG_CLASS_PRIVATE"); break; case TC_NOCLASS: break; } OUT(" | (%" PRIdASN " << 2))", tag->tag_value); return 0;}static int_tag2el_cmp(const void *ap, const void *bp) { const tag2el_t *a = ap; const tag2el_t *b = bp; const struct asn1p_type_tag_s *ta = &a->el_tag; const struct asn1p_type_tag_s *tb = &b->el_tag; if(ta->tag_class == tb->tag_class) { if(ta->tag_value == tb->tag_value) { /* * Sort by their respective positions. */ if(a->el_no < b->el_no) return -1; else if(a->el_no > b->el_no) return 1; return 0; } else if(ta->tag_value < tb->tag_value) return -1; else return 1; } else if(ta->tag_class < tb->tag_class) { return -1; } else { return 1; }}/* * For constructed types, number of external tags may be greater than * number of elements in the type because of CHOICE type. * T ::= SET { -- Three possible tags: * a INTEGER, -- One tag is here... * b Choice1 -- ... and two more tags are there. * } * Choice1 ::= CHOICE { * s1 IA5String, * s2 ObjectDescriptor * } */static int_fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) { asn1p_expr_t *expr = arg->expr; arg_t tmparg = *arg; asn1p_expr_t *v; int element = 0; int original_count = *count; int sort_until = -1; TQ_FOR(v, &(expr->members), next) { if(v->expr_type == A1TC_EXTENSIBLE) { /* * CXER mandates sorting * only for the root part. */ if(flags == FTE_CANONICAL_XER && sort_until == -1) sort_until = *count; continue; } tmparg.expr = v; if(_add_tag2el_member(&tmparg, tag2el, count, (el_no==-1)?element:el_no, flags)) { return -1; } element++; } if(flags == FTE_CANONICAL_XER) { if(sort_until == -1) sort_until = *count; qsort((*tag2el) + original_count, sort_until - original_count, sizeof(**tag2el), _tag2el_cmp); if(arg->expr->expr_type == ASN_CONSTR_CHOICE && (sort_until - original_count) >= 1) { /* Only take in account the root component */ *count = original_count + 1; } } else { /* * Sort the map according to canonical order of their * tags and element numbers. */ qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp); } /* * Initialize .toff_{first|last} members. */ if(*count) { struct asn1p_type_tag_s *cur_tag = 0; tag2el_t *cur = *tag2el; tag2el_t *end = cur + *count; int occur, i; for(occur = 0; cur < end; cur++) { if(cur_tag == 0 || cur_tag->tag_value != cur->el_tag.tag_value || cur_tag->tag_class != cur->el_tag.tag_class) { cur_tag = &cur->el_tag; occur = 0; } else { occur++; } cur->toff_first = -occur; for(i = 0; i >= -occur; i--) cur[i].toff_last = -i; } } return 0;}static int_add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) { struct asn1p_type_tag_s tag; int ret; assert(el_no >= 0); ret = asn1f_fetch_outmost_tag(arg->asn, arg->expr->module, arg->expr, &tag, 1); if(ret == 0) { tag2el_t *te; int new_count = (*count) + 1; void *p; if(tag.tag_value == -1) { /* * This is an untagged ANY type, * proceed without adding a tag */ return 0; } p = realloc(*tag2el, new_count * sizeof(tag2el_t)); if(p) *tag2el = p; else return -1; DEBUG("Found tag for %s: %ld", arg->expr->Identifier, (long)tag.tag_value); te = &((*tag2el)[*count]); te->el_tag = tag; te->el_no = el_no; te->from_expr = arg->expr; *count = new_count; return 0; } DEBUG("Searching tag in complex expression %s:%x at line %d", arg->expr->Identifier, arg->expr->expr_type, arg->expr->_lineno); /* * Iterate over members of CHOICE type. */ if(arg->expr->expr_type == ASN_CONSTR_CHOICE) { return _fill_tag2el_map(arg, tag2el, count, el_no, flags); } if(arg->expr->expr_type == A1TC_REFERENCE) { arg_t tmp = *arg; asn1p_expr_t *expr; expr = asn1f_lookup_symbol_ex(tmp.asn, tmp.mod, tmp.expr, arg->expr->reference); if(expr) { tmp.mod = expr->module; tmp.expr = expr; return _add_tag2el_member(&tmp, tag2el, count, el_no, flags); } else { FATAL("Cannot dereference %s at line %d", arg->expr->Identifier, arg->expr->_lineno); return -1; } } DEBUG("No tag for %s at line %d", arg->expr->Identifier, arg->expr->_lineno); return -1;}static intemit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier) { asn1p_expr_t *expr = arg->expr; OUT("static asn_TYPE_tag2member_t asn_MAP_%s_%d_tag2el%s[] = {\n", MKID(expr->Identifier), expr->_type_unique_index, opt_modifier?opt_modifier:""); if(tag2el_count) { int i; for(i = 0; i < tag2el_count; i++) { OUT(" { "); _print_tag(arg, &tag2el[i].el_tag); OUT(", "); OUT("%d, ", tag2el[i].el_no); OUT("%d, ", tag2el[i].toff_first); OUT("%d ", tag2el[i].toff_last); OUT("}%s /* %s at %d */\n", (i + 1 < tag2el_count) ? "," : "", tag2el[i].from_expr->Identifier, tag2el[i].from_expr->_lineno ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -