1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2018-2019 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 /*
14 * bits.c: print all possible type/values of given bits
15 * written by Reini Urban
16 */
17
18 #include "../src/config.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23
24 #include "dwg.h"
25 #include "../src/bits.h"
26 static int maxoff = 0;
27
28 static int
29 decode (Bit_Chain *dat, int off, const int size)
30 {
31 int pos = 0;
32 BITCODE_BS bs = 0;
33 printf ("decode offset:%d, size:%d\n", off, size);
34 if (off >= size)
35 return 0;
36
37 bit_set_position (dat, off);
38 if (size - off >= 66)
39 {
40 double d = bit_read_BD (dat);
41 int p = (int)bit_position (dat);
42 if (d != bit_nan ())
43 {
44 printf ("%.15f BD @%d (%d)\n", d, p, size);
45 pos = p;
46 }
47 bit_set_position (dat, off);
48 }
49 if (size - off >= 64)
50 {
51 double d = bit_read_RD (dat);
52 int p = (int)bit_position (dat);
53 if (d != bit_nan ())
54 {
55 printf ("%.15f RD @%d (%d)\n", d, p, size);
56 pos = p;
57 }
58 bit_set_position (dat, off);
59 }
60 if (size - off >= 34)
61 {
62 BITCODE_BL l = (long)bit_read_BL (dat);
63 int p = (int)bit_position (dat);
64 if (p <= size - off)
65 {
66 printf ("%u BL @%d (%d)\n", l, p, size);
67 pos = p;
68 }
69 bit_set_position (dat, off);
70 }
71 if (size - off >= 32)
72 {
73 BITCODE_BL l = (long)bit_read_RL (dat);
74 pos = (int)bit_position (dat);
75 printf ("%u RL @%d (%d)\n", l, pos, size);
76 bit_set_position (dat, off);
77 }
78 if (size - off >= 16)
79 {
80 BITCODE_RS l = (int)bit_read_RS (dat);
81 pos = (int)bit_position (dat);
82 printf ("%d RS @%d (%d)\n", l, pos, size);
83 bit_set_position (dat, off);
84 }
85 if (size - off >= 10)
86 {
87 int p;
88 bs = bit_read_BS (dat);
89 p = (int)bit_position (dat);
90 if (p <= size - off)
91 {
92 printf ("%d BS @%d (%d)\n", bs, p, size);
93 pos = p;
94 }
95 bit_set_position (dat, off);
96 }
97 if (size - off >= 8)
98 {
99 int l = bit_read_RC (dat);
100 pos = (int)bit_position (dat);
101 printf ("%d RC @%d (%d)\n", l, pos, size);
102 bit_set_position (dat, off);
103 }
104 if (size - off >= 8)
105 {
106 Dwg_Handle h;
107 int err, p;
108 err = bit_read_H (dat, &h);
109 p = (int)bit_position (dat);
110 if (!err && h.size == 1 && p <= size - off)
111 {
112 printf ("%x.%d.%lX H @%d (%d)\n", h.code, h.size, h.value, p, size);
113 pos = p;
114 }
115 bit_set_position (dat, off);
116 }
117 if (size - off >= 4)
118 {
119 Dwg_Color c;
120 int p;
121 bit_read_CMC (dat, dat, &c);
122 p = (int)bit_position (dat);
123 if (c.index < 257 && p <= size - off)
124 {
125 printf ("%d 0x%06X 0x%x CMC @%d (%d)\n", c.index, c.rgb, c.flag, p,
126 size);
127 pos = p;
128 }
129 free (c.name);
130 free (c.book_name);
131 bit_set_position (dat, off);
132 }
133 if (size - off >= 2)
134 {
135 int i = bit_read_BB (dat);
136 pos = (int)bit_position (dat);
137 printf ("%d BB @%d (%d)\n", i, pos, size);
138 if (i == 2)
139 printf ("%d BS/BL @%d (%d)\n", 0, pos, size);
140 else if (i == 3)
141 printf ("%d BS @%d (%d)\n", 256, pos, size);
142 bit_set_position (dat, off);
143 }
144 // if BS is a valid length try TV also
145 if (bs > 0 && bs < size - off - pos)
146 {
147 int i;
148 char *s = bit_read_TV (dat);
149 int p = (int)bit_position (dat);
150 if (s)
151 {
152 for (i = 0; i < bs; i++)
153 if (!isprint (s[i]))
154 break;
155 if (i == bs)
156 {
157 printf ("%s TV @%d (%d)\n", s, pos, size);
158 pos = p;
159 }
160 free (s);
161 }
162 }
163
164 while (pos < size)
165 {
166 if (pos <= off)
167 pos++;
168 if (maxoff < pos)
169 maxoff = pos;
170 // printf ("offset %d\n", pos);
171 return decode (dat, off + 1, size);
172 }
173 return 0;
174 }
175
176 int
177 main (int argc, char *argv[])
178 {
179 int hex = 0;
180 int i;
181 int pos;
182 Bit_Chain dat = EMPTY_CHAIN (0);
183
184 if (argc < 2)
185 {
186 printf ("usage: examples/bits "
187 "001100000000000000000000000000011000000000000000100000001010010"
188 "00\n");
189 printf (
190 "or examples/bits -x '8055 40f9 3284 d222 3e40 7436 e0d9 23fd'\n");
191 return 1;
192 }
193 if (argc > 2 && !strcmp (argv[1], "-x"))
194 {
195 hex = 1;
196 i = 2;
197 }
198 else
199 {
200 i = 1;
201 }
202
203 // dat.chain = malloc (size + 1);
204 // dat.size = size;
205 dat.version = R_2004;
206 do
207 {
208 char *input = argv[i];
209 int bits = strlen (input);
210 if (hex)
211 dat.size += bits;
212 else
213 dat.size += bits / 8;
214 dat.chain = realloc (dat.chain, dat.size + 1);
215 if (hex)
216 {
217 int size = bit_write_hexbits (&dat, input);
218 dat.size -= dat.size - size;
219 }
220 else
221 bit_write_bits (&dat, input);
222 i++;
223 }
224 while (i < argc);
225
226 pos = (int)bit_position (&dat);
227 // accept all types, like CMC, BS, BL, HANDLE and print all possible variants
228 pos = decode (&dat, 0, (int)pos);
229
230 free (dat.chain);
231 return 0;
232 }