gen_length.c revision 72445
155682Smarkm/* 272445Sassar * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "gen_locl.h" 3555682Smarkm 3672445SassarRCSID("$Id: gen_length.c,v 1.10 2000/06/21 22:40:53 assar Exp $"); 3755682Smarkm 3855682Smarkmstatic void 3955682Smarkmlength_primitive (const char *typename, 4055682Smarkm const char *name, 4155682Smarkm const char *variable) 4255682Smarkm{ 4355682Smarkm fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name); 4455682Smarkm} 4555682Smarkm 4655682Smarkmstatic void 4755682Smarkmlength_type (const char *name, const Type *t, const char *variable) 4855682Smarkm{ 4972445Sassar switch (t->type) { 5072445Sassar case TType: 5155682Smarkm#if 0 5272445Sassar length_type (name, t->symbol->type); 5355682Smarkm#endif 5472445Sassar fprintf (codefile, "%s += length_%s(%s);\n", 5572445Sassar variable, t->symbol->gen_name, name); 5672445Sassar break; 5772445Sassar case TInteger: 5872445Sassar if(t->members == NULL) 5972445Sassar length_primitive ("integer", name, variable); 6072445Sassar else { 6172445Sassar char *s; 6272445Sassar asprintf(&s, "(const int*)%s", name); 6372445Sassar if(s == NULL) 6472445Sassar errx (1, "out of memory"); 6572445Sassar length_primitive ("integer", s, variable); 6672445Sassar free(s); 6772445Sassar } 6872445Sassar break; 6972445Sassar case TUInteger: 7072445Sassar length_primitive ("unsigned", name, variable); 7172445Sassar break; 7272445Sassar case TOctetString: 7372445Sassar length_primitive ("octet_string", name, variable); 7472445Sassar break; 7572445Sassar case TBitString: { 7672445Sassar /* 7772445Sassar * XXX - Hope this is correct 7872445Sassar * look at TBitString case in `encode_type' 7972445Sassar */ 8072445Sassar fprintf (codefile, "%s += 7;\n", variable); 8172445Sassar break; 8272445Sassar } 8372445Sassar case TSequence: { 8472445Sassar Member *m; 8572445Sassar int tag = -1; 8655682Smarkm 8772445Sassar if (t->members == NULL) 8872445Sassar break; 8955682Smarkm 9072445Sassar for (m = t->members; m && tag != m->val; m = m->next) { 9172445Sassar char *s; 9255682Smarkm 9372445Sassar asprintf (&s, "%s(%s)->%s", 9472445Sassar m->optional ? "" : "&", name, m->gen_name); 9572445Sassar if (m->optional) 9672445Sassar fprintf (codefile, "if(%s)", s); 9772445Sassar fprintf (codefile, "{\n" 9872445Sassar "int oldret = %s;\n" 9972445Sassar "%s = 0;\n", variable, variable); 10072445Sassar length_type (s, m->type, "ret"); 10172445Sassar fprintf (codefile, "%s += 1 + length_len(%s) + oldret;\n", 10272445Sassar variable, variable); 10372445Sassar fprintf (codefile, "}\n"); 10472445Sassar if (tag == -1) 10572445Sassar tag = m->val; 10672445Sassar free (s); 10772445Sassar } 10872445Sassar fprintf (codefile, 10972445Sassar "%s += 1 + length_len(%s);\n", variable, variable); 11072445Sassar break; 11172445Sassar } 11272445Sassar case TSequenceOf: { 11372445Sassar char *n; 11455682Smarkm 11572445Sassar fprintf (codefile, 11672445Sassar "{\n" 11772445Sassar "int oldret = %s;\n" 11872445Sassar "int i;\n" 11972445Sassar "%s = 0;\n", 12072445Sassar variable, variable); 12155682Smarkm 12272445Sassar fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name); 12372445Sassar asprintf (&n, "&(%s)->val[i]", name); 12472445Sassar length_type(n, t->subtype, variable); 12572445Sassar fprintf (codefile, "}\n"); 12655682Smarkm 12772445Sassar fprintf (codefile, 12872445Sassar "%s += 1 + length_len(%s) + oldret;\n" 12972445Sassar "}\n", variable, variable); 13072445Sassar free(n); 13172445Sassar break; 13272445Sassar } 13372445Sassar case TGeneralizedTime: 13472445Sassar length_primitive ("generalized_time", name, variable); 13572445Sassar break; 13672445Sassar case TGeneralString: 13772445Sassar length_primitive ("general_string", name, variable); 13872445Sassar break; 13972445Sassar case TApplication: 14072445Sassar length_type (name, t->subtype, variable); 14172445Sassar fprintf (codefile, "ret += 1 + length_len (ret);\n"); 14272445Sassar break; 14372445Sassar default : 14472445Sassar abort (); 14572445Sassar } 14655682Smarkm} 14755682Smarkm 14855682Smarkmvoid 14955682Smarkmgenerate_type_length (const Symbol *s) 15055682Smarkm{ 15155682Smarkm fprintf (headerfile, 15255682Smarkm "size_t length_%s(const %s *);\n", 15355682Smarkm s->gen_name, s->gen_name); 15455682Smarkm 15555682Smarkm fprintf (codefile, 15655682Smarkm "size_t\n" 15755682Smarkm "length_%s(const %s *data)\n" 15855682Smarkm "{\n" 15955682Smarkm "size_t ret = 0;\n", 16055682Smarkm s->gen_name, s->gen_name); 16155682Smarkm 16255682Smarkm length_type ("data", s->type, "ret"); 16355682Smarkm fprintf (codefile, "return ret;\n}\n\n"); 16455682Smarkm} 16555682Smarkm 166