2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
36 RCSID("$Id: gen_encode.c,v 1.12 2001/09/25 13:39:26 assar Exp $");
39 encode_primitive (const char *typename, const char *name)
42 "e = encode_%s(p, len, %s, &l);\n"
49 encode_type (const char *name, const Type *t)
54 encode_type (name, t->symbol->type);
57 "e = encode_%s(p, len, %s, &l);\n"
59 t->symbol->gen_name, name);
62 if(t->members == NULL)
63 encode_primitive ("integer", name);
66 asprintf(&s, "(const int*)%s", name);
68 errx(1, "out of memory");
69 encode_primitive ("integer", s);
74 encode_primitive ("unsigned", name);
77 encode_primitive ("octet_string", name);
80 encode_primitive ("oid", name);
88 if (t->members == NULL)
91 fprintf (codefile, "{\n"
92 "unsigned char c = 0;\n");
93 pos = t->members->prev->val;
94 /* fix for buggy MIT (and OSF?) code */
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.
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) {
110 "*p-- = c; len--; ret++;\n"
115 "if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
128 "e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
129 "UT_BitString, &l);\n"
135 encode_primitive ("enumerated", name);
142 if (t->members == NULL)
145 for (m = t->members->prev; m && tag != m->val; m = m->prev) {
148 asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
154 fprintf (codefile, "{\n"
155 "int oldret = ret;\n"
158 encode_type (s, m->type);
160 "e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, "
174 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
182 "for(i = (%s)->len - 1; i >= 0; --i) {\n"
184 "int oldret = ret;\n"
190 asprintf (&n, "&(%s)->val[i]", name);
191 encode_type (n, t->subtype);
197 "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
202 case TGeneralizedTime:
203 encode_primitive ("generalized_time", name);
206 encode_primitive ("general_string", name);
209 encode_type (name, t->subtype);
211 "e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n"
221 generate_type_encode (const Symbol *s)
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"
235 s->gen_name, s->gen_name);
237 switch (s->type->type) {
241 case TGeneralizedTime:
254 fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
256 encode_type("data", s->type);
258 fprintf (codefile, "*size = ret;\n"
264 fprintf (codefile, "}\n\n");