Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / dwg / DwgUtil.java @ 2896

History | View | Annotate | Download (25.9 KB)

1
/* jdwglib. Java Library for reading Dwg files.
2
 * 
3
 * Author: Jose Morell Rama (jose.morell@gmail.com).
4
 * Port from the Pythoncad Dwg library by Art Haas.
5
 *
6
 * Copyright (C) 2005 Jose Morell, IVER TI S.A. and Generalitat Valenciana
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 * Jose Morell (jose.morell@gmail.com)
25
 * 
26
 * or
27
 *
28
 * IVER TI S.A.
29
 *  C/Salamanca, 50
30
 *  46005 Valencia
31
 *  Spain
32
 *  +34 963163400
33
 *  dac@iver.es
34
 */
35
package com.iver.cit.jdwglib.dwg;
36

    
37
import java.nio.ByteBuffer;
38
import java.nio.ByteOrder;
39
import java.util.Vector;
40

    
41
import com.iver.cit.gvsig.fmap.drivers.dgn.ByteUtils;
42

    
43
import freenet.support.HexUtil;
44

    
45
/**
46
 * The DwgUtil class contains the essential set of functions for reading bitstreams
47
 * in DWG files
48
 * 
49
 * @author jmorell
50
 */
51
public final class DwgUtil {
52
    
53
        /**
54
         * Read the extended data for a DWG object
55
         * Don't use in this version. Serious bugs detected
56
         * 
57
         * @param data Array of unsigned bytes obtained from the DWG binary file
58
         * @param offset The current bit offset where the value begins
59
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
60
         *                    when we are looking for LwPolylines.
61
         * @return Vector This vector has two parts. First is an int value that represents
62
         *                    the new offset, and second is the extended data of a DWG object 
63
         */
64
        public static Vector readExtendedData(int[] data, int offset) throws Exception {
65
                int bitPos = offset;
66
                Vector extData = new Vector();
67
                while (true) {
68
                        int newBitPos = ((Integer)getBitShort(data, bitPos).get(0)).intValue();
69
                        int size = ((Integer)getBitShort(data, bitPos).get(1)).intValue();
70
                        bitPos = newBitPos;
71
                        if (size==0) {
72
                                break;
73
                        }
74
                        newBitPos = ((Integer)((Vector)getHandle(data, bitPos)).get(0)).intValue();
75
                        // TODO: Esto no es correcto. Repasar ...
76
                        int handle = ((Integer)((Vector)getHandle(data, bitPos)).get(1)).intValue();
77
                        bitPos = newBitPos;
78
                        Vector eedata = new Vector();
79
                        while (size>0) {
80
                                newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
81
                                int cb = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
82
                                bitPos = newBitPos;
83
                                size = size-1;
84
                                if (cb==0x0) {
85
                                        newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
86
                                        int len = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
87
                                        bitPos = newBitPos;
88
                                        newBitPos = ((Integer)getRawShort(data, bitPos).get(0)).intValue();
89
                                        int cp = ((Integer)getRawShort(data, bitPos).get(1)).intValue();
90
                                        bitPos = newBitPos;
91
                                        Vector chars = new Vector();
92
                                        for (int i=0; i<len; i++) {
93
                                                newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
94
                                                int charr = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
95
                                                bitPos = newBitPos;
96
                                                // ?int o char?
97
                                                chars.add(new Integer(charr));
98
                                        }
99
                                        // Incorrecto. Repasar ...
100
                                        eedata.add(chars);
101
                                        size = size-len-3;
102
                                } else if (cb==0x1) {
103
                                        System.out.println("Invalid EXX code byte: 0x1");
104
                                } else if (cb==0x2) {
105
                                        newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
106
                                        int charr = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
107
                                        bitPos = newBitPos;
108
                                        if (charr==0x0) {
109
                                                eedata.add("{");
110
                                        } else if (charr==0x1) {
111
                                                eedata.add("}");
112
                                        } else {
113
                                                System.out.println("Unexpected EXX char: " + charr);
114
                                        }
115
                                        size = size - 1;
116
                                } else if (cb==0x3 || cb==0x5) {
117
                                        Vector chars = new Vector();
118
                                        for (int i=0; i<8; i++) {
119
                                                newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
120
                                                int charr = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
121
                                                bitPos = newBitPos;
122
                                                chars.add(new Integer(charr));
123
                                        }
124
                                        eedata.add(chars);
125
                                        size = size - 8;
126
                                } else if (cb==0x4) {
127
                                        newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
128
                                        int len = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
129
                                        bitPos = newBitPos;
130
                                        Vector chars = new Vector();
131
                                        for (int i=0; i<len; i++) {
132
                                                newBitPos = ((Integer)getRawChar(data, bitPos).get(0)).intValue();
133
                                                int charr = ((Integer)getRawChar(data, bitPos).get(1)).intValue();
134
                                                bitPos = newBitPos;
135
                                                chars.add(new Integer(charr));
136
                                        }
137
                                        eedata.add(chars);
138
                                        size = size - len -1;
139
                                } else if (0xa<=cb && cb<=0xd) {
140
                                        newBitPos = ((Integer)((Vector)getRawDouble(data, bitPos)).get(0)).intValue();
141
                                        double d1 = ((Double)((Vector)getRawDouble(data, bitPos)).get(1)).doubleValue();
142
                                        bitPos = newBitPos;
143
                                        newBitPos = ((Integer)((Vector)getRawDouble(data, bitPos)).get(0)).intValue();
144
                                        double d2 = ((Double)((Vector)getRawDouble(data, bitPos)).get(1)).doubleValue();
145
                                        bitPos = newBitPos;
146
                                        newBitPos = ((Integer)((Vector)getRawDouble(data, bitPos)).get(0)).intValue();
147
                                        double d3 = ((Double)((Vector)getRawDouble(data, bitPos)).get(1)).doubleValue();
148
                                        bitPos = newBitPos;
149
                                        eedata.add(new double[]{d1, d2, d3});
150
                                        size = size - 24;
151
                                } else if (0x28<=cb && cb<=0x2a) {
152
                                        newBitPos = ((Integer)((Vector)getRawDouble(data, bitPos)).get(0)).intValue();
153
                                        double d = ((Double)((Vector)getRawDouble(data, bitPos)).get(1)).doubleValue();
154
                                        bitPos = newBitPos;
155
                                        eedata.add(new Double(d));
156
                                        size=size-8;
157
                                } else if (cb==0x46) {
158
                                        newBitPos = ((Integer)getRawShort(data, bitPos).get(0)).intValue();
159
                                        int shortt = ((Integer)getRawShort(data, bitPos).get(1)).intValue();
160
                                        bitPos = newBitPos;
161
                                        eedata.add(new Integer(shortt));
162
                                        size=size-2;
163
                                } else if (cb==0x47) {
164
                                        newBitPos = ((Integer)getRawLong(data, bitPos).get(0)).intValue();
165
                                        int longg = ((Integer)getRawLong(data, bitPos).get(1)).intValue();
166
                                        bitPos = newBitPos;
167
                                        eedata.add(new Integer(longg));
168
                                        size=size-4;
169
                                } else {
170
                                        System.out.println("Unexpected code byte: " + cb);
171
                                }
172
                        }
173
                        Vector v = new Vector();
174
                        //v.add(handle, eedata);
175
                        extData.add(v);
176
                }
177
                Vector v = new Vector();
178
                v.add(new Integer(bitPos));
179
                v.add(extData);
180
                return v;
181
        }
182
        /**
183
         * Read a double value from a group of unsigned bytes and a default double
184
         * 
185
         * @param data Array of unsigned bytes obtained from the DWG binary file
186
         * @param offset The current bit offset where the value begins
187
         * @param defVal Default double value
188
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
189
         *                    when we are looking for LwPolylines.
190
         * @return Vector This vector has two parts. First is an int value that represents
191
         *                    the new offset, and second is the double value
192
         */
193
        public static Vector getDefaultDouble(int[] data, int offset, double defVal) throws Exception {
194
            int flags = ((Integer)getBits(data, 2, offset)).intValue();
195
            int read = 2;
196
            double val;
197
            if (flags==0x0) {
198
                    val = defVal;
199
            } else {
200
                    int _offset = offset + 2;
201
                    String dstr;
202
                    if (flags==0x3) {
203
                            byte[] bytes = (byte[])getBits(data, 64, _offset);
204
                            ByteBuffer bb = ByteBuffer.wrap(bytes);
205
                            bb.order(ByteOrder.LITTLE_ENDIAN);
206
                            val = bb.getDouble();
207
                            read = 66;
208
                    } else {
209
                            byte[] dstrArrayAux = new byte[8];
210
                            int[] doubleOffset = new int[]{0};
211
                            ByteUtils.doubleToBytes(defVal, dstrArrayAux, doubleOffset);
212
                            byte[] dstrArrayAuxx = new byte[8];
213
                            dstrArrayAuxx[0] = dstrArrayAux[7];
214
                            dstrArrayAuxx[1] = dstrArrayAux[6];
215
                            dstrArrayAuxx[2] = dstrArrayAux[5];
216
                            dstrArrayAuxx[3] = dstrArrayAux[4];
217
                            dstrArrayAuxx[4] = dstrArrayAux[3];
218
                            dstrArrayAuxx[5] = dstrArrayAux[2];
219
                            dstrArrayAuxx[6] = dstrArrayAux[1];
220
                            dstrArrayAuxx[7] = dstrArrayAux[0];
221
                            int[] dstrArrayAuxxx = new int[8];
222
                            for (int i=0;i<dstrArrayAuxxx.length;i++) {
223
                                dstrArrayAuxxx[i] = ByteUtils.getUnsigned(dstrArrayAuxx[i]);
224
                            }
225
                            byte[] dstrArray = new byte[8];
226
                            for (int i=0;i<dstrArray.length;i++) {
227
                                    dstrArray[i] = (byte)dstrArrayAuxxx[i];
228
                            }
229
                            if (flags==0x1) {
230
                                byte[] ddArray = (byte[])getBits(data, 32, _offset);
231
                                    dstrArray[0] = ddArray[0];
232
                                dstrArray[1] = ddArray[1];
233
                                dstrArray[2] = ddArray[2];
234
                                dstrArray[3] = ddArray[3];
235
                                read = 34;
236
                            } else {
237
                                byte[] ddArray = (byte[])getBits(data, 48, _offset);
238
                                    dstrArray[4] = ddArray[0];
239
                                dstrArray[5] = ddArray[1];
240
                                dstrArray[0] = ddArray[2];
241
                                dstrArray[1] = ddArray[3];
242
                                dstrArray[2] = ddArray[4];
243
                                dstrArray[3] = ddArray[5];
244
                                read = 50;
245
                            }
246
                            ByteBuffer bb = ByteBuffer.wrap(dstrArray);
247
                            bb.order(ByteOrder.LITTLE_ENDIAN);
248
                            val = bb.getDouble();
249
                    }
250
            }
251
            Vector v = new Vector();
252
                v.add(new Integer(offset+read));
253
                v.add(new Double(val));
254
                return v;
255
        }
256
        /**
257
         * Read a double value from a group of unsigned bytes
258
         * 
259
         * @param data Array of unsigned bytes obtained from the DWG binary file
260
         * @param offset The current bit offset where the value begins
261
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
262
         *                    when we are looking for LwPolylines.
263
         * @return Vector This vector has two parts. First is an int value that represents
264
         *                    the new offset, and second is the double value
265
         */
266
        public static Vector getBitDouble(int[] data, int offset) throws Exception {
267
                Vector v = new Vector();
268
                int type = ((Integer)getBits(data, 2, offset)).intValue();
269
                int read = 2;
270
                double val = 0.0;
271
                if (type==0x00) {
272
                        byte[] bytes = (byte[])getBits(data, 64, (offset+2));
273
                        ByteBuffer bb = ByteBuffer.wrap(bytes);
274
                        bb.order(ByteOrder.LITTLE_ENDIAN);
275
                        val = bb.getDouble();
276
                        read = 66;
277
                } else if (type==0x01) {
278
                        val = 1.0;
279
                } else if (type==0x02) {
280
                        val = 0.0;
281
                } else {
282
                        System.out.println("Bad type at bit offset: " + offset);
283
                }
284
                v.add(new Integer(offset+read));
285
                v.add(new Double(val));
286
                return v;
287
        }
288
        /**
289
         * Read a double value from a group of unsigned bytes
290
         * 
291
         * @param data Array of unsigned bytes obtained from the DWG binary file
292
         * @param offset The current bit offset where the value begins
293
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
294
         *                    when we are looking for LwPolylines.
295
         * @return Vector This vector has two parts. First is an int value that represents
296
         *                    the new offset, and second is the double value
297
         */
298
        public static Vector getRawDouble(int[] data, int offset) throws Exception {
299
            byte[] bytes = (byte[])getBits(data, 64, offset);
300
                ByteBuffer bb = ByteBuffer.wrap(bytes);
301
                bb.order(ByteOrder.LITTLE_ENDIAN);
302
                double val = bb.getDouble();
303
                Vector v = new Vector();
304
                v.add(new Integer(offset+64));
305
                v.add(new Double(val));
306
                return v;
307
        }
308
        /**
309
         * Read a short value from a group of unsigned bytes
310
         * 
311
         * @param data Array of unsigned bytes obtained from the DWG binary file
312
         * @param offset The current bit offset where the value begins
313
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
314
         *                    when we are looking for LwPolylines.
315
         * @return Vector This vector has two parts. First is an int value that represents
316
         *                    the new offset, and second is the short value
317
         */
318
        public static Vector getBitShort(int[] data, int offset) throws Exception {
319
                Vector v = new Vector();
320
                int type = ((Integer)getBits(data, 2, offset)).intValue();
321
                int read = 2;
322
                int val = 0;
323
                if (type==0x00) {
324
                        byte[] bytes = (byte[])getBits(data, 16, (offset+2));
325
                        ByteBuffer bb = ByteBuffer.wrap(bytes);
326
                        bb.order(ByteOrder.LITTLE_ENDIAN);
327
                        val = bb.getShort();
328
                        read = 18;
329
                } else if (type==0x01) {
330
                        val = ((Integer)getBits(data, 8, (offset+2))).intValue();
331
                        read = 10;
332
                } else if (type==0x02) {
333
                        val = 0;
334
                } else if (type==0x03) {
335
                        val = 256;
336
                }
337
                v.add(new Integer(offset+read));
338
                v.add(new Integer(val));
339
                return v;
340
        }
341
        /**
342
         * Read a short value from a group of unsigned bytes
343
         * 
344
         * @param data Array of unsigned bytes obtained from the DWG binary file
345
         * @param offset The current bit offset where the value begins
346
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
347
         *                    when we are looking for LwPolylines.
348
         * @return Vector This vector has two parts. First is an int value that represents
349
         *                    the new offset, and second is the short value
350
         */
351
        public static Vector getRawShort(int[] data, int offset) throws Exception {
352
                byte[] bytes = (byte[])getBits(data, 16, offset);
353
                ByteBuffer bb = ByteBuffer.wrap(bytes);
354
                bb.order(ByteOrder.LITTLE_ENDIAN);
355
                int val = bb.getShort();
356
                Vector v = new Vector();
357
                v.add(new Integer(offset+16));
358
                v.add(new Integer(val));
359
                return v;
360
        }
361
        /**
362
         * Read a long value from a group of unsigned bytes
363
         * 
364
         * @param data Array of unsigned bytes obtained from the DWG binary file
365
         * @param offset The current bit offset where the value begins
366
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
367
         *                    when we are looking for LwPolylines.
368
         * @return Vector This vector has two parts. First is an int value that represents
369
         *                    the new offset, and second is the long value
370
         */
371
        public static Vector getBitLong(int[] data, int offset) throws Exception {
372
            int type = ((Integer)getBits(data, 2, offset)).intValue();
373
            int read = 2;
374
            int val = 0;
375
            if (type==0x0) {
376
                    byte[] bytes = (byte[])getBits(data, 32, (offset+2));
377
                    ByteBuffer bb = ByteBuffer.wrap(bytes);
378
                    bb.order(ByteOrder.LITTLE_ENDIAN);
379
                    val = bb.getInt();
380
                    read = 34;
381
            } else if (type==0x01) {
382
                    val = ((Integer)getBits(data, 8, (offset+2))).intValue();
383
                    read = 10;
384
            } else if (type==0x02) {
385
                    val = 0;
386
            } else {
387
                        System.out.println("Bad type at bit offset: " + offset);
388
            }
389
            Vector v = new Vector();
390
            v.add(new Integer(offset+read));
391
            v.add(new Integer(val));
392
            return v;
393
        }
394
        /**
395
         * Read a long value from a group of unsigned bytes
396
         * 
397
         * @param data Array of unsigned bytes obtained from the DWG binary file
398
         * @param offset The current bit offset where the value begins
399
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
400
         *                    when we are looking for LwPolylines.
401
         * @return Vector This vector has two parts. First is an int value that represents
402
         *                    the new offset, and second is the long value
403
         */
404
        public static Vector getRawLong(int[] data, int offset) {
405
                Vector v = new Vector();
406
                // TODO: Incorrecto. Repasar ...
407
            // _val = struct.unpack('<l', _long)[0]
408
                int val = 0;
409
                v.add(new Integer(offset+32));
410
                v.add(new Integer(val));
411
                return v;
412
        }
413
        /**
414
         * Read a char value from a group of unsigned bytes
415
         * 
416
         * @param data Array of unsigned bytes obtained from the DWG binary file
417
         * @param offset The current bit offset where the value begins
418
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
419
         *                    when we are looking for LwPolylines.
420
         * @return Vector This vector has two parts. First is an int value that represents
421
         *                    the new offset, and second is the char value
422
         */
423
        public static Vector getRawChar(int[] data, int offset) throws Exception {
424
                int charr = ((Integer)getBits(data, 8, offset)).intValue();
425
            Vector v = new Vector();
426
            v.add(new Integer(offset+8));
427
            v.add(new Integer(charr));
428
                return v;
429
        }
430
        /**
431
         * Read a char value from a group of unsigned bytes
432
         * 
433
         * @param data Array of unsigned bytes obtained from the DWG binary file
434
         * @param offset The current bit offset where the value begins
435
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
436
         *                    when we are looking for LwPolylines.
437
         * @return Vector This vector has two parts. First is an int value that represents
438
         *                    the new offset, and second is the char value
439
         */
440
        public static Vector getModularChar(int[] data, int offset) throws Exception {
441
                int val=0;
442
                Vector bytes = new Vector();
443
                boolean read = true;
444
                int offsett = offset;
445
                int fac = 1;
446
                while (read) {
447
                        int bytee = ((Integer)getBits(data, 8, offsett)).intValue();
448
                        offsett = offsett + 8;
449
                        if ((bytee & 0x80)==0) {
450
                                read = false;
451
                                if ((bytee & 0x40)>0) {
452
                                        fac = -1;
453
                                        bytee = bytee & 0xbf;
454
                                }
455
                        }
456
                        bytes.add(new Integer(bytee & 0x7f));
457
                }
458
                if (bytes.size()==1) val = ((Integer)bytes.get(0)).intValue();
459
                else if (bytes.size()==2) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7);
460
                else if (bytes.size()==3) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7) | (((Integer)bytes.get(2)).intValue() << 14);
