gen_length.c revision 55682
1/*
2 * Copyright (c) 1997 - 1999 Kungliga Tekniska H�gskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
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.
16 *
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.
20 *
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.
32 */
33
34#include "gen_locl.h"
35
36RCSID("$Id: gen_length.c,v 1.7 1999/12/02 17:05:02 joda Exp $");
37
38static void
39length_primitive (const char *typename,
40		  const char *name,
41		  const char *variable)
42{
43    fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
44}
45
46static void
47length_type (const char *name, const Type *t, const char *variable)
48{
49  switch (t->type) {
50  case TType:
51#if 0
52      length_type (name, t->symbol->type);
53#endif
54      fprintf (codefile, "%s += length_%s(%s);\n",
55	       variable, t->symbol->gen_name, name);
56      break;
57  case TInteger:
58      length_primitive ("integer", name, variable);
59      break;
60  case TOctetString:
61      length_primitive ("octet_string", name, variable);
62      break;
63  case TBitString: {
64      /*
65       * XXX - Hope this is correct
66       * look at TBitString case in `encode_type'
67       */
68      fprintf (codefile, "%s += 7;\n", variable);
69      break;
70  }
71  case TSequence: {
72      Member *m;
73      int tag = -1;
74
75      if (t->members == NULL)
76	  break;
77
78      for (m = t->members; m && tag != m->val; m = m->next) {
79	  char *s;
80
81	  asprintf (&s, "%s(%s)->%s",
82		    m->optional ? "" : "&", name, m->gen_name);
83	  if (m->optional)
84	      fprintf (codefile, "if(%s)", s);
85	  fprintf (codefile, "{\n"
86		   "int oldret = %s;\n"
87		   "%s = 0;\n", variable, variable);
88	  length_type (s, m->type, "ret");
89	  fprintf (codefile, "%s += 1 + length_len(%s) + oldret;\n",
90		   variable, variable);
91	  fprintf (codefile, "}\n");
92	  if (tag == -1)
93	      tag = m->val;
94	  free (s);
95      }
96      fprintf (codefile,
97	       "%s += 1 + length_len(%s);\n", variable, variable);
98      break;
99  }
100  case TSequenceOf: {
101      char *n;
102
103      fprintf (codefile,
104	       "{\n"
105	       "int oldret = %s;\n"
106	       "int i;\n"
107	       "%s = 0;\n",
108	       variable, variable);
109
110      fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
111      asprintf (&n, "&(%s)->val[i]", name);
112      length_type(n, t->subtype, variable);
113      fprintf (codefile, "}\n");
114
115      fprintf (codefile,
116	       "%s += 1 + length_len(%s) + oldret;\n"
117	       "}\n", variable, variable);
118      free(n);
119      break;
120  }
121  case TGeneralizedTime:
122      length_primitive ("generalized_time", name, variable);
123      break;
124  case TGeneralString:
125      length_primitive ("general_string", name, variable);
126      break;
127  case TApplication:
128      length_type (name, t->subtype, variable);
129      fprintf (codefile, "ret += 1 + length_len (ret);\n");
130      break;
131  default :
132      abort ();
133  }
134}
135
136void
137generate_type_length (const Symbol *s)
138{
139  fprintf (headerfile,
140	   "size_t length_%s(const %s *);\n",
141	   s->gen_name, s->gen_name);
142
143  fprintf (codefile,
144	   "size_t\n"
145	   "length_%s(const %s *data)\n"
146	   "{\n"
147	   "size_t ret = 0;\n",
148	   s->gen_name, s->gen_name);
149
150  length_type ("data", s->type, "ret");
151  fprintf (codefile, "return ret;\n}\n\n");
152}
153
154