CCL: fix use of "term" field in sub queries
[yaz-moved-to-github.git] / src / dumpber.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2012 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file dumpber.c
8  * \brief Implements BER dumping
9  */
10
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <stdio.h>
16 #include "odr-priv.h"
17
18 static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset)
19 {
20     int res, ll, zclass, tag, cons, lenlen, taglen;
21     const char *b = buf;
22     
23     if (!len)
24         return 0;
25     if (!buf[0] && !buf[1])
26         return 0;
27     if ((res = ber_dectag((unsigned char*)b, &zclass, &tag, &cons, len)) <= 0)
28         return 0;
29     if (res > len)
30     {
31         fprintf(stderr, "Unexpected end of buffer\n");
32         return 0;
33     }
34     fprintf(f, "%5d: %*s", offset, level * 4, "");
35     if (zclass == ODR_UNIVERSAL)
36     {
37         static char *nl[] =
38         {
39             "[Univ 0]", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
40             "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
41             "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
42             "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
43             "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
44             "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
45         };
46
47         if (tag >= 0 && tag < 28)
48             fprintf(f, "%s", nl[tag]);
49         else
50             fprintf(f, "[UNIV %d]", tag);
51     }
52     else if (zclass == ODR_CONTEXT)
53         fprintf(f, "[%d]", tag);
54     else
55         fprintf(f, "[%d:%d]", zclass, tag);
56     b += res;
57     taglen = res;
58     len -= res;
59     if ((res = ber_declen((unsigned char*)b, &ll, len)) <= 0)
60     {
61         fprintf(f, "\n%*sBad length\n", level*4+5, "");
62         return 0;
63     }
64     lenlen = res;
65     b += res;
66     len -= res;
67     if (ll >= 0)
68         fprintf(f, " len=%d", ll);
69     else
70         fprintf(f, " len=?");
71     fprintf(f, "       tl=%d, ll=%d cons=%d\n", taglen, lenlen, cons);
72     if (!cons)
73     {
74         if (ll < 0 || ll > len)
75         {
76             fprintf(f, "%*sBad length on primitive type. ll=%d len=%d\n",
77                     level*4+5, "", ll, len);
78             return 0;
79         }
80         return ll + (b - buf);
81     }
82     if (ll >= 0)
83     {
84         if (ll > len)
85         {
86             fprintf(f, "%*sBad length of constructed type ll=%d len=%d.\n",
87                     level*4+5, "", ll, len);
88             return 0;
89         }
90         len = ll;
91     }
92     /* constructed - cycle through children */
93     while ((ll == -1 && len >= 2) || (ll >= 0 && len))
94     {
95         if (ll == -1 && *b == 0 && *(b + 1) == 0)
96             break;
97         if (!(res = do_dumpBER(f, b, len, level + 1, offset + (b - buf))))
98         {
99             fprintf(f, "%*sDump of content element failed.\n", level*4+5, "");
100             return 0;
101         }
102         b += res;
103         len -= res;
104         if (len < 0)
105         {
106             fprintf(f, "%*sBad length\n", level*4+5, "");
107             return 0;
108         }
109     }
110     if (ll == -1)
111     {
112         if (len < 2)
113         {
114             fprintf(f, "%*sBuffer too short in indefinite length.\n",
115                     level*4+5, "");
116             return 0;
117         }
118         return (b - buf) + 2;
119     }
120     return b - buf;
121 }
122
123 int odr_dumpBER(FILE *f, const char *buf, int len)
124 {
125     return do_dumpBER(f, buf, len, 0, 0);
126 }
127 /*
128  * Local variables:
129  * c-basic-offset: 4
130  * c-file-style: "Stroustrup"
131  * indent-tabs-mode: nil
132  * End:
133  * vim: shiftwidth=4 tabstop=8 expandtab
134  */
135