461
                else if (bytes.size()==4) val = ((Integer)bytes.get(0)).intValue() | (((Integer)bytes.get(1)).intValue() << 7) | (((Integer)bytes.get(2)).intValue() << 14) | (((Integer)bytes.get(3)).intValue() << 21);
462
                else System.out.println("Unexpected byte array length: " + bytes.size());
463
                Vector v = new Vector();
464
                v.add(new Integer(offsett));
465
                v.add(new Integer(fac*val));
466
                return v;
467
        }
468
        /**
469
         * Read a String from a group of unsigned bytes
470
         * 
471
         * @param data Array of unsigned bytes obtained from the DWG binary file
472
         * @param offset The current bit offset where the value begins
473
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
474
         *                    when we are looking for LwPolylines.
475
         * @return Vector This vector has two parts. First is an int value that represents
476
         *                    the new offset, and second is the String
477
         */
478
        public static Vector getTextString(int[] data, int offset) throws Exception {
479
                int bitPos = offset;
480
            int newBitPos = ((Integer)DwgUtil.getBitShort(data, bitPos).get(0)).intValue();
481
            int len = ((Integer)DwgUtil.getBitShort(data, bitPos).get(1)).intValue();
482
            bitPos = newBitPos;
483
            int bitLen = len * 8;
484
            Object cosa = DwgUtil.getBits(data, bitLen, bitPos);
485
            String string;
486
            if (cosa instanceof byte[]) {
487
                    string = new String((byte[])cosa);
488
            } else {
489
                    //string = ((Integer)cosa).toString();
490
                    byte[] bytes = new byte[]{((Integer)cosa).byteValue()};
491
                    string = new String((byte[])bytes);
492
            }
493
            bitPos = bitPos + bitLen;
494
            Vector v = new Vector();
495
            v.add(new Integer(bitPos));
496
            v.add(string);
497
            return v;
498
        }
