version 2 check
[yaz-moved-to-github.git] / src / dumpber.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file dumpber.c
8  * \brief Implements BER dumping
9  */
10
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <stdio.h>
16 #include "odr-priv.h"
17
18 static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset)
19 {
20     int res, ll, zclass, tag, cons, lenlen, taglen;
21     const char *b = buf;
22     char level_str[80];
23
24     if (level >= 15)
25         sprintf(level_str, "level=%-6d%*s", level, 18, "");
26     else
27         sprintf(level_str, "%*s", level * 2, "");
28
29     if (!len)
30         return 0;
31     if (!buf[0] && !buf[1])
32         return 0;
33     if ((res = ber_dectag((unsigned char*)b, &zclass, &tag, &cons, len)) <= 0)
34         return 0;
35     if (res > len)
36     {
37         fprintf(f, "%5d: %s : Unexpected enf of buffer\n", offset, level_str);
38         return 0;
39     }
40     fprintf(f, "%5d: %s", offset, level_str);
41     if (zclass == ODR_UNIVERSAL)
42     {
43         static char *nl[] =
44         {
45             "[Univ 0]", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
46             "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
47             "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
48             "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
49             "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
50             "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
51         };
52
53         if (tag >= 0 && tag < 28)
54             fprintf(f, "%s", nl[tag]);
55         else
56             fprintf(f, "[UNIV %d]", tag);
57     }
58     else if (zclass == ODR_CONTEXT)
59         fprintf(f, "[%d]", tag);
60     else
61         fprintf(f, "[%d:%d]", zclass, tag);
62     b += res;
63     taglen = res;
64     len -= res;
65     if ((res = ber_declen((unsigned char*)b, &ll, len)) <= 0)
66     {
67         fprintf(f, "\n%sBad length\n", level_str);
68         return 0;
69     }
70     lenlen = res;
71     b += res;
72     len -= res;
73     if (ll >= 0)
74         fprintf(f, " len=%d", ll);
75     else
76         fprintf(f, " len=?");
77     fprintf(f, " tl=%d, ll=%d cons=%d\n", taglen, lenlen, cons);
78     if (!cons)
79     {
80         if (ll < 0 || ll > len)
81         {
82             fprintf(f, "%sBad length on primitive type. ll=%d len=%d\n",
83                     level_str, ll, len);
84             return 0;
85         }
86         return ll + (b - buf);
87     }
88     if (ll >= 0)
89     {
90         if (ll > len)
91         {
92             fprintf(f, "%sBad length of constructed type ll=%d len=%d\n",
93                     level_str, ll, len);
94             return 0;
95         }
96         len = ll;
97     }
98     /* constructed - cycle through children */
99     while ((ll == -1 && len >= 2) || (ll >= 0 && len))
100     {
101         if (ll == -1 && *b == 0 && *(b + 1) == 0)
102             break;
103         if (!(res = do_dumpBER(f, b, len, level + 1, offset + (b - buf))))
104         {
105             fprintf(f, "%s Dump of content element failed\n", level_str);
106             return 0;
107         }
108         b += res;
109         len -= res;
110         if (len < 0)
111         {
112             fprintf(f, "%sBad length\n", level_str);
113             return 0;
114         }
115     }
116     if (ll == -1)
117     {
118         if (len < 2)
119         {
120             fprintf(f, "%sBuffer too short in indefinite length\n",
121                     level_str);
122             return 0;
123         }
124         return (b - buf) + 2;
125     }
126     return b - buf;
127 }
128
129 int odr_dumpBER(FILE *f, const char *buf, int len)
130 {
131     return do_dumpBER(f, buf, len, 0, 0);
132 }
133 /*
134  * Local variables:
135  * c-basic-offset: 4
136  * c-file-style: "Stroustrup"
137  * indent-tabs-mode: nil
138  * End:
139  * vim: shiftwidth=4 tabstop=8 expandtab
140  */
141