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