499
        /**
500
         * Read a int value (the handle of a DWG object) from a group of unsigned bytes
501
         * 
502
         * @param data Array of unsigned bytes obtained from the DWG binary file
503
         * @param offset The current bit offset where the value begins
504
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
505
         *                    when we are looking for LwPolylines.
506
         * @return Vector This vector has two parts. First is an int value that represents
507
         *                    the new offset, and second is the int value (handle of a DWG object)
508
         */
509
        public static Vector getHandle(int[] data, int offset) throws Exception {
510
                Vector v = new Vector();
511
                int code = ((Integer)DwgUtil.getBits(data, 4, offset)).intValue();
512
            int counter = ((Integer)DwgUtil.getBits(data, 4, (offset + 4))).intValue();
513
            int read = 8;
514
            Vector hlist = new Vector();
515
            if (counter>0) {
516
                int hlen = counter * 8;
517
                Object handle = DwgUtil.getBits(data, hlen, (offset + 8));
518
                read = read + hlen;
519
                if (hlen > 8) {
520
                        byte[] handleBytes = (byte[])handle;
521
                        int[] handleInts = new int[handleBytes.length];
522
                            // Hacerlos unsigned ...
523
                            for (int i=0; i<handleBytes.length; i++) {
524
                                    handleInts[i] = ByteUtils.getUnsigned(handleBytes[i]);
525
                            }
526
                        for (int i=0; i<handleInts.length; i++) {
527
                                hlist.add(new Integer(handleInts[i]));
528
                        }
529
                } else {
530
                    hlist.add(handle);
531
                }
532
            }
533
            v.add(new Integer(offset+read));
534
            v.add(new Integer(code));
535
            v.add(new Integer(counter));
536
            for (int i=0;i<hlist.size();i++) {
537
                    v.add(hlist.get(i));
538
            }
539
                return v;
540
        }
