diff --git a/include/libtcap.h b/include/libtcap.h index e7f115a..01ebe33 100644 --- a/include/libtcap.h +++ b/include/libtcap.h @@ -7,10 +7,24 @@ #include "constr_TYPE.h" +struct output_buffer { + char *buf; + size_t buf_size; + size_t used; +}; +#define OUTPUT_BUFFER_INIT(o, i) output_buffer_init(o, i, sizeof(i)) +static inline void output_buffer_init(struct output_buffer *o, char *i, size_t s) { + o->buf = i; + o->buf_size = s; + o->used = 0; +} + + + TCMessage_t *tcap_decode(const char *buf, size_t len); void *inap_decode(Invoke_t *invoke, asn_TYPE_descriptor_t **); -int tcap_extract(const char *buf, size_t len, const char *spec, void *out); -int inap_extract(const char *buf, size_t len, const char *spec, void *out); +int tcap_extract(const char *buf, size_t len, const char *spec, struct output_buffer *out); +int inap_extract(const char *buf, size_t len, const char *spec, struct output_buffer *out); #endif diff --git a/src/tcap.c b/src/tcap.c index 3b3f4c7..caccdd6 100644 --- a/src/tcap.c +++ b/src/tcap.c @@ -102,7 +102,19 @@ static inline int next_token_2(const char **token, const char **c) { return 0; } -static int asn1_extract(const char *spec, void *out, asn_TYPE_descriptor_t *type, void *element) { +int cb(const void *buf, size_t s, void *app_key) { + struct output_buffer *out = app_key; + + if (out->buf_size - out->used < s) + return -1; + memcpy(out->buf + out->used, buf, s); + out->used += s; + return 0; +} + +static int asn1_extract(const char *spec, struct output_buffer *out, asn_TYPE_descriptor_t *type, + void *element) +{ const char *token, *c; int token_len, i, num; asn_TYPE_member_t *member; @@ -181,14 +193,7 @@ found_element: if (type->elements_count) goto out; - if (type == &asn_DEF_INTEGER) { - if (asn_INTEGER2long(element, out)) - goto error; - } - else if (!type->specifics) { - /* primitive integer */ - *((long *) out) = *((long *) element); - } + type->print_struct(type, element, 0, cb, out); out: return 0; @@ -199,13 +204,13 @@ error: -int tcap_extract(const char *buf, size_t len, const char *spec, void *out) { +int tcap_extract(const char *buf, size_t len, const char *spec, struct output_buffer *out) { return asn1_extract(spec, out, &asn_DEF_TCMessage, tcap_decode(buf, len)); } -int inap_extract(const char *buf, size_t len, const char *spec, void *out) { +int inap_extract(const char *buf, size_t len, const char *spec, struct output_buffer *out) { TCMessage_t *tcm; ComponentPortion_t *cp; Component_t *cmp; diff --git a/tests/basic.c b/tests/basic.c index 68be8f7..957e55a 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -10,93 +10,27 @@ const int tcap_len = sizeof(tcap) - 1; int main() { - TCMessage_t *tcm; - ComponentPortion_t *components = 0; - Component_t *component; int i; - void *arg; - asn_TYPE_descriptor_t *type; - long l; + struct output_buffer out; + char buf[256]; - tcm = tcap_decode(tcap, tcap_len); + OUTPUT_BUFFER_INIT(&out, buf); + i = tcap_extract(tcap, tcap_len, "end.components.1.invoke.opCode.localValue", &out); + printf("tcap_extract opcode: returned %i, value %.*s\n", i, (int) out.used, out.buf); - printf("TCMessage: %p\n", tcm); - - switch (tcm->present) { - case TCMessage_PR_NOTHING: - printf("nothing\n"); - break; - - case TCMessage_PR_unidirectional: - printf("unidirectional\n"); - components = &tcm->choice.unidirectional.components; - break; - - case TCMessage_PR_begin: - printf("begin\n"); - components = tcm->choice.begin.components; - break; - - case TCMessage_PR_end: - printf("end\n"); - components = tcm->choice.end.components; - break; - - case TCMessage_PR_continue: - printf("continue\n"); - components = tcm->choice.Continue.components; - break; - - case TCMessage_PR_abort: - printf("abort\n"); - break; - } - - if (components) { - printf("%i components\n", components->list.count); - - for (i = 0; i < components->list.count; i++) { - printf("Component #%i\n", i); - - component = components->list.array[i]; - - switch (component->present) { - case Component_PR_NOTHING: - printf("nothing\n"); - break; - - case Component_PR_invoke: - printf("invoke\n"); - arg = inap_decode(&component->choice.invoke, &type); - printf("arg: type %s -> %p\n", type ? type->name : "n/a", arg); - break; - - case Component_PR_returnResultLast: - printf("returnResultLast\n"); - break; - - case Component_PR_returnError: - printf("returnError\n"); - break; - - case Component_PR_reject: - printf("reject\n"); - break; + i = inap_extract(tcap, tcap_len, "ConnectArg", NULL); + printf("inap_extract ConnectArg: returned %i\n", i); - case Component_PR_returnResultNotLast: - printf("returnResultNotLast\n"); - break; - } - } - } + OUTPUT_BUFFER_INIT(&out, buf); + i = inap_extract(tcap, tcap_len, "ConnectArg.cutAndPaste", &out); + printf("inap_extract ConnectArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); - i = tcap_extract(tcap, tcap_len, "end.components.1.invoke.opCode.localValue", &l); - printf("tcap_extract opcode: returned %i, value %li\n", i, l); + i = inap_extract(tcap, tcap_len, "ConnectArg.destinationRoutingAddress", NULL); + printf("inap_extract ConnectArg.destinationRoutingAddress: returned %i\n", i); - i = inap_extract(tcap, tcap_len, "ConnectArg", NULL); - printf("inap_extract ConnectArg: returned %i\n", i); - i = inap_extract(tcap, tcap_len, "ConnectArg.cutAndPaste", &l); - printf("inap_extract ConnectArg: returned %i, value %li\n", i, l); + OUTPUT_BUFFER_INIT(&out, buf); + i = inap_extract(tcap, tcap_len, "ConnectArg.destinationRoutingAddress.0", &out); + printf("inap_extract ConnectArg: returned %i, value %.*s\n", i, (int) out.used, out.buf); return 0; }