Added BER dumper.
[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.1  1995-06-19 12:38:45  quinn
8  * Added BER dumper.
9  *
10  *
11  */
12
13 #include <odr.h>
14 #include <stdio.h>
15
16 static int do_dumpBER(FILE *f, char *buf, int len, int level)
17 {
18     int res, ll, class, tag, cons;
19     char *b = buf;
20     
21     if (!len)
22         return 0;
23     if (!buf[0] && !buf[1])
24         return 0;
25     if ((res = ber_dectag(b, &class, &tag, &cons)) <= 0)
26         return 0;
27     if (res > len)
28     {
29         fprintf(stderr, "Unexpected end of buffer\n");
30         return 0;
31     }
32     fprintf(stderr, "%*s", level * 4, "");
33     if (class == ODR_UNIVERSAL)
34     {
35         static char *nl[] =
36         {
37             "Ugh", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
38             "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
39             "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
40             "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
41             "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
42             "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
43         };
44
45         if (tag < 28)
46             fprintf(stderr, "%s", nl[tag]);
47         else
48             fprintf(stderr, "[UNIV %d]", tag);
49     }
50     else if (class == ODR_CONTEXT)
51         fprintf(stderr, "[%d]", tag);
52     else
53         fprintf(stderr, "[%d:%d]", class, tag);
54     b += res;
55     len -= res;
56     if ((res = ber_declen(b, &ll)) <= 0)
57     {
58         fprintf(stderr, "bad length\n");
59         return 0;
60     }
61     if (res > len)
62     {
63         fprintf(stderr, "Unexpected end of buffer\n");
64         return 0;
65     }
66     b += res;
67     len -= res;
68     if (ll >= 0)
69         fprintf(stderr, " len=%d\n", ll);
70     else
71         fprintf(stderr, " len=?\n");
72     if (!cons)
73     {
74         if (ll < 0)
75         {
76             fprintf(stderr, "Bad length on primitive type.\n");
77             return 0;
78         }
79         return ll + (b - buf);
80     }
81     if (ll >= 0)
82         len = ll;
83     /* constructed - cycle through children */
84     while ((ll == -1 && len >= 2) || (ll >= 0 && len))
85     {
86         if (ll == -1 && *b == 0 && *(b + 1) == 0)
87             break;
88         if (!(res = do_dumpBER(f, b, len, level + 1)))
89         {
90             fprintf(stderr, "Dump of content element failed.\n");
91             return 0;
92         }
93         b += res;
94         len -= res;
95     }
96     if (ll == -1)
97     {
98         if (len < 2)
99         {
100             fprintf(stderr, "Buffer too short in indefinite lenght.\n");
101             return 0;
102         }
103         return (b - buf) + 2;
104     }
105     return b - buf;
106 }
107
108 int odr_dumpBER(FILE *f, char *buf, int len)
109 {
110     return do_dumpBER(f, buf, len, 0);
111 }