541
        /**
542
         * Read a int value (the size of a modular short) from a ByteBuffer
543
         * 
544
         * @param bb Data given as a ByteBuffer
545
         * @return int Size of the modular short
546
         */
547
        public static int getModularShort(ByteBuffer bb) {
548
                Vector shorts = new Vector();
549
                bb.order(ByteOrder.BIG_ENDIAN);
550
                short shortt = bb.getShort();
551
                int size = 0;
552
                while ((shortt & 0x80)>0) {
553
                        shorts.add(new Short(shortt));
554
                        shortt = bb.getShort();
555
                }
556
                shorts.add(new Short(shortt));
557
                for (int i=0; i<shorts.size(); i++) {
558
                        shortt = ((Short)shorts.get(i)).shortValue();
559
                        shorts.set(i, new Integer(((shortt & 0xff00) >> 8) | ((shortt & 0xff) << 8)));
560
                }
561
                int slen = shorts.size();
562
                if (slen==1) {
563
                        size = (((Integer)shorts.get(0)).intValue()) & 0x7fff;//(new Integer(((Integer)shorts.get(0)).shortValue() & 0x7fff)).byteValue();
564
                } else if (slen==2) {
565
                        int tmp = ((Integer)shorts.get(0)).intValue();
566
                        shorts.set(0, shorts.get(1));
567
                        shorts.set(1, new Integer(tmp));
568
                        size = (((((Integer)shorts.get(0)).intValue()) & 0x7fff) << 15) | (((((Integer)shorts.get(1)).intValue()) & 0x7fff));//(new Integer(((Integer)shorts.get(0)).shortValue() & 0x7fff)).byteValue();
569
                } else {
570
                        System.out.println("Unexpected array length: " + slen);
571
                }
572
                return size;
573
        }
