blob: 77b270c355bd0866407af980729d0b6c06a8d7eb [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5/*
6 * Declarations internally useful for the ASN.1 support code.
7 */
8#ifndef ASN_INTERNAL_H
9#define ASN_INTERNAL_H
10#ifndef __EXTENSIONS__
11#define __EXTENSIONS__ /* for Sun */
12#endif
13
14#include "asn_application.h" /* Application-visible API */
15
16#ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */
17#include <assert.h> /* for assert() macro */
18#endif
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* Environment version might be used to avoid running with the old library */
25#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
26int get_asn1c_environment_version(void); /* Run-time version */
27
28#define CALLOC(nmemb, size) calloc(nmemb, size)
29#define MALLOC(size) malloc(size)
30#define REALLOC(oldptr, size) realloc(oldptr, size)
31#define FREEMEM(ptr) free(ptr)
32
33#define asn_debug_indent 0
34#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
35
36#ifdef EMIT_ASN_DEBUG
37#warning "Use ASN_EMIT_DEBUG instead of EMIT_ASN_DEBUG"
38#define ASN_EMIT_DEBUG EMIT_ASN_DEBUG
39#endif
40
41/*
42 * A macro for debugging the ASN.1 internals.
43 * You may enable or override it.
44 */
45#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
46#if ASN_EMIT_DEBUG == 1 /* And it was asked to emit this code... */
47#if __STDC_VERSION__ >= 199901L
48#ifdef ASN_THREAD_SAFE
49/* Thread safety requires sacrifice in output indentation:
50 * Retain empty definition of ASN_DEBUG_INDENT_ADD. */
51#else /* !ASN_THREAD_SAFE */
52#undef ASN_DEBUG_INDENT_ADD
53#undef asn_debug_indent
54int asn_debug_indent;
55#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
56#endif /* ASN_THREAD_SAFE */
57#define ASN_DEBUG(fmt, args...) do { \
58 int adi = asn_debug_indent; \
59 while(adi--) fprintf(stderr, " "); \
60 fprintf(stderr, fmt, ##args); \
61 fprintf(stderr, " (%s:%d)\n", \
62 __FILE__, __LINE__); \
63 } while(0)
64#else /* !C99 */
65void CC_PRINTFLIKE(1, 2) ASN_DEBUG_f(const char *fmt, ...);
66#define ASN_DEBUG ASN_DEBUG_f
67#endif /* C99 */
68#else /* ASN_EMIT_DEBUG != 1 */
69#if __STDC_VERSION__ >= 199901L
70#define ASN_DEBUG(...) do{}while(0)
71#else /* not C99 */
72static void CC_PRINTFLIKE(1, 2) ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
73#endif /* C99 or better */
74#endif /* ASN_EMIT_DEBUG */
75#endif /* ASN_DEBUG */
76
77/*
78 * Print to a callback.
79 * The callback is expected to return negative values on error.
80 * 0 and positive values are treated as success.
81 * RETURN VALUES:
82 * -1: Failed to format or invoke the callback.
83 * >0: Size of the data that got delivered to the callback.
84 */
85ssize_t CC_PRINTFLIKE(3, 4)
86asn__format_to_callback(
87 int (*callback)(const void *, size_t, void *key), void *key,
88 const char *fmt, ...);
89
90/*
91 * Invoke the application-supplied callback and fail, if something is wrong.
92 */
93#define ASN__E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
94#define ASN__E_CALLBACK(size, foo) \
95 do { \
96 if(foo) goto cb_failed; \
97 er.encoded += (size); \
98 } while(0)
99#define ASN__CALLBACK(buf, size) ASN__E_CALLBACK(size, ASN__E_cbc(buf, size))
100#define ASN__CALLBACK2(buf1, size1, buf2, size2) \
101 ASN__E_CALLBACK((size1) + (size2), \
102 ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
103#define ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
104 ASN__E_CALLBACK((size1) + (size2) + (size3), \
105 ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2) \
106 || ASN__E_cbc(buf3, size3))
107
108#define ASN__TEXT_INDENT(nl, level) \
109 do { \
110 int tmp_level = (level); \
111 int tmp_nl = ((nl) != 0); \
112 int tmp_i; \
113 if(tmp_nl) ASN__CALLBACK("\n", 1); \
114 if(tmp_level < 0) tmp_level = 0; \
115 for(tmp_i = 0; tmp_i < tmp_level; tmp_i++) ASN__CALLBACK(" ", 4); \
116 } while(0)
117
118#define _i_INDENT(nl) do { \
119 int tmp_i; \
120 if((nl) && cb("\n", 1, app_key) < 0) \
121 return -1; \
122 for(tmp_i = 0; tmp_i < ilevel; tmp_i++) \
123 if(cb(" ", 4, app_key) < 0) \
124 return -1; \
125 } while(0)
126
127/*
128 * Check stack against overflow, if limit is set.
129 */
130#define ASN__DEFAULT_STACK_MAX (30000)
131static int CC_NOTUSED
132ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
133 if(ctx && ctx->max_stack_size) {
134
135 /* ctx MUST be allocated on the stack */
136 ptrdiff_t usedstack = ((const char *)ctx - (const char *)&ctx);
137 if(usedstack > 0) usedstack = -usedstack; /* grows up! */
138
139 /* double negative required to avoid int wrap-around */
140 if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
141 ASN_DEBUG("Stack limit %ld reached",
142 (long)ctx->max_stack_size);
143 return -1;
144 }
145 }
146 return 0;
147}
148
149#ifdef __cplusplus
150}
151#endif
152
153#endif /* ASN_INTERNAL_H */