blob: e6da3fe60e6986b5841ff9d84b187f6eca598edb [file] [log] [blame]
Harald Welte92c45f32010-06-12 18:59:38 +02001/*-
Harald Welteec0e2172010-07-20 00:03:44 +02002 * Copyright (c) 2003, 2004, 2005, 2007 Lev Walkin <vlm@lionet.info>.
Harald Welte92c45f32010-06-12 18:59:38 +02003 * All rights reserved.
4 * Redistribution and modifications are permitted subject to BSD license.
5 */
6/*
7 * Declarations internally useful for the ASN.1 support code.
8 */
9#ifndef _ASN_INTERNAL_H_
10#define _ASN_INTERNAL_H_
11
12#include "asn_application.h" /* Application-visible API */
13
14#ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */
15#include <assert.h> /* for assert() macro */
16#endif
17
Harald Weltea68b3a32011-10-14 20:35:00 +020018#include <osmocom/core/talloc.h>
Harald Weltefa034002010-07-18 23:15:24 +020019
Harald Welte92c45f32010-06-12 18:59:38 +020020#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* Environment version might be used to avoid running with the old library */
Harald Welteec0e2172010-07-20 00:03:44 +020025#define ASN1C_ENVIRONMENT_VERSION 922 /* Compile-time version */
Harald Welte92c45f32010-06-12 18:59:38 +020026int get_asn1c_environment_version(void); /* Run-time version */
27
Harald Weltefa034002010-07-18 23:15:24 +020028extern void *talloc_asn1_ctx;
29
Harald Welte6264d3d2010-07-18 23:30:11 +020030#define CALLOC(nmemb, size) talloc_zero_size(talloc_asn1_ctx, (nmemb) * (size))
Harald Weltefa034002010-07-18 23:15:24 +020031#define MALLOC(size) talloc_size(talloc_asn1_ctx, size)
32#define REALLOC(oldptr, size) talloc_realloc_size(talloc_asn1_ctx, oldptr, size)
33#define FREEMEM(ptr) talloc_free(ptr)
Harald Welte92c45f32010-06-12 18:59:38 +020034
35/*
36 * A macro for debugging the ASN.1 internals.
37 * You may enable or override it.
38 */
39#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
40#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
41#ifdef __GNUC__
Harald Welteec0e2172010-07-20 00:03:44 +020042#ifdef ASN_THREAD_SAFE
43#define asn_debug_indent 0
44#else /* !ASN_THREAD_SAFE */
45int asn_debug_indent;
46#endif /* ASN_THREAD_SAFE */
47#define ASN_DEBUG(fmt, args...) do { \
48 int adi = asn_debug_indent; \
49 while(adi--) fprintf(stderr, " "); \
50 fprintf(stderr, fmt, ##args); \
51 fprintf(stderr, " (%s:%d)\n", \
52 __FILE__, __LINE__); \
Harald Welte92c45f32010-06-12 18:59:38 +020053 } while(0)
54#else /* !__GNUC__ */
55void ASN_DEBUG_f(const char *fmt, ...);
56#define ASN_DEBUG ASN_DEBUG_f
57#endif /* __GNUC__ */
58#else /* EMIT_ASN_DEBUG != 1 */
59static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
60#endif /* EMIT_ASN_DEBUG */
61#endif /* ASN_DEBUG */
62
63/*
64 * Invoke the application-supplied callback and fail, if something is wrong.
65 */
66#define __ASN_E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
67#define _ASN_E_CALLBACK(foo) do { \
68 if(foo) goto cb_failed; \
69 } while(0)
70#define _ASN_CALLBACK(buf, size) \
71 _ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
72#define _ASN_CALLBACK2(buf1, size1, buf2, size2) \
73 _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
74#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
75 _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) \
76 || __ASN_E_cbc(buf2, size2) \
77 || __ASN_E_cbc(buf3, size3))
78
79#define _i_ASN_TEXT_INDENT(nl, level) do { \
80 int __level = (level); \
81 int __nl = ((nl) != 0); \
82 int __i; \
83 if(__nl) _ASN_CALLBACK("\n", 1); \
Harald Welteec0e2172010-07-20 00:03:44 +020084 if(__level < 0) __level = 0; \
Harald Welte92c45f32010-06-12 18:59:38 +020085 for(__i = 0; __i < __level; __i++) \
86 _ASN_CALLBACK(" ", 4); \
87 er.encoded += __nl + 4 * __level; \
88} while(0)
89
90#define _i_INDENT(nl) do { \
91 int __i; \
92 if((nl) && cb("\n", 1, app_key) < 0) return -1; \
93 for(__i = 0; __i < ilevel; __i++) \
94 if(cb(" ", 4, app_key) < 0) return -1; \
95} while(0)
96
97/*
98 * Check stack against overflow, if limit is set.
99 */
100#define _ASN_DEFAULT_STACK_MAX (30000)
101static inline int
102_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
103 if(ctx && ctx->max_stack_size) {
104
105 /* ctx MUST be allocated on the stack */
106 ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx);
107 if(usedstack > 0) usedstack = -usedstack; /* grows up! */
108
109 /* double negative required to avoid int wrap-around */
110 if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
111 ASN_DEBUG("Stack limit %ld reached",
112 (long)ctx->max_stack_size);
113 return -1;
114 }
115 }
116 return 0;
117}
118
119#ifdef __cplusplus
120}
121#endif
122
123#endif /* _ASN_INTERNAL_H_ */