574
        /**
575
         * Returns a set of bits from a group of unsigned bytes
576
         * 
577
         * @param data Array of unsigned bytes obtained from the DWG binary file
578
         * @param count Bit counter
579
         * @param offset The current bit offset where the value begins
580
         * @throws Exception If an unexpected bit value is found in the DWG file. Occurs
581
         *                    when we are looking for LwPolylines.
582
         * @return This method returns an array of bytes or an int value
583
         */
584
        public static Object getBits(int[] data, int count, int offset) throws Exception {
585
                int idx = offset/8;
586
                int bitidx = offset%8;
587
                /**
588
                 * mask1: bit mask to apply to the current byte
589
                 * lshift: left shift amount of mask results
590
                 * mask2: bit mask to apply to the next byte
591
                 * rshift: right shift amount of the mask results
592
                 */
593
                int[][] maskTable = new int[][]{
594
                    {0xff, 0, 0x00, 0}, // bit offset == 0
595
                    {0x7f, 1, 0x80, 7}, // bit offset == 1
596
                    {0x3f, 2, 0xc0, 6}, // bit offset == 2
597
                    {0x1f, 3, 0xe0, 5}, // bit offset == 3
598
                    {0x0f, 4, 0xf0, 4}, // bit offset == 4
599
                    {0x07, 5, 0xf8, 3}, // bit offset == 5
600
                    {0x03, 6, 0xfc, 2}, // bit offset == 6
601
                    {0x01, 7, 0xfe, 1}, // bit offset == 7
602
                };
603
                int mask1 = maskTable[bitidx][0];
604
                int lsh = maskTable[bitidx][1];
605
                int mask2 = maskTable[bitidx][2];
606
                int rsh = maskTable[bitidx][3];
607
                int binc = 8 - bitidx;
608
                int read = 0;
609
                int rem = count;
610
                int bytee = 0x0;
611
                Vector bytes = new Vector();
612
                while (read < count) {
613
                        int b1 = 0;
614
                        if (rem > binc) {
615
                                b1 = (data[idx] & mask1);
616
                                read = read + binc;
617
                                rem = rem - binc;
618
                        } else {
619
                    b1 = ((data[idx] & mask1) >> (8 - bitidx - rem));
620
                    bytee = b1;
621
                                read = read + rem;
622
                                rem = 0;
623
                        }
624
                        if (read < count) {
625
                                idx = idx + 1;
626
                                if (rem > bitidx) {
627
                        int b2 = (data[idx] & mask2);
628
                        bytee = (b1 << lsh) | (b2 >> rsh);
629
                        read = read + bitidx;
630
                        rem = rem - bitidx;
631
                                } else {
632
                        int mask = maskTable[rem][2];
633
                        int b2 = data[idx] & mask;
634
                        bytee = (b1 << rem) | (b2 >> (8 - rem));
635
                        read = read + rem;
636
                        rem = 0;
637
                                }
638
                        }
639
                        if (count > 8) {
640
                                bytes.add(new Integer(bytee));
641
                        }
642
                }
643
                if (bytes.size()>0) {
644
                        byte[] newBytes = new byte[bytes.size()];
645
                        for (int i=0; i<newBytes.length; i++) {
646
                                newBytes[i] = ((Integer)bytes.get(i)).byteValue();
647
                        }
648
                        return newBytes;
649
                }
650
                return new Integer(bytee);
651
        }
