Header files moved to include (used to be z39.50).
[yaz-moved-to-github.git] / odr / dumpber.c
1 /*
2  * Copyright (c) 1995-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: dumpber.c,v $
7  * Revision 1.10  1999-01-08 11:23:26  adam
8  * Added const modifier to some of the BER/ODR encoding routines.
9  *
10  * Revision 1.9  1998/01/14 09:53:26  quinn
11  * Added a bit more info to dump.
12  *
13  * Revision 1.8  1997/05/14 06:53:57  adam
14  * C++ support.
15  *
16  * Revision 1.7  1996/03/08 14:38:41  quinn
17  * Fixed output.
18  *
19  * Revision 1.6  1996/01/19  15:41:34  quinn
20  * dumpber was ignoring the file argument.
21  *
22  * Revision 1.5  1995/10/18  16:12:55  quinn
23  * Better diagnostics. Added special case in NULL to handle WAIS server.
24  *
25  * Revision 1.4  1995/09/29  17:12:21  quinn
26  * Smallish
27  *
28  * Revision 1.3  1995/09/27  15:02:57  quinn
29  * Modified function heads & prototypes.
30  *
31  * Revision 1.2  1995/06/27  13:20:51  quinn
32  * Fixed sign-clash. Non-fatal warning
33  *
34  * Revision 1.1  1995/06/19  12:38:45  quinn
35  * Added BER dumper.
36  *
37  *
38  */
39
40 #include <odr.h>
41 #include <stdio.h>
42
43 static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset)
44 {
45     int res, ll, zclass, tag, cons, lenlen, taglen;
46     const char *b = buf, *bp = buf;
47     
48     if (!len)
49         return 0;
50     if (!buf[0] && !buf[1])
51         return 0;
52     if ((res = ber_dectag((unsigned char*)b, &zclass, &tag, &cons)) <= 0)
53         return 0;
54     if (res > len)
55     {
56         fprintf(stderr, "Unexpected end of buffer\n");
57         return 0;
58     }
59     fprintf(f, "%5d: %*s", offset, level * 4, "");
60     if (zclass == ODR_UNIVERSAL)
61     {
62         static char *nl[] =
63         {
64             "[Univ 0]", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
65             "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
66             "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
67             "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
68             "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
69             "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
70         };
71
72         if (tag < 28)
73             fprintf(f, "%s", nl[tag]);
74         else
75             fprintf(f, "[UNIV %d]", tag);
76     }
77     else if (zclass == ODR_CONTEXT)
78         fprintf(f, "[%d]", tag);
79     else
80         fprintf(f, "[%d:%d]", zclass, tag);
81     b += res;
82     taglen = res;
83     len -= res;
84     bp = b;
85     if ((res = ber_declen((unsigned char*)b, &ll)) <= 0)
86     {
87         fprintf(f, "bad length\n");
88         return 0;
89     }
90     if (res > len)
91     {
92         fprintf(f, "Unexpected end of buffer\n");
93         return 0;
94     }
95     lenlen = res;
96     b += res;
97     len -= res;
98     if (ll >= 0)
99         fprintf(f, " len=%d", ll);
100     else
101         fprintf(f, " len=?");
102     fprintf(f, "       tl=%d, ll=%d\n", taglen, lenlen);
103     if (!cons)
104     {
105         if (ll < 0)
106         {
107             fprintf(f, "Bad length on primitive type.\n");
108             return 0;
109         }
110         return ll + (b - buf);
111     }
112     if (ll >= 0)
113         len = ll;
114     /* constructed - cycle through children */
115     while ((ll == -1 && len >= 2) || (ll >= 0 && len))
116     {
117         if (ll == -1 && *b == 0 && *(b + 1) == 0)
118             break;
119         if (!(res = do_dumpBER(f, b, len, level + 1, offset + (b - buf))))
120         {
121             fprintf(f, "Dump of content element failed.\n");
122             return 0;
123         }
124         b += res;
125         len -= res;
126     }
127     if (ll == -1)
128     {
129         if (len < 2)
130         {
131             fprintf(f, "Buffer too short in indefinite lenght.\n");
132             return 0;
133         }
134         return (b - buf) + 2;
135     }
136     return b - buf;
137 }
138
139 int odr_dumpBER(FILE *f, const char *buf, int len)
140 {
141     return do_dumpBER(f, buf, len, 0, 0);
142 }