gen_encode.c revision 178825
1252190Srpaulo/* 2252190Srpaulo * Copyright (c) 1997 - 2006 Kungliga Tekniska H�gskolan 3252190Srpaulo * (Royal Institute of Technology, Stockholm, Sweden). 4252190Srpaulo * All rights reserved. 5252190Srpaulo * 6252190Srpaulo * Redistribution and use in source and binary forms, with or without 7252190Srpaulo * modification, are permitted provided that the following conditions 8252190Srpaulo * are met: 9252190Srpaulo * 10252190Srpaulo * 1. Redistributions of source code must retain the above copyright 11252190Srpaulo * notice, this list of conditions and the following disclaimer. 12252190Srpaulo * 13252190Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 14252190Srpaulo * notice, this list of conditions and the following disclaimer in the 15252190Srpaulo * documentation and/or other materials provided with the distribution. 16252190Srpaulo * 17252190Srpaulo * 3. Neither the name of the Institute nor the names of its contributors 18252190Srpaulo * may be used to endorse or promote products derived from this software 19252190Srpaulo * without specific prior written permission. 20252190Srpaulo * 21252190Srpaulo * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22252190Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23252190Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24252190Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25252190Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26252190Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27252190Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28252190Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29252190Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30252190Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31252190Srpaulo * SUCH DAMAGE. 32252190Srpaulo */ 33252190Srpaulo 34252190Srpaulo#include "gen_locl.h" 35252190Srpaulo 36252190SrpauloRCSID("$Id: gen_encode.c 22429 2008-01-13 10:25:50Z lha $"); 37252190Srpaulo 38252190Srpaulostatic void 39252190Srpauloencode_primitive (const char *typename, const char *name) 40252190Srpaulo{ 41252190Srpaulo fprintf (codefile, 42252190Srpaulo "e = der_put_%s(p, len, %s, &l);\n" 43252190Srpaulo "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 44252190Srpaulo typename, 45252190Srpaulo name); 46252190Srpaulo} 47252190Srpaulo 48252190Srpauloconst char * 49252190Srpauloclassname(Der_class class) 50252190Srpaulo{ 51252190Srpaulo const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL", 52252190Srpaulo "ASN1_C_CONTEXT", "ASN1_C_PRIV" }; 53252190Srpaulo if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE) 54252190Srpaulo return "???"; 55252190Srpaulo return cn[class]; 56252190Srpaulo} 57252190Srpaulo 58252190Srpaulo 59252190Srpauloconst char * 60252190Srpaulovaluename(Der_class class, int value) 61252190Srpaulo{ 62252190Srpaulo static char s[32]; 63252190Srpaulo struct { 64252190Srpaulo int value; 65252190Srpaulo const char *s; 66252190Srpaulo } *p, values[] = { 67252190Srpaulo#define X(Y) { Y, #Y } 68252190Srpaulo X(UT_BMPString), 69252190Srpaulo X(UT_BitString), 70252190Srpaulo X(UT_Boolean), 71252190Srpaulo X(UT_EmbeddedPDV), 72252190Srpaulo X(UT_Enumerated), 73252190Srpaulo X(UT_External), 74252190Srpaulo X(UT_GeneralString), 75252190Srpaulo X(UT_GeneralizedTime), 76252190Srpaulo X(UT_GraphicString), 77252190Srpaulo X(UT_IA5String), 78252190Srpaulo X(UT_Integer), 79252190Srpaulo X(UT_Null), 80252190Srpaulo X(UT_NumericString), 81252190Srpaulo X(UT_OID), 82252190Srpaulo X(UT_ObjectDescriptor), 83252190Srpaulo X(UT_OctetString), 84252190Srpaulo X(UT_PrintableString), 85252190Srpaulo X(UT_Real), 86252190Srpaulo X(UT_RelativeOID), 87252190Srpaulo X(UT_Sequence), 88252190Srpaulo X(UT_Set), 89252190Srpaulo X(UT_TeletexString), 90252190Srpaulo X(UT_UTCTime), 91252190Srpaulo X(UT_UTF8String), 92252190Srpaulo X(UT_UniversalString), 93252190Srpaulo X(UT_VideotexString), 94252190Srpaulo X(UT_VisibleString), 95252190Srpaulo#undef X 96252190Srpaulo { -1, NULL } 97252190Srpaulo }; 98252190Srpaulo if(class == ASN1_C_UNIV) { 99252190Srpaulo for(p = values; p->value != -1; p++) 100252190Srpaulo if(p->value == value) 101252190Srpaulo return p->s; 102252190Srpaulo } 103252190Srpaulo snprintf(s, sizeof(s), "%d", value); 104252190Srpaulo return s; 105252190Srpaulo} 106252190Srpaulo 107252190Srpaulostatic int 108252190Srpauloencode_type (const char *name, const Type *t, const char *tmpstr) 109252190Srpaulo{ 110252190Srpaulo int constructed = 1; 111252190Srpaulo 112252190Srpaulo switch (t->type) { 113252190Srpaulo case TType: 114252190Srpaulo#if 0 115252190Srpaulo encode_type (name, t->symbol->type); 116252190Srpaulo#endif 117252190Srpaulo fprintf (codefile, 118252190Srpaulo "e = encode_%s(p, len, %s, &l);\n" 119252190Srpaulo "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 120252190Srpaulo t->symbol->gen_name, name); 121252190Srpaulo break; 122252190Srpaulo case TInteger: 123252190Srpaulo if(t->members) { 124252190Srpaulo fprintf(codefile, 125252190Srpaulo "{\n" 126252190Srpaulo "int enumint = (int)*%s;\n", 127252190Srpaulo name); 128252190Srpaulo encode_primitive ("integer", "&enumint"); 129252190Srpaulo fprintf(codefile, "}\n;"); 130252190Srpaulo } else if (t->range == NULL) { 131252190Srpaulo encode_primitive ("heim_integer", name); 132252190Srpaulo } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) { 133252190Srpaulo encode_primitive ("integer", name); 134252190Srpaulo } else if (t->range->min == 0 && t->range->max == UINT_MAX) { 135252190Srpaulo encode_primitive ("unsigned", name); 136252190Srpaulo } else if (t->range->min == 0 && t->range->max == INT_MAX) { 137252190Srpaulo encode_primitive ("unsigned", name); 138252190Srpaulo } else 139252190Srpaulo errx(1, "%s: unsupported range %d -> %d", 140252190Srpaulo name, t->range->min, t->range->max); 141252190Srpaulo constructed = 0; 142252190Srpaulo break; 143252190Srpaulo case TBoolean: 144252190Srpaulo encode_primitive ("boolean", name); 145252190Srpaulo constructed = 0; 146252190Srpaulo break; 147252190Srpaulo case TOctetString: 148252190Srpaulo encode_primitive ("octet_string", name); 149252190Srpaulo constructed = 0; 150252190Srpaulo break; 151252190Srpaulo case TBitString: { 152252190Srpaulo Member *m; 153252190Srpaulo int pos; 154252190Srpaulo 155252190Srpaulo if (ASN1_TAILQ_EMPTY(t->members)) { 156252190Srpaulo encode_primitive("bit_string", name); 157252190Srpaulo constructed = 0; 158252190Srpaulo break; 159252190Srpaulo } 160252190Srpaulo 161252190Srpaulo fprintf (codefile, "{\n" 162252190Srpaulo "unsigned char c = 0;\n"); 163252190Srpaulo if (!rfc1510_bitstring) 164252190Srpaulo fprintf (codefile, 165252190Srpaulo "int rest = 0;\n" 166252190Srpaulo "int bit_set = 0;\n"); 167252190Srpaulo#if 0 168252190Srpaulo pos = t->members->prev->val; 169252190Srpaulo /* fix for buggy MIT (and OSF?) code */ 170252190Srpaulo if (pos > 31) 171252190Srpaulo abort (); 172252190Srpaulo#endif 173252190Srpaulo /* 174252190Srpaulo * It seems that if we do not always set pos to 31 here, the MIT 175252190Srpaulo * code will do the wrong thing. 176252190Srpaulo * 177252190Srpaulo * I hate ASN.1 (and DER), but I hate it even more when everybody 178252190Srpaulo * has to screw it up differently. 179252190Srpaulo */ 180252190Srpaulo pos = ASN1_TAILQ_LAST(t->members, memhead)->val; 181252190Srpaulo if (rfc1510_bitstring) { 182252190Srpaulo if (pos < 31) 183252190Srpaulo pos = 31; 184252190Srpaulo } 185252190Srpaulo 186252190Srpaulo ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 187252190Srpaulo while (m->val / 8 < pos / 8) { 188252190Srpaulo if (!rfc1510_bitstring) 189252190Srpaulo fprintf (codefile, 190252190Srpaulo "if (c != 0 || bit_set) {\n"); 191252190Srpaulo fprintf (codefile, 192252190Srpaulo "if (len < 1) return ASN1_OVERFLOW;\n" 193252190Srpaulo "*p-- = c; len--; ret++;\n"); 194252190Srpaulo if (!rfc1510_bitstring) 195252190Srpaulo fprintf (codefile, 196252190Srpaulo "if (!bit_set) {\n" 197252190Srpaulo "rest = 0;\n" 198252190Srpaulo "while(c) { \n" 199252190Srpaulo "if (c & 1) break;\n" 200252190Srpaulo "c = c >> 1;\n" 201252190Srpaulo "rest++;\n" 202252190Srpaulo "}\n" 203252190Srpaulo "bit_set = 1;\n" 204252190Srpaulo "}\n" 205252190Srpaulo "}\n"); 206252190Srpaulo fprintf (codefile, 207252190Srpaulo "c = 0;\n"); 208252190Srpaulo pos -= 8; 209252190Srpaulo } 210252190Srpaulo fprintf (codefile, 211252190Srpaulo "if((%s)->%s) {\n" 212252190Srpaulo "c |= 1<<%d;\n", 213252190Srpaulo name, m->gen_name, 7 - m->val % 8); 214252190Srpaulo fprintf (codefile, 215252190Srpaulo "}\n"); 216252190Srpaulo } 217252190Srpaulo 218252190Srpaulo if (!rfc1510_bitstring) 219252190Srpaulo fprintf (codefile, 220252190Srpaulo "if (c != 0 || bit_set) {\n"); 221252190Srpaulo fprintf (codefile, 222252190Srpaulo "if (len < 1) return ASN1_OVERFLOW;\n" 223252190Srpaulo "*p-- = c; len--; ret++;\n"); 224252190Srpaulo if (!rfc1510_bitstring) 225252190Srpaulo fprintf (codefile, 226252190Srpaulo "if (!bit_set) {\n" 227252190Srpaulo "rest = 0;\n" 228252190Srpaulo "if(c) { \n" 229252190Srpaulo "while(c) { \n" 230252190Srpaulo "if (c & 1) break;\n" 231252190Srpaulo "c = c >> 1;\n" 232252190Srpaulo "rest++;\n" 233252190Srpaulo "}\n" 234252190Srpaulo "}\n" 235252190Srpaulo "}\n" 236252190Srpaulo "}\n"); 237252190Srpaulo 238252190Srpaulo fprintf (codefile, 239252190Srpaulo "if (len < 1) return ASN1_OVERFLOW;\n" 240252190Srpaulo "*p-- = %s;\n" 241252190Srpaulo "len -= 1;\n" 242252190Srpaulo "ret += 1;\n" 243252190Srpaulo "}\n\n", 244252190Srpaulo rfc1510_bitstring ? "0" : "rest"); 245252190Srpaulo constructed = 0; 246252190Srpaulo break; 247252190Srpaulo } 248252190Srpaulo case TEnumerated : { 249252190Srpaulo encode_primitive ("enumerated", name); 250252190Srpaulo constructed = 0; 251252190Srpaulo break; 252252190Srpaulo } 253252190Srpaulo 254252190Srpaulo case TSet: 255252190Srpaulo case TSequence: { 256252190Srpaulo Member *m; 257252190Srpaulo 258252190Srpaulo if (t->members == NULL) 259252190Srpaulo break; 260252190Srpaulo 261252190Srpaulo ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 262252190Srpaulo char *s; 263252190Srpaulo 264252190Srpaulo if (m->ellipsis) 265252190Srpaulo continue; 266252190Srpaulo 267252190Srpaulo asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); 268252190Srpaulo if (s == NULL) 269252190Srpaulo errx(1, "malloc"); 270252190Srpaulo fprintf(codefile, "/* %s */\n", m->name); 271252190Srpaulo if (m->optional) 272252190Srpaulo fprintf (codefile, 273252190Srpaulo "if(%s) ", 274252190Srpaulo s); 275252190Srpaulo else if(m->defval) 276252190Srpaulo gen_compare_defval(s + 1, m->defval); 277252190Srpaulo fprintf (codefile, "{\n"); 278252190Srpaulo fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr); 279252190Srpaulo fprintf (codefile, "ret = 0;\n"); 280252190Srpaulo encode_type (s, m->type, m->gen_name); 281252190Srpaulo fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 282252190Srpaulo fprintf (codefile, "}\n"); 283252190Srpaulo free (s); 284252190Srpaulo } 285252190Srpaulo break; 286252190Srpaulo } 287252190Srpaulo case TSetOf: { 288252190Srpaulo 289252190Srpaulo fprintf(codefile, 290252190Srpaulo "{\n" 291252190Srpaulo "struct heim_octet_string *val;\n" 292252190Srpaulo "size_t elen, totallen = 0;\n" 293252190Srpaulo "int eret;\n"); 294252190Srpaulo 295252190Srpaulo fprintf(codefile, 296252190Srpaulo "if ((%s)->len > UINT_MAX/sizeof(val[0]))\n" 297252190Srpaulo "return ERANGE;\n", 298252190Srpaulo name); 299252190Srpaulo 300252190Srpaulo fprintf(codefile, 301252190Srpaulo "val = malloc(sizeof(val[0]) * (%s)->len);\n" 302252190Srpaulo "if (val == NULL && (%s)->len != 0) return ENOMEM;\n", 303252190Srpaulo name, name); 304252190Srpaulo 305252190Srpaulo fprintf(codefile, 306252190Srpaulo "for(i = 0; i < (%s)->len; i++) {\n", 307252190Srpaulo name); 308252190Srpaulo 309252190Srpaulo fprintf(codefile, 310252190Srpaulo "ASN1_MALLOC_ENCODE(%s, val[i].data, " 311252190Srpaulo "val[i].length, &(%s)->val[i], &elen, eret);\n", 312252190Srpaulo t->subtype->symbol->gen_name, 313252190Srpaulo name); 314252190Srpaulo 315252190Srpaulo fprintf(codefile, 316252190Srpaulo "if(eret) {\n" 317252190Srpaulo "i--;\n" 318252190Srpaulo "while (i >= 0) {\n" 319252190Srpaulo "free(val[i].data);\n" 320252190Srpaulo "i--;\n" 321252190Srpaulo "}\n" 322252190Srpaulo "free(val);\n" 323252190Srpaulo "return eret;\n" 324252190Srpaulo "}\n" 325252190Srpaulo "totallen += elen;\n" 326252190Srpaulo "}\n"); 327252190Srpaulo 328252190Srpaulo fprintf(codefile, 329252190Srpaulo "if (totallen > len) {\n" 330252190Srpaulo "for (i = 0; i < (%s)->len; i++) {\n" 331252190Srpaulo "free(val[i].data);\n" 332252190Srpaulo "}\n" 333252190Srpaulo "free(val);\n" 334252190Srpaulo "return ASN1_OVERFLOW;\n" 335252190Srpaulo "}\n", 336252190Srpaulo name); 337252190Srpaulo 338252190Srpaulo fprintf(codefile, 339252190Srpaulo "qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n", 340252190Srpaulo name); 341252190Srpaulo 342252190Srpaulo fprintf (codefile, 343252190Srpaulo "for(i = (%s)->len - 1; i >= 0; --i) {\n" 344252190Srpaulo "p -= val[i].length;\n" 345252190Srpaulo "ret += val[i].length;\n" 346252190Srpaulo "memcpy(p + 1, val[i].data, val[i].length);\n" 347252190Srpaulo "free(val[i].data);\n" 348252190Srpaulo "}\n" 349252190Srpaulo "free(val);\n" 350252190Srpaulo "}\n", 351252190Srpaulo name); 352252190Srpaulo break; 353252190Srpaulo } 354252190Srpaulo case TSequenceOf: { 355252190Srpaulo char *n; 356252190Srpaulo char *sname; 357252190Srpaulo 358252190Srpaulo fprintf (codefile, 359252190Srpaulo "for(i = (%s)->len - 1; i >= 0; --i) {\n" 360252190Srpaulo "size_t %s_for_oldret = ret;\n" 361252190Srpaulo "ret = 0;\n", 362252190Srpaulo name, tmpstr); 363252190Srpaulo asprintf (&n, "&(%s)->val[i]", name); 364252190Srpaulo if (n == NULL) 365252190Srpaulo errx(1, "malloc"); 366252190Srpaulo asprintf (&sname, "%s_S_Of", tmpstr); 367252190Srpaulo if (sname == NULL) 368252190Srpaulo errx(1, "malloc"); 369252190Srpaulo encode_type (n, t->subtype, sname); 370252190Srpaulo fprintf (codefile, 371252190Srpaulo "ret += %s_for_oldret;\n" 372252190Srpaulo "}\n", 373252190Srpaulo tmpstr); 374252190Srpaulo free (n); 375252190Srpaulo free (sname); 376252190Srpaulo break; 377252190Srpaulo } 378252190Srpaulo case TGeneralizedTime: 379252190Srpaulo encode_primitive ("generalized_time", name); 380252190Srpaulo constructed = 0; 381252190Srpaulo break; 382252190Srpaulo case TGeneralString: 383252190Srpaulo encode_primitive ("general_string", name); 384252190Srpaulo constructed = 0; 385252190Srpaulo break; 386252190Srpaulo case TTag: { 387252190Srpaulo char *tname; 388252190Srpaulo int c; 389252190Srpaulo asprintf (&tname, "%s_tag", tmpstr); 390252190Srpaulo if (tname == NULL) 391252190Srpaulo errx(1, "malloc"); 392252190Srpaulo c = encode_type (name, t->subtype, tname); 393252190Srpaulo fprintf (codefile, 394252190Srpaulo "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n" 395252190Srpaulo "if (e) return e;\np -= l; len -= l; ret += l;\n\n", 396252190Srpaulo classname(t->tag.tagclass), 397252190Srpaulo c ? "CONS" : "PRIM", 398252190Srpaulo valuename(t->tag.tagclass, t->tag.tagvalue)); 399252190Srpaulo free (tname); 400252190Srpaulo break; 401252190Srpaulo } 402252190Srpaulo case TChoice:{ 403252190Srpaulo Member *m, *have_ellipsis = NULL; 404252190Srpaulo char *s; 405252190Srpaulo 406252190Srpaulo if (t->members == NULL) 407252190Srpaulo break; 408252190Srpaulo 409252190Srpaulo fprintf(codefile, "\n"); 410252190Srpaulo 411252190Srpaulo asprintf (&s, "(%s)", name); 412252190Srpaulo if (s == NULL) 413252190Srpaulo errx(1, "malloc"); 414252190Srpaulo fprintf(codefile, "switch(%s->element) {\n", s); 415252190Srpaulo 416252190Srpaulo ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { 417252190Srpaulo char *s2; 418252190Srpaulo 419252190Srpaulo if (m->ellipsis) { 420252190Srpaulo have_ellipsis = m; 421252190Srpaulo continue; 422252190Srpaulo } 423252190Srpaulo 424252190Srpaulo fprintf (codefile, "case %s: {", m->label); 425252190Srpaulo asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&", 426252190Srpaulo s, m->gen_name); 427252190Srpaulo if (s2 == NULL) 428252190Srpaulo errx(1, "malloc"); 429252190Srpaulo if (m->optional) 430252190Srpaulo fprintf (codefile, "if(%s) {\n", s2); 431252190Srpaulo fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr); 432252190Srpaulo fprintf (codefile, "ret = 0;\n"); 433252190Srpaulo constructed = encode_type (s2, m->type, m->gen_name); 434252190Srpaulo fprintf (codefile, "ret += %s_oldret;\n", tmpstr); 435252190Srpaulo if(m->optional) 436252190Srpaulo fprintf (codefile, "}\n"); 437252190Srpaulo fprintf(codefile, "break;\n"); 438252190Srpaulo fprintf(codefile, "}\n"); 439252190Srpaulo free (s2); 440252190Srpaulo } 441252190Srpaulo free (s); 442252190Srpaulo if (have_ellipsis) { 443252190Srpaulo fprintf(codefile, 444252190Srpaulo "case %s: {\n" 445252190Srpaulo "if (len < (%s)->u.%s.length)\n" 446252190Srpaulo "return ASN1_OVERFLOW;\n" 447252190Srpaulo "p -= (%s)->u.%s.length;\n" 448252190Srpaulo "ret += (%s)->u.%s.length;\n" 449252190Srpaulo "memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n" 450252190Srpaulo "break;\n" 451252190Srpaulo "}\n", 452252190Srpaulo have_ellipsis->label, 453252190Srpaulo name, have_ellipsis->gen_name, 454252190Srpaulo name, have_ellipsis->gen_name, 455252190Srpaulo name, have_ellipsis->gen_name, 456252190Srpaulo name, have_ellipsis->gen_name, 457252190Srpaulo name, have_ellipsis->gen_name); 458252190Srpaulo } 459252190Srpaulo fprintf(codefile, "};\n"); 460252190Srpaulo break; 461252190Srpaulo } 462252190Srpaulo case TOID: 463252190Srpaulo encode_primitive ("oid", name); 464252190Srpaulo constructed = 0; 465252190Srpaulo break; 466252190Srpaulo case TUTCTime: 467252190Srpaulo encode_primitive ("utctime", name); 468252190Srpaulo constructed = 0; 469252190Srpaulo break; 470252190Srpaulo case TUTF8String: 471252190Srpaulo encode_primitive ("utf8string", name); 472252190Srpaulo constructed = 0; 473252190Srpaulo break; 474252190Srpaulo case TPrintableString: 475252190Srpaulo encode_primitive ("printable_string", name); 476252190Srpaulo constructed = 0; 477252190Srpaulo break; 478252190Srpaulo case TIA5String: 479252190Srpaulo encode_primitive ("ia5_string", name); 480252190Srpaulo constructed = 0; 481252190Srpaulo break; 482252190Srpaulo case TBMPString: 483252190Srpaulo encode_primitive ("bmp_string", name); 484252190Srpaulo constructed = 0; 485252190Srpaulo break; 486252190Srpaulo case TUniversalString: 487252190Srpaulo encode_primitive ("universal_string", name); 488252190Srpaulo constructed = 0; 489252190Srpaulo break; 490252190Srpaulo case TVisibleString: 491252190Srpaulo encode_primitive ("visible_string", name); 492252190Srpaulo constructed = 0; 493252190Srpaulo break; 494252190Srpaulo case TNull: 495252190Srpaulo fprintf (codefile, "/* NULL */\n"); 496252190Srpaulo constructed = 0; 497252190Srpaulo break; 498252190Srpaulo default: 499252190Srpaulo abort (); 500252190Srpaulo } 501252190Srpaulo return constructed; 502252190Srpaulo} 503252190Srpaulo 504252190Srpaulovoid 505252190Srpaulogenerate_type_encode (const Symbol *s) 506252190Srpaulo{ 507252190Srpaulo fprintf (headerfile, 508252190Srpaulo "int " 509252190Srpaulo "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n", 510252190Srpaulo s->gen_name, s->gen_name); 511252190Srpaulo 512252190Srpaulo fprintf (codefile, "int\n" 513252190Srpaulo "encode_%s(unsigned char *p, size_t len," 514252190Srpaulo " const %s *data, size_t *size)\n" 515252190Srpaulo "{\n", 516252190Srpaulo s->gen_name, s->gen_name); 517252190Srpaulo 518252190Srpaulo switch (s->type->type) { 519252190Srpaulo case TInteger: 520252190Srpaulo case TBoolean: 521252190Srpaulo case TOctetString: 522252190Srpaulo case TGeneralizedTime: 523252190Srpaulo case TGeneralString: 524252190Srpaulo case TUTCTime: 525252190Srpaulo case TUTF8String: 526252190Srpaulo case TPrintableString: 527252190Srpaulo case TIA5String: 528252190Srpaulo case TBMPString: 529252190Srpaulo case TUniversalString: 530252190Srpaulo case TVisibleString: 531252190Srpaulo case TNull: 532252190Srpaulo case TBitString: 533252190Srpaulo case TEnumerated: 534252190Srpaulo case TOID: 535252190Srpaulo case TSequence: 536252190Srpaulo case TSequenceOf: 537252190Srpaulo case TSet: 538252190Srpaulo case TSetOf: 539252190Srpaulo case TTag: 540252190Srpaulo case TType: 541252190Srpaulo case TChoice: 542252190Srpaulo fprintf (codefile, 543252190Srpaulo "size_t ret = 0;\n" 544252190Srpaulo "size_t l;\n" 545252190Srpaulo "int i, e;\n\n"); 546252190Srpaulo fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */ 547252190Srpaulo 548252190Srpaulo encode_type("data", s->type, "Top"); 549252190Srpaulo 550252190Srpaulo fprintf (codefile, "*size = ret;\n" 551252190Srpaulo "return 0;\n"); 552252190Srpaulo break; 553252190Srpaulo default: 554252190Srpaulo abort (); 555252190Srpaulo } 556252190Srpaulo fprintf (codefile, "}\n\n"); 557252190Srpaulo} 558252190Srpaulo