Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_898 / libraries / libDwg / src / com / iver / cit / javacad / util / ByteUtils.java @ 10513

History | View | Annotate | Download (23.4 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.javacad.util;
42
import java.math.BigInteger;
43

    
44

    
45
/**
46
 * Clase que engloba m?todos para trabajar con bytes. 
47
 *
48
 * @author Vicente Caballero Navarro
49
 */
50
public class ByteUtils {
51
        public static final int SIZE_BOOL = 1;
52
        public static final int SIZE_SHORT = 2;
53
        public static final int SIZE_INT = 4;
54
        public static final int SIZE_LONG = 8;
55
        public static final int SIZE_DOUBLE = 8;
56

    
57
        /** A nibble->char mapping for printing out bytes. */
58
        public static final char[] digits = {
59
                        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
60
                        'e', 'f'
61
                };
62

    
63
        /**
64
         * Return the <code>int</code> represented by the bytes in
65
         * <code>data</code> staring at offset <code>offset[0]</code>.
66
         *
67
         * @param data the array from which to read
68
         * @param offset A single element array whose first element is the index in
69
         *                   data from which to begin reading on function entry, and which on
70
         *                   function exit has been incremented by the number of bytes read.
71
         *
72
         * @return the value of the <code>int</code> decoded
73
         */
74
        public static final int bytesToInt(byte[] data, int[] offset) {
75
                /**
76
                 * TODO: We use network-order within OceanStore, but temporarily
77
                 * supporting intel-order to work with some JNI code until JNI code is
78
                 * set to interoperate with network-order.
79
                 */
80
                int result = 0;
81

    
82
                for (int i = 0; i < SIZE_INT; ++i) {
83
                        result <<= 8;
84
                        result |= byteToUnsignedInt(data[offset[0]++]);
85
                }
86

    
87
                return result;
88
        }
89

    
90
        /**
91
         * Write the bytes representing <code>i</code> into the byte array
92
         * <code>data</code>, starting at index <code>offset [0]</code>, and
93
         * increment <code>offset [0]</code> by the number of bytes written; if
94
         * <code>data == null</code>, increment <code>offset [0]</code> by the
95
         * number of bytes that would have been written otherwise.
96
         *
97
         * @param i the <code>int</code> to encode
98
         * @param data The byte array to store into, or <code>null</code>.
99
         * @param offset A single element array whose first element is the index in
100
         *                   data to begin writing at on function entry, and which on
101
         *                   function exit has been incremented by the number of bytes
102
         *                   written.
103
         */
104
        public static final void intToBytes(int i, byte[] data, int[] offset) {
105
                /**
106
                 * TODO: We use network-order within OceanStore, but temporarily
107
                 * supporting intel-order to work with some JNI code until JNI code is
108
                 * set to interoperate with network-order.
109
                 */
110
                if (data != null) {
111
                        for (int j = (offset[0] + SIZE_INT) - 1; j >= offset[0]; --j) {
112
                                data[j] = (byte) i;
113
                                i >>= 8;
114
                        }
115
                }
116

    
117
                offset[0] += SIZE_INT;
118
        }
119

    
120
        /**
121
         * Return the <code>short</code> represented by the bytes in
122
         * <code>data</code> staring at offset <code>offset[0]</code>.
123
         *
124
         * @param data the array from which to read
125
         * @param offset A single element array whose first element is the index in
126
         *                   data from which to begin reading on function entry, and which on
127
         *                   function exit has been incremented by the number of bytes read.
128
         *
129
         * @return the value of the <code>short</code> decoded
130
         */
131
        public static final short bytesToShort(byte[] data, int[] offset) {
132
                /**
133
                 * TODO: We use network-order within OceanStore, but temporarily
134
                 * supporting intel-order to work with some JNI code until JNI code is
135
                 * set to interoperate with network-order.
136
                 */
137
                short result = 0;
138

    
139
                for (int i = 0; i < SIZE_SHORT; ++i) {
140
                        result <<= 8;
141
                        result |= (short) byteToUnsignedInt(data[offset[0]++]);
142
                }
143

    
144
                return result;
145
        }
146

    
147
        /**
148
         * Write the bytes representing <code>s</code> into the byte array
149
         * <code>data</code>, starting at index <code>offset [0]</code>, and
150
         * increment <code>offset [0]</code> by the number of bytes written; if
151
         * <code>data == null</code>, increment <code>offset [0]</code> by the
152
         * number of bytes that would have been written otherwise.
153
         *
154
         * @param s the <code>short</code> to encode
155
         * @param data The byte array to store into, or <code>null</code>.
156
         * @param offset A single element array whose first element is the index in
157
         *                   data to begin writing at on function entry, and which on
158
         *                   function exit has been incremented by the number of bytes
159
         *                   written.
160
         */
161
        public static final void shortToBytes(short s, byte[] data, int[] offset) {
162
                /**
163
                 * TODO: We use network-order within OceanStore, but temporarily
164
                 * supporting intel-order to work with some JNI code until JNI code is
165
                 * set to interoperate with network-order.
166
                 */
167
                if (data != null) {
168
                        data[offset[0] + 1] = (byte) s;
169
                        data[offset[0]] = (byte) (s >> 8);
170
                }
171

    
172
                offset[0] += SIZE_SHORT;
173
        }
174

    
175
        /**
176
         * Return the <code>long</code> represented by the bytes in
177
         * <code>data</code> staring at offset <code>offset[0]</code>.
178
         *
179
         * @param data the array from which to read
180
         * @param offset A single element array whose first element is the index in
181
         *                   data from which to begin reading on  function entry, and which
182
         *                   on function exit has been incremented by the number of bytes
183
         *                   read.
184
         *
185
         * @return the value of the <code>long</code> decoded
186
         */
187
        public static final long bytesToLong(byte[] data, int[] offset) {
188
                long result = 0;
189

    
190
                for (int i = 0; i < SIZE_LONG; ++i) {
191
                        result <<= 8;
192

    
193
                        int res = byteToUnsignedInt(data[offset[0]++]);
194
                        result = result | res;
195
                }
196

    
197
                return result;
198
        }
199

    
200
        /**
201
         * Write the bytes representing <code>l</code> into the byte array
202
         * <code>data</code>, starting at index <code>offset [0]</code>, and
203
         * increment <code>offset [0]</code> by the number of bytes written; if
204
         * <code>data == null</code>, increment <code>offset [0]</code> by the
205
         * number of bytes that would have been written otherwise.
206
         *
207
         * @param l the <code>long</code> to encode
208
         * @param data The byte array to store into, or <code>null</code>.
209
         * @param offset A single element array whose first element is the index in
210
         *                   data to begin writing at on function entry, and which on
211
         *                   function exit has been incremented by the number of bytes
212
         *                   written.
213
         */
214
        public static final void longToBytes(long l, byte[] data, int[] offset) {
215
                /**
216
                 * TODO: We use network-order within OceanStore, but temporarily
217
                 * supporting intel-order to work with some JNI code until JNI code is
218
                 * set to interoperate with network-order.
219
                 */
220
                if (data != null) {
221
                        for (int j = (offset[0] + SIZE_LONG) - 1; j >= offset[0]; --j) {
222
                                data[j] = (byte) l;
223
                                l >>= 8;
224
                        }
225
                }
226

    
227
                offset[0] += SIZE_LONG;
228
        }
229

    
230
        /**
231
         * Return the <code>double</code> represented by the bytes in
232
         * <code>data</code> staring at offset <code>offset[0]</code>.
233
         *
234
         * @param data the array from which to read
235
         * @param offset A single element array whose first element is the index in
236
         *                   data from which to begin reading on  function entry, and which
237
         *                   on function exit has been incremented by the number of bytes
238
         *                   read.
239
         *
240
         * @return the value of the <code>double</code> decoded
241
         */
242
        public static final double bytesToDouble(byte[] data, int[] offset) {
243
                long bits = bytesToLong(data, offset);
244

    
245
                return Double.longBitsToDouble(bits);
246
        }
247

    
248
        /**
249
         * Write the bytes representing <code>d</code> into the byte array
250
         * <code>data</code>, starting at index <code>offset [0]</code>, and
251
         * increment <code>offset [0]</code> by the number of bytes written; if
252
         * <code>data == null</code>, increment <code>offset [0]</code> by the
253
         * number of bytes that would have been written otherwise.
254
         *
255
         * @param d the <code>double</code> to encode
256
         * @param data The byte array to store into, or <code>null</code>.
257
         * @param offset A single element array whose first element is the index in
258
         *                   data to begin writing at on function entry, and which on
259
         *                   function exit has been incremented by the number of bytes
260
         *                   written.
261
         */
262
        public static final void doubleToBytes(double d, byte[] data, int[] offset) {
263
                long bits = Double.doubleToLongBits(d);
264
                longToBytes(bits, data, offset);
265
        }
266

    
267
        /**
268
         * Return the <code>String</code> represented by the bytes in
269
         * <code>data</code> staring at offset <code>offset[0]</code>. This method
270
         * relies on the user using the corresponding <code>stringToBytes</code>
271
         * method to encode the <code>String</code>, so that it may properly
272
         * retrieve the <code>String</code> length.
273
         *
274
         * @param data the array from which to read
275
         * @param offset A single element array whose first element is the index in
276
         *                   data from which to begin reading on function entry, and which on
277
         *                   function exit has been incremented by the number of bytes read.
278
         *
279
         * @return the value of the <code>String</code> decoded
280
         */
281
        public static final String bytesToString(byte[] data, int[] offset) {
282
                offset[0] = 0;
283

    
284
                int length = bytesToInt(data, offset);
285
                String st = null;
286

    
287
                if ((length < 0) || (length > data.length)) {
288
                        st = new String(data);
289
                } else {
290
                        st = new String(data, offset[0], length);
291
                }
292

    
293
                offset[0] += length;
294

    
295
                return st;
296
        }
297

    
298
        /**
299
         * Write the bytes representing <code>s</code> into the byte array
300
         * <code>data</code>, starting at index <code>offset [0]</code>, and
301
         * increment <code>offset [0]</code> by the number of bytes written; if
302
         * <code>data == null</code>, increment <code>offset [0]</code> by the
303
         * number of bytes that would have been written otherwise.
304
         *
305
         * @param s the <code>String</code> to encode
306
         * @param data The byte array to store into, or <code>null</code>.
307
         * @param offset A single element array whose first element is the index in
308
         *                   data to begin writing at on function entry, and which on
309
         *                   function exit has been incremented by the number of bytes
310
         *                   written.
311
         */
312
        public static final void stringToBytes(String s, byte[] data, int[] offset) {
313
                byte[] s_bytes = s.getBytes();
314

    
315
                if (data != null) {
316
                        intToBytes(s_bytes.length, data, offset);
317
                        memcpy(data, offset[0], s_bytes, 0, s_bytes.length);
318
                } else {
319
                        offset[0] += SIZE_INT;
320
                }
321

    
322
                offset[0] += s_bytes.length;
323
        }
324

    
325
        /**
326
         * Return the <code>boolean</code> represented by the bytes in
327
         * <code>data</code> staring at offset <code>offset[0]</code>.
328
         *
329
         * @param data the array from which to read
330
         * @param offset A single element array whose first element is the index in
331
         *                   data from which to begin reading on  function entry, and which
332
         *                   on function exit has been incremented by the number of bytes
333
         *                   read.
334
         *
335
         * @return the value of the <code>boolean</code> decoded
336
         */
337
        public static final boolean bytesToBool(byte[] data, int[] offset) {
338
                boolean result = true;
339

    
340
                if (data[offset[0]] == 0) {
341
                        result = false;
342
                }
343

    
344
                offset[0] += SIZE_BOOL;
345

    
346
                return result;
347
        }
348

    
349
        /**
350
         * Write the bytes representing <code>b</code> into the byte array
351
         * <code>data</code>, starting at index <code>offset [0]</code>, and
352
         * increment <code>offset [0]</code> by the number of bytes written; if
353
         * <code>data == null</code>, increment <code>offset [0]</code> by the
354
         * number of bytes that would have been written otherwise.
355
         *
356
         * @param b the <code>boolean</code> to encode
357
         * @param data The byte array to store into, or <code>null</code>.
358
         * @param offset A single element array whose first element is the index in
359
         *                   data to begin writing at on function entry, and which on
360
         *                   function exit has been incremented by the number of bytes
361
         *                   written.
362
         */
363
        public static final void boolToBytes(boolean b, byte[] data, int[] offset) {
364
                if (data != null) {
365
                        data[offset[0]] = (byte) (b ? 1 : 0);
366
                }
367

    
368
                offset[0] += SIZE_BOOL;
369
        }
370

    
371
        /**
372
         * Return the <code>BigInteger</code> represented by the bytes in
373
         * <code>data</code> staring at offset <code>offset[0]</code>.
374
         *
375
         * @param data the array from which to read
376
         * @param offset A single element array whose first element is the index in
377
         *                   data from which to begin reading on  function entry, and which
378
         *                   on function exit has been incremented by the number of bytes
379
         *                   read.
380
         *
381
         * @return the <code>BigInteger</code> decoded
382
         */
383
        public static final BigInteger bytesToBigInteger(byte[] data, int[] offset) {
384
                int length = bytesToInt(data, offset);
385
                byte[] bytes = new byte[length];
386
                offset[0] += memcpy(bytes, 0, data, offset[0], length);
387

    
388
                return new BigInteger(bytes);
389
        }
390

    
391
        /**
392
         * Write the bytes representing <code>n</code> into the byte array
393
         * <code>data</code>, starting at index <code>offset [0]</code>, and
394
         * increment <code>offset [0]</code> by the number of bytes written; if
395
         * <code>data == null</code>, increment <code>offset [0]</code> by the
396
         * number of bytes that would have been written otherwise.
397
         *
398
         * @param n the <code>BigInteger</code> to encode
399
         * @param data The byte array to store into, or <code>null</code>.
400
         * @param offset A single element array whose first element is the index in
401
         *                   data to begin writing at on function entry, and which on
402
         *                   function exit has been incremented by the number of bytes
403
         *                   written.
404
         */
405
        public static final void bigIntegerToBytes(BigInteger n, byte[] data,
406
                int[] offset) {
407
                byte[] bytes = n.toByteArray();
408
                intToBytes(bytes.length, data, offset);
409
                offset[0] += memcpy(data, offset[0], bytes, 0, bytes.length);
410
        }
411

    
412
        /**
413
         * Convert an array of <code>bytes</code>s into an array of
414
         * <code>ints</code>.
415
         *
416
         * @param dst the array to write
417
         * @param dst_offset the start offset in <code>dst</code>, times 4. This
418
         *                   measures the offset as if <code>dst</code> were an array of
419
         *                   <code>byte</code>s (rather than <code>int</code>s).
420
         * @param src the array to read
421
         * @param src_offset the start offset in <code>src</code>
422
         * @param length the number of <code>byte</code>s to copy.
423
         */
424
        public static final void bytesToInts(int[] dst, int dst_offset, byte[] src,
425
                int src_offset, int length) {
426
                if ((src == null) || (dst == null) ||
427
                                ((src_offset + length) > src.length) ||
428
                                ((dst_offset + length) > (dst.length * 4)) ||
429
                                ((dst_offset % 4) != 0) || ((length % 4) != 0)) {
430
                        croak("bytesToInts parameters are invalid" + " src==" + src +
431
                                " dst==" + dst +
432
                                (((src == null) || (dst == null)) ? " "
433
                                                                                                  : (" (src_offset+length)>src.length==" +
434
                                (src_offset + length) + ">" + src.length +
435
                                " (dst_offset+length)>(dst.length*4)==" +
436
                                (dst_offset + length) + ">" + (dst.length * 4) +
437
                                " (dst_offset%4)==" + (dst_offset % 4) + " (length%4)==" +
438
                                (length % 4) + " dest.length==" + dst.length + " length==" +
439
                                length)));
440
                }
441

    
442
                // Convert parameters to normal format
443
                int[] offset = new int[1];
444
                offset[0] = src_offset;
445

    
446
                int int_dst_offset = dst_offset / 4;
447

    
448
                for (int i = 0; i < (length / 4); ++i) {
449
                        dst[int_dst_offset++] = bytesToInt(src, offset);
450
                }
451
        }
452

    
453
        /**
454
         * Convert an array of <code>int</code>s into an array of
455
         * <code>bytes</code>.
456
         *
457
         * @param dst the array to write
458
         * @param dst_offset the start offset in <code>dst</code>
459
         * @param src the array to read
460
         * @param src_offset the start offset in <code>src</code>, times 4. This
461
         *                   measures the offset as if <code>src</code> were an array of
462
         *                   <code>byte</code>s (rather than <code>int</code>s).
463
         * @param length the number of <code>byte</code>s to copy.
464
         */
465
        public static final void intsToBytes(byte[] dst, int dst_offset, int[] src,
466
                int src_offset, int length) {
467
                if ((src == null) || (dst == null) ||
468
                                ((dst_offset + length) > dst.length) ||
469
                                ((src_offset + length) > (src.length * 4)) ||
470
                                ((src_offset % 4) != 0) || ((length % 4) != 0)) {
471
                        croak("intsToBytes parameters are invalid:" + " src=" + src +
472
                                " dst=" + dst + " (dst_offset=" + dst_offset + " + length=" +
473
                                length + ")=" + (dst_offset + length) + " > dst.length=" +
474
                                ((dst == null) ? 0 : dst.length) + " (src_offset=" +
475
                                src_offset + " + length=" + length + ")=" +
476
                                (src_offset + length) + " > (src.length=" +
477
                                ((src == null) ? 0 : src.length) + "*4)=" +
478
                                ((src == null) ? 0 : (src.length * 4)) + " (src_offset=" +
479
                                src_offset + " % 4)=" + (src_offset % 4) + " != 0" +
480
                                " (length=" + length + " % 4)=" + (length % 4) + " != 0");
481
                }
482

    
483
                // Convert parameters to normal format
484
                int[] offset = new int[1];
485
                offset[0] = dst_offset;
486

    
487
                int int_src_offset = src_offset / 4;
488

    
489
                for (int i = 0; i < (length / 4); ++i) {
490
                        intToBytes(src[int_src_offset++], dst, offset);
491
                }
492
        }
493

    
494
        /**
495
         * Convert a <code>byte</code> into an unsigned integer.
496
         *
497
         * @param b the <code>byte</code> to cast
498
         *
499
         * @return a postiive <code>int</code> whose lowest byte contains the bits
500
         *                    of <code>b</code>.
501
         */
502
        public static final int byteToUnsignedInt(byte b) {
503
                return ((int) b) & 0xff;
504
        }
505

    
506
        /**
507
         * Copy contents of one array of <code>bytes</code> into another. If either
508
         * array is <code>null</code>, simply return the <code>length</code>
509
         * parameter directly.
510
         *
511
         * @param dst the array to write, or <code>null</code>
512
         * @param dst_offset the start offset in <code>dst</code>
513
         * @param src the array to read, or <code>null</code>
514
         * @param src_offset the start offset in <code>src</code>
515
         * @param length the number of <code>byte</code>s to copy.
516
         *
517
         * @return DOCUMENT ME!
518
         */
519
        public static int memcpy(byte[] dst, int dst_offset, byte[] src,
520
                int src_offset, int length) {
521
                if ((dst != null) && (src != null)) {
522
                        if (dst.length < (dst_offset + length)) {
523
                                croak("dst.length = " + dst.length + ", but " +
524
                                        "dst_offset = " + dst_offset + " and length = " + length +
525
                                        ".");
526
                        }
527

    
528
                        if (src.length < (src_offset + length)) {
529
                                croak("src.length = " + src.length + ", but " +
530
                                        "src_offset = " + src_offset + " and length = " + length +
531
                                        ".");
532
                        }
533

    
534
                        for (int i = 0; i < length; ++i, ++dst_offset, ++src_offset)
535
                                dst[dst_offset] = src[src_offset];
536
                }
537

    
538
                return length;
539
        }
540

    
541
        /**
542
         * Compare the contents of one array of <code>bytes</code> to another.
543
         *
544
         * @param a the first array
545
         * @param a_offset the start offset in <code>a</code>
546
         * @param b the second array
547
         * @param b_offset the start offset in <code>b</code>
548
         * @param length the number of <code>byte</code>s to compare.
549
         *
550
         * @return DOCUMENT ME!
551
         */
552
        public static boolean memcmp(byte[] a, int a_offset, byte[] b,
553
                int b_offset, int length) {
554
                if ((a == null) && (b == null)) {
555
                        return true;
556
                }
557

    
558
                if ((a == null) || (b == null)) {
559
                        return false;
560
                }
561

    
562
                for (int i = 0; i < length; ++i, ++a_offset, ++b_offset)
563
                        if (a[a_offset] != b[b_offset]) {
564
                                return false;
565
                        }
566

    
567
                return true;
568
        }
569

    
570
        /**
571
         * Fill the given array with zeros.
572
         *
573
         * @param array the array to clear
574
         * @param offset the start offset
575
         * @param length the number of <code>byte</code>s to clear.
576
         */
577
        public static void memclr(byte[] array, int offset, int length) {
578
                for (int i = 0; i < length; ++i, ++offset)
579
                        array[offset] = 0;
580
        }
581

    
582
        /**
583
         * Round a number up to a given multiple.
584
         *
585
         * @param value the number to be rounded
586
         * @param multiple the number to which to be rounded
587
         *
588
         * @return the smallest <code>int</code> greater than or equal to
589
         *                    <code>value</code> which divides <code>multiple</code> exactly.
590
         */
591
        public static int round_up(int value, int multiple) {
592
                return (((value - 1) / multiple) + 1) * multiple;
593
        }
594

    
595
        /**
596
         * Return a new array equal to original except zero-padded to an integral
597
         * mulitple of blocks.  If the original is already an integral multiple of
598
         * blocks, just return it.
599
         *
600
         * @param original the array of <code>byte</code>s to be padded
601
         * @param block_size the size of the blocks
602
         *
603
         * @return an array whose size divides <code>block_size</code> exactly. The
604
         *                    array is either <code>original</code> itself, or a copy whose
605
         *                    first <code>original.length</code> bytes are equal to
606
         *                    <code>original</code>.
607
         */
608
        public static byte[] zero_pad(byte[] original, int block_size) {
609
                if ((original.length % block_size) == 0) {
610
                        return original;
611
                }
612

    
613
                byte[] result = new byte[round_up(original.length, block_size)];
614
                memcpy(result, 0, original, 0, original.length);
615

    
616
                // Unnecessary - jvm sets bytes to 0.
617
                // memclr (result, original.length, result.length - original.length);
618
                return result;
619
        }
620

    
621
        /**
622
         * Determines whether two arrays of <code>byte</code>s contain the same
623
         * contents.
624
         *
625
         * @param b1 The first array
626
         * @param b2 The second array
627
         *
628
         * @return <code>true</code> if both arrays are <code>null</code>, both
629
         *                    empty, or both of the same length with equal contents.
630
         */
631
        public static boolean equals(byte[] b1, byte[] b2) {
632
                if (b1 == b2) {
633
                        return true;
634
                }
635

    
636
                if ((b1 == null) || (b2 == null)) { // only one is null
637

    
638
                        return false;
639
                }
640

    
641
                if (b1.length != b2.length) {
642
                        return false;
643
                }
644

    
645
                for (int i = 0; i < b1.length; ++i)
646
                        if (b1[i] != b2[i]) {
647
                                return false;
648
                        }
649

    
650
                return true;
651
        }
652

    
653
        /**
654
         * Produce a <code>String</code> representation for the specified array of
655
         * <code>byte</code>s.  Print each <code>byte</code> as two hexadecimal
656
         * digits.
657
         *
658
         * @param data The array to print
659
         * @param offset the start offset in <code>data</code>
660
         * @param length the number of <code>byte</code>s to print
661
         *
662
         * @return DOCUMENT ME!
663
         */
664
        public static String print_bytes(byte[] data, int offset, int length) {
665
                int size = 2 * length;
666
                size += ((size / 8) + (size / 64));
667

    
668
                char[] buf = new char[size];
669
                int low_mask = 0x0f;
670
                int high_mask = 0xf0;
671
                int buf_pos = 0;
672
                byte b;
673

    
674
                int j = 0;
675

    
676
                for (int i = offset; i < (offset + length); ++i) {
677
                        b = data[i];
678
                        buf[buf_pos++] = digits[(high_mask & b) >> 4];
679
                        buf[buf_pos++] = digits[(low_mask & b)];
680

    
681
                        if ((j % 4) == 3) {
682
                                buf[buf_pos++] = ' ';
683
                        }
684

    
685
                        if ((j % 32) == 31) {
686
                                buf[buf_pos++] = '\n';
687
                        }
688

    
689
                        ++j;
690
                }
691

    
692
                return new String(buf);
693
        }
694

    
695
        /**
696
         * DOCUMENT ME!
697
         *
698
         * @param data DOCUMENT ME!
699
         * @param offset DOCUMENT ME!
700
         * @param length DOCUMENT ME!
701
         *
702
         * @return DOCUMENT ME!
703
         */
704
        public static String print_bytes_exact(byte[] data, int offset, int length) {
705
                int size = 2 * length;
706
                char[] buf = new char[size];
707
                int low_mask = 0x0f;
708
                int high_mask = 0xf0;
709
                int buf_pos = 0;
710
                byte b;
711

    
712
                int j = 0;
713

    
714
                for (int i = offset; i < (offset + length); ++i) {
715
                        b = data[i];
716
                        buf[buf_pos++] = digits[(high_mask & b) >> 4];
717
                        buf[buf_pos++] = digits[(low_mask & b)];
718
                        ++j;
719
                }
720

    
721
                return new String(buf);
722
        }
723

    
724
        /**
725
         * DOCUMENT ME!
726
         *
727
         * @param data DOCUMENT ME!
728
         *
729
         * @return DOCUMENT ME!
730
         */
731
        public static String print_bytes(byte[] data) {
732
                return print_bytes(data, 0, data.length);
733
        }
734

    
735
        /**
736
         * DOCUMENT ME!
737
         *
738
         * @param msg DOCUMENT ME!
739
         */
740
        private static void croak(String msg) {
741
                // throw new java.AssertionViolatedException(msg);
742
        }
743

    
744
        /**
745
         * DOCUMENT ME!
746
         *
747
         * @param b DOCUMENT ME!
748
         *
749
         * @return DOCUMENT ME!
750
         */
751
        public static int getUnsigned(byte b) {
752
                return ((b & 0xff)); // >> 8);
753
        }
754
}