652
        /**
653
         * Test a bit obtained from a set of unsigned bytes
654
         * 
655
         * @param data Array of unsigned bytes obtained from the DWG binary file
656
         * @param offset The current bit offset where the value begins
657
         * @return Vector This vector has two parts. First is an int value that represents
658
         *                    the new offset, and second is a bit flag
659
         */
660
        public static Vector testBit(int[] data, int offset) {
661
                int idx = offset/8;
662
                int bitidx = offset%8;
663
                int mask = 0x1 << (7-bitidx);
664
                boolean val = false;
665
                if ((data[idx] & mask) > 0) val = true;
666
                Vector v = new Vector();
667
                v.add(new Integer(offset+1));
668
                v.add(new Boolean(val));
669
                return v;
670
        }
671
        /**
672
         * Convert bytes to machine value bytes
673
         * 
674
         * @param data Input of array of bytes
675
         * @return int[] Output of array of machine bytes
676
         */
677
        public static int[] bytesToMachineBytes(byte[] data) {
678
                String[] dataString = new String[data.length];
679
                int[] dataOut = new int[data.length];
680
                for (int i=0; i<data.length; i++) {
681
                        dataString[i] = HexUtil.bytesToHex(new byte[]{data[i]});
682
                        Integer dataInt = Integer.decode("0x" + dataString[i]);
683
                        dataOut[i] = dataInt.intValue();
684
                }
685
                return dataOut;
686
        }
