remove gcc34
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / asn1 / gen_encode.c
blobba50d5da4c0a5fdc877d08404f01e3e88348dc42
1 /*
2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "gen_locl.h"
36 RCSID("$Id: gen_encode.c,v 1.12 2001/09/25 13:39:26 assar Exp $");
38 static void
39 encode_primitive (const char *typename, const char *name)
41 fprintf (codefile,
42 "e = encode_%s(p, len, %s, &l);\n"
43 "BACK;\n",
44 typename,
45 name);
48 static void
49 encode_type (const char *name, const Type *t)
51 switch (t->type) {
52 case TType:
53 #if 0
54 encode_type (name, t->symbol->type);
55 #endif
56 fprintf (codefile,
57 "e = encode_%s(p, len, %s, &l);\n"
58 "BACK;\n",
59 t->symbol->gen_name, name);
60 break;
61 case TInteger:
62 if(t->members == NULL)
63 encode_primitive ("integer", name);
64 else {
65 char *s;
66 asprintf(&s, "(const int*)%s", name);
67 if(s == NULL)
68 errx(1, "out of memory");
69 encode_primitive ("integer", s);
70 free(s);
72 break;
73 case TUInteger:
74 encode_primitive ("unsigned", name);
75 break;
76 case TOctetString:
77 encode_primitive ("octet_string", name);
78 break;
79 case TOID :
80 encode_primitive ("oid", name);
81 break;
82 case TBitString: {
83 Member *m;
84 int pos;
85 int rest;
86 int tag = -1;
88 if (t->members == NULL)
89 break;
91 fprintf (codefile, "{\n"
92 "unsigned char c = 0;\n");
93 pos = t->members->prev->val;
94 /* fix for buggy MIT (and OSF?) code */
95 if (pos > 31)
96 abort ();
98 * It seems that if we do not always set pos to 31 here, the MIT
99 * code will do the wrong thing.
101 * I hate ASN.1 (and DER), but I hate it even more when everybody
102 * has to screw it up differently.
104 pos = 31;
105 rest = 7 - (pos % 8);
107 for (m = t->members->prev; m && tag != m->val; m = m->prev) {
108 while (m->val / 8 < pos / 8) {
109 fprintf (codefile,
110 "*p-- = c; len--; ret++;\n"
111 "c = 0;\n");
112 pos -= 8;
114 fprintf (codefile,
115 "if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
116 7 - m->val % 8);
118 if (tag == -1)
119 tag = m->val;
122 fprintf (codefile,
123 "*p-- = c;\n"
124 "*p-- = %d;\n"
125 "len -= 2;\n"
126 "ret += 2;\n"
127 "}\n\n"
128 "e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
129 "UT_BitString, &l);\n"
130 "BACK;\n",
131 rest);
132 break;
134 case TEnumerated : {
135 encode_primitive ("enumerated", name);
136 break;
138 case TSequence: {
139 Member *m;
140 int tag = -1;
142 if (t->members == NULL)
143 break;
145 for (m = t->members->prev; m && tag != m->val; m = m->prev) {
146 char *s;
148 asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
149 if (m->optional)
150 fprintf (codefile,
151 "if(%s)\n",
153 #if 1
154 fprintf (codefile, "{\n"
155 "int oldret = ret;\n"
156 "ret = 0;\n");
157 #endif
158 encode_type (s, m->type);
159 fprintf (codefile,
160 "e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, "
161 "%d, &l);\n"
162 "BACK;\n",
163 m->val);
164 #if 1
165 fprintf (codefile,
166 "ret += oldret;\n"
167 "}\n");
168 #endif
169 if (tag == -1)
170 tag = m->val;
171 free (s);
173 fprintf (codefile,
174 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
175 "BACK;\n");
176 break;
178 case TSequenceOf: {
179 char *n;
181 fprintf (codefile,
182 "for(i = (%s)->len - 1; i >= 0; --i) {\n"
183 #if 1
184 "int oldret = ret;\n"
185 "ret = 0;\n",
186 #else
188 #endif
189 name);
190 asprintf (&n, "&(%s)->val[i]", name);
191 encode_type (n, t->subtype);
192 fprintf (codefile,
193 #if 1
194 "ret += oldret;\n"
195 #endif
196 "}\n"
197 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
198 "BACK;\n");
199 free (n);
200 break;
202 case TGeneralizedTime:
203 encode_primitive ("generalized_time", name);
204 break;
205 case TGeneralString:
206 encode_primitive ("general_string", name);
207 break;
208 case TApplication:
209 encode_type (name, t->subtype);
210 fprintf (codefile,
211 "e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n"
212 "BACK;\n",
213 t->application);
214 break;
215 default:
216 abort ();
220 void
221 generate_type_encode (const Symbol *s)
223 fprintf (headerfile,
224 "int "
225 "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
226 s->gen_name, s->gen_name);
228 fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
231 fprintf (codefile, "int\n"
232 "encode_%s(unsigned char *p, size_t len,"
233 " const %s *data, size_t *size)\n"
234 "{\n",
235 s->gen_name, s->gen_name);
237 switch (s->type->type) {
238 case TInteger:
239 case TUInteger:
240 case TOctetString:
241 case TGeneralizedTime:
242 case TGeneralString:
243 case TBitString:
244 case TEnumerated:
245 case TOID:
246 case TSequence:
247 case TSequenceOf:
248 case TApplication:
249 case TType:
250 fprintf (codefile,
251 "size_t ret = 0;\n"
252 "size_t l;\n"
253 "int i, e;\n\n");
254 fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
256 encode_type("data", s->type);
258 fprintf (codefile, "*size = ret;\n"
259 "return 0;\n");
260 break;
261 default:
262 abort ();
264 fprintf (codefile, "}\n\n");