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