687
        /**
688
         * Obtain the int value of a handle given in binary format 
689
         * 
690
         * @param layerHandle Handle in binary format
691
         * @return int Int value of the handle
692
         */
693
        public static int handleBinToHandleInt(Vector layerHandle) {
694
                byte[] layerBytes = new byte[]{0,0,0,0};
695
                if (layerHandle.size()>2) layerBytes[3] = (byte)((Integer)layerHandle.get(2)).intValue();
696
                if (layerHandle.size()>3) {
697
                        layerBytes[3] = (byte)((Integer)layerHandle.get(3)).intValue();
698
                        layerBytes[2] = (byte)((Integer)layerHandle.get(2)).intValue();
699
                }
700
                if (layerHandle.size()>4) {
701
                        layerBytes[3] = (byte)((Integer)layerHandle.get(4)).intValue();
702
                        layerBytes[2] = (byte)((Integer)layerHandle.get(3)).intValue();
703
                        layerBytes[1] = (byte)((Integer)layerHandle.get(2)).intValue();
704
                }
705
                if (layerHandle.size()>5) {
706
                        layerBytes[3] = (byte)((Integer)layerHandle.get(5)).intValue();
707
                        layerBytes[2] = (byte)((Integer)layerHandle.get(4)).intValue();
708
                        layerBytes[1] = (byte)((Integer)layerHandle.get(3)).intValue();
709
                        layerBytes[0] = (byte)((Integer)layerHandle.get(2)).intValue();
710
                }
711
                int layer = ByteUtils.bytesToInt(layerBytes, new int[]{0});
712
                return layer;
713
        }
714
}