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