KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > services > io > CompressedNumber


1 /*
2
3    Derby - Class org.apache.derby.iapi.services.io.CompressedNumber
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.services.io;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26 import java.io.*;
27
28 /**
29     Static methods to write and read compressed forms of numbers
30     to DataOut and DataIn interfaces. Format written is platform
31     independent like the Data* interfaces and must remain fixed
32     once a product is shipped. If a different format is required
33     then write a new set of methods, e.g. writeInt2. The formats
34     defined by stored format identifiers are implicitly dependent
35     on these formats not changing.
36 */

37
38 public abstract class CompressedNumber {
39
40     // the maximum number of bytes written out for an int
41
public static final int MAX_INT_STORED_SIZE = 4;
42
43     // the maximum number of bytes written out for a long
44
public static final int MAX_LONG_STORED_SIZE = 8;
45
46     // largest int stored compressed in 1 byte
47
public static final int MAX_COMPRESSED_INT_ONE_BYTE = 0x3f;
48
49     // largest int stored compressed in 2 bytes
50
public static final int MAX_COMPRESSED_INT_TWO_BYTES = 0x3fff;
51
52
53     /**
54         Write a compressed integer only supporting signed values.
55         Formats are (with x representing value bits):
56         <PRE>
57         1 Byte - 00xxxxxx Represents the value <= 63 (0x3f)
58         2 Byte - 01xxxxxx xxxxxxxx Represents the value > 63 && <= 16383 (0x3fff)
59         4 byte - 1xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx Represents the value > 16383 && <= MAX_INT
60         </PRE>
61
62
63         @exception IOException value is negative or an exception was thrown by a method on out.
64     */

65     public static final int writeInt(DataOutput out, int value) throws IOException {
66
67         if (value < 0)
68             throw new IOException();
69
70         if (value <= 0x3f) {
71
72             out.writeByte(value);
73             return 1;
74         }
75
76         if (value <= 0x3fff) {
77
78             out.writeByte(0x40 | (value >>> 8));
79             out.writeByte(value & 0xff);
80             return 2;
81         }
82
83         out.writeByte(((value >>> 24) | 0x80) & 0xff);
84         out.writeByte((value >>> 16) & 0xff);
85         out.writeByte((value >>> 8) & 0xff);
86         out.writeByte((value) & 0xff);
87         return 4;
88     }
89
90     /**
91         Write a compressed integer directly to an OutputStream.
92         @exception IOException an exception was thrown by a method on in.
93     */

94     public static final int writeInt(OutputStream out, int value) throws IOException {
95
96         if (value < 0)
97             throw new IOException();
98
99         if (value <= 0x3f) {
100
101             out.write(value);
102             return 1;
103         }
104
105         if (value <= 0x3fff) {
106
107             out.write(0x40 | (value >>> 8));
108             out.write(value & 0xff);
109             return 2;
110         }
111
112         out.write(((value >>> 24) | 0x80) & 0xff);
113         out.write((value >>> 16) & 0xff);
114         out.write((value >>> 8) & 0xff);
115         out.write((value) & 0xff);
116         return 4;
117     }
118
119
120     /**
121         Read an integer previously written by writeInt().
122
123         @exception IOException an exception was thrown by a method on in.
124     */

125     public static final int readInt(DataInput in) throws IOException {
126
127         int value = in.readUnsignedByte();
128
129         if ((value & ~0x3f) == 0)
130         {
131             // length is stored in this byte, we also know that the 0x80 bit
132
// was not set, so no need to mask off the sign extension from
133
// the byte to int conversion.
134

135             // account for 1 byte stored length of field + 1 for all returns
136
return(value);
137         }
138         else if ((value & 0x80) == 0)
139         {
140             // length is stored in 2 bytes. only use low 6 bits from 1st byte.
141

142             if (SanityManager.DEBUG)
143             {
144                 SanityManager.ASSERT((value & 0x40) == 0x40);
145             }
146
147             // top 8 bits of 2 byte length is stored in this byte, we also
148
// know that the 0x80 bit was not set, so no need to mask off the
149
// sign extension from the 1st byte to int conversion. Need to
150
// mask the byte in data[offset + 1] to account for possible sign
151
// extension.
152

153             return(((value & 0x3f) << 8) | in.readUnsignedByte());
154         }
155         else
156         {
157             // length is stored in 4 bytes. only use low 7 bits from 1st byte.
158

159             if (SanityManager.DEBUG)
160             {
161                 SanityManager.ASSERT((value & 0x80) == 0x80);
162             }
163
164             // top 8 bits of 4 byte length is stored in this byte, we also
165
// know that the 0x80 bit was set, so need to mask off the
166
// sign extension from the 1st byte to int conversion. Need to
167
// mask the bytes from the next 3 bytes data[offset + 1,2,3] to
168
// account for possible sign extension.
169
//
170
return(
171                  ((value & 0x7f) << 24) |
172                  (in.readUnsignedByte() << 16) |
173                  (in.readUnsignedByte() << 8) |
174                  (in.readUnsignedByte() ));
175         }
176     }
177
178     /**
179         Read an integer previously written by writeInt().
180
181         @exception IOException an exception was thrown by a method on in.
182     */

183     public static final int readInt(InputStream in) throws IOException {
184
185         int value = InputStreamUtil.readUnsignedByte(in);
186
187         if ((value & ~0x3f) == 0)
188         {
189             return(value);
190         }
191         else if ((value & 0x80) == 0)
192         {
193             return(
194                 ((value & 0x3f) << 8) | InputStreamUtil.readUnsignedByte(in));
195         }
196         else
197         {
198             return(
199                 ((value & 0x7f) << 24) |
200                 (InputStreamUtil.readUnsignedByte(in) << 16) |
201                 (InputStreamUtil.readUnsignedByte(in) << 8) |
202                 (InputStreamUtil.readUnsignedByte(in) ));
203         }
204     }
205
206     public static final int readInt(
207     byte[] data,
208     int offset)
209     {
210         int value = data[offset++];
211
212         if ((value & ~0x3f) == 0)
213         {
214             // length is stored in this byte, we also know that the 0x80 bit
215
// was not set, so no need to mask off the sign extension from
216
// the byte to int conversion.
217

218             return(value);
219         }
220         else if ((value & 0x80) == 0)
221         {
222             // length is stored in 2 bytes. only use low 6 bits from 1st byte.
223

224             if (SanityManager.DEBUG)
225             {
226                 SanityManager.ASSERT((value & 0x40) == 0x40);
227             }
228
229             // top 8 bits of 2 byte length is stored in this byte, we also
230
// know that the 0x80 bit was not set, so no need to mask off the
231
// sign extension from the 1st byte to int conversion. Need to
232
// mask the byte in data[offset + 1] to account for possible sign
233
// extension.
234

235             return(((value & 0x3f) << 8) | (data[offset] & 0xff));
236         }
237         else
238         {
239             // length is stored in 4 bytes. only use low 7 bits from 1st byte.
240

241             if (SanityManager.DEBUG)
242             {
243                 SanityManager.ASSERT((value & 0x80) == 0x80);
244             }
245
246             // top 8 bits of 4 byte length is stored in this byte, we also
247
// know that the 0x80 bit was set, so need to mask off the
248
// sign extension from the 1st byte to int conversion. Need to
249
// mask the bytes from the next 3 bytes data[offset + 1,2,3] to
250
// account for possible sign extension.
251
//
252
return(
253                 ((value & 0x7f) << 24) |
254                 ((data[offset++] & 0xff) << 16) |
255                 ((data[offset++] & 0xff) << 8) |
256                 ((data[offset] & 0xff) ));
257         }
258     }
259
260     /**
261      * Return the compressed Int value + stored size of the length + 1
262      * <p>
263      * Given offset in array to beginning of compressed int, return the
264      * value of the compressed int + the number of bytes used to store the
265      * length.
266      * <p>
267      * So 1 byte lengths will return: length + 1 + 1
268      * So 2 byte lengths will return: length + 2 + 1
269      * So 4 byte lengths will return: length + 4 + 1
270      * <p>
271      * Note that this routine will not work for lengths MAX_INT - (MAX_INT - 5).
272      * <p>
273      * This routine is currently used by the StorePage code to skip fields
274      * as efficiently as possible. Since the page size is less than
275      * (MAX_INT - 5) it is all right to use this routine.
276      *
277      * @return compressed int value + length used to store the length.
278      *
279      * @param data byte array containing the field.
280      * @param offset offset to beginning of field, ie. data[offset] contains
281      * 1st byte of the compressed int.
282      **/

283     public static final int readIntAndReturnIntPlusOverhead(
284     byte[] data,
285     int offset)
286     {
287         int value = data[offset];
288
289         if ((value & ~0x3f) == 0)
290         {
291             // length is stored in this byte, we also know that the 0x80 bit
292
// was not set, so no need to mask off the sign extension from
293
// the byte to int conversion.
294

295             // account for 1 byte stored length of field + 1 for all returns
296
return(value + 2);
297         }
298         else if ((value & 0x80) == 0)
299         {
300             // length is stored in 2 bytes. only use low 6 bits from 1st byte.
301

302             if (SanityManager.DEBUG)
303             {
304                 SanityManager.ASSERT((value & 0x40) == 0x40);
305             }
306
307             // top 8 bits of 2 byte length is stored in this byte, we also
308
// know that the 0x80 bit was not set, so no need to mask off the
309
// sign extension from the 1st byte to int conversion. Need to
310
// mask the byte in data[offset + 1] to account for possible sign
311
// extension.
312

313             // add 3 to account for 2 byte length + 1 added to all returns
314

315             return((((value & 0x3f) << 8) | (data[offset + 1] & 0xff)) + 3);
316         }
317         else
318         {
319             // length is stored in 4 bytes. only use low 7 bits from 1st byte.
320

321             if (SanityManager.DEBUG)
322             {
323                 SanityManager.ASSERT((value & 0x80) == 0x80);
324             }
325
326             // top 8 bits of 4 byte length is stored in this byte, we also
327
// know that the 0x80 bit was set, so need to mask off the
328
// sign extension from the 1st byte to int conversion. Need to
329
// mask the bytes from the next 3 bytes data[offset + 1,2,3] to
330
// account for possible sign extension.
331

332
333             // add 5 to account for 4 byte length + 1 added to all returns
334
return(
335                 (((value & 0x7f) << 24) |
336                  ((data[offset + 1] & 0xff) << 16) |
337                  ((data[offset + 2] & 0xff) << 8) |
338                   (data[offset + 3] & 0xff)) + 5);
339         }
340     }
341
342
343     /**
344         Skip an integer previously written by writeInt().
345
346         @exception IOException an exception was thrown by a method on in.
347     */

348     public static final int skipInt(DataInput in) throws IOException {
349
350         int value = in.readUnsignedByte();
351
352         if ((value & 0x80) == 0x80) {
353             in.skipBytes(3);
354             return 4;
355         }
356
357         if ((value & 0x40) == 0x40) {
358             in.skipBytes(1);
359             return 2;
360         }
361
362         return 1;
363     }
364
365     /**
366         Skip an integer previously written by writeInt().
367
368         @exception IOException an exception was thrown by a method on in.
369     */

370     public static final int skipInt(InputStream in) throws IOException {
371
372         int value = InputStreamUtil.readUnsignedByte(in);
373
374         int skipBytes = 0;
375
376         if ((value & 0x80) == 0x80) {
377             skipBytes = 3;
378         }
379         else if ((value & 0x40) == 0x40) {
380             skipBytes = 1;
381         }
382
383         if (skipBytes != 0) {
384             if (in.skip(skipBytes) != skipBytes)
385                 throw new EOFException();
386         }
387
388
389         return skipBytes + 1;
390     }
391
392     /**
393         Return the number of bytes that would be written by a writeInt call
394     */

395     public static final int sizeInt(int value) {
396         if (value <= 0x3f) {
397             return 1;
398         }
399         if (value <= 0x3fff) {
400             return 2;
401         }
402         return 4;
403     }
404
405     /**
406         Write a compressed long only supporting signed values.
407
408         Formats are (with x representing value bits):
409         <PRE>
410         2 byte - 00xxxxxx xxxxxxxx Represents the value <= 16383 (0x3fff)
411         4 byte - 01xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx Represents the value > 16383 && <= 0x3fffffff
412         8 byte - 1xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx Represents the value > 0x3fffffff && <= MAX_LONG
413         </PRE>
414
415
416         @exception IOException value is negative or an exception was thrown by a method on out.
417     */

418     public static final int writeLong(DataOutput out, long value) throws IOException {
419
420         if (value < 0)
421             throw new IOException();
422
423         if (value <= 0x3fff) {
424
425             out.writeByte((int) ((value >>> 8) & 0xff));
426             out.writeByte((int) ((value ) & 0xff));
427             return 2;
428         }
429
430         if (value <= 0x3fffffff) {
431
432             out.writeByte((int) (((value >>> 24) | 0x40) & 0xff));
433             out.writeByte((int) ( (value >>> 16) & 0xff));
434             out.writeByte((int) ( (value >>> 8) & 0xff));
435             out.writeByte((int) ( (value ) & 0xff));
436             return 4;
437         }
438
439         out.writeByte((int) (((value >>> 56) | 0x80) & 0xff));
440         out.writeByte((int) ( (value >>> 48) & 0xff));
441         out.writeByte((int) ( (value >>> 40) & 0xff));
442         out.writeByte((int) ( (value >>> 32) & 0xff));
443         out.writeByte((int) ( (value >>> 24) & 0xff));
444         out.writeByte((int) ( (value >>> 16) & 0xff));
445         out.writeByte((int) ( (value >>> 8) & 0xff));
446         out.writeByte((int) ( (value ) & 0xff));
447         return 8;
448     }
449     /**
450         Write a compressed integer only supporting signed values.
451
452         @exception IOException value is negative or an exception was thrown by a method on out.
453     */

454     public static final int writeLong(OutputStream out, long value) throws IOException {
455
456         if (value < 0)
457             throw new IOException();
458
459         if (value <= 0x3fff) {
460
461             out.write((int) ((value >>> 8) & 0xff));
462             out.write((int) ((value ) & 0xff));
463             return 2;
464         }
465
466         if (value <= 0x3fffffff) {
467
468             out.write((int) (((value >>> 24) | 0x40) & 0xff));
469             out.write((int) ( (value >>> 16) & 0xff));
470             out.write((int) ( (value >>> 8) & 0xff));
471             out.write((int) ( (value ) & 0xff));
472             return 4;
473         }
474
475         out.write((int) (((value >>> 56) | 0x80) & 0xff));
476         out.write((int) ( (value >>> 48) & 0xff));
477         out.write((int) ( (value >>> 40) & 0xff));
478         out.write((int) ( (value >>> 32) & 0xff));
479         out.write((int) ( (value >>> 24) & 0xff));
480         out.write((int) ( (value >>> 16) & 0xff));
481         out.write((int) ( (value >>> 8) & 0xff));
482         out.write((int) ( (value ) & 0xff));
483         return 8;
484     }
485
486     /**
487         Read a long previously written by writeLong().
488
489         @exception IOException an exception was thrown by a method on in.
490     */

491     public static final long readLong(DataInput in) throws IOException {
492
493         int int_value = in.readUnsignedByte();
494
495         if ((int_value & ~0x3f) == 0)
496         {
497             // test for small case first - assuming this is usual case.
498
// this is stored in 2 bytes.
499

500             return((int_value << 8) | in.readUnsignedByte());
501         }
502         else if ((int_value & 0x80) == 0)
503         {
504             // value is stored in 4 bytes. only use low 6 bits from 1st byte.
505

506             return(
507                 ((int_value & 0x3f) << 24) |
508                 (in.readUnsignedByte() << 16) |
509                 (in.readUnsignedByte() << 8) |
510                 (in.readUnsignedByte()));
511         }
512         else
513         {
514             // value is stored in 8 bytes. only use low 7 bits from 1st byte.
515
return(
516                 (((long) (int_value & 0x7f) ) << 56) |
517                 (((long) in.readUnsignedByte()) << 48) |
518                 (((long) in.readUnsignedByte()) << 40) |
519                 (((long) in.readUnsignedByte()) << 32) |
520                 (((long) in.readUnsignedByte()) << 24) |
521                 (((long) in.readUnsignedByte()) << 16) |
522                 (((long) in.readUnsignedByte()) << 8) |
523                 (((long) in.readUnsignedByte()) ));
524         }
525     }
526
527     /**
528         Read a long previously written by writeLong().
529
530         @exception IOException an exception was thrown by a method on in.
531     */

532     public static final long readLong(InputStream in) throws IOException {
533
534         int int_value = InputStreamUtil.readUnsignedByte(in);
535
536         if ((int_value & ~0x3f) == 0)
537         {
538             // test for small case first - assuming this is usual case.
539
// this is stored in 2 bytes.
540

541             return((int_value << 8) | InputStreamUtil.readUnsignedByte(in));
542         }
543         else if ((int_value & 0x80) == 0)
544         {
545             // value is stored in 4 bytes. only use low 6 bits from 1st byte.
546

547             return(
548                 ((int_value & 0x3f) << 24) |
549                 (InputStreamUtil.readUnsignedByte(in) << 16) |
550                 (InputStreamUtil.readUnsignedByte(in) << 8) |
551                 (InputStreamUtil.readUnsignedByte(in) ));
552
553         }
554         else
555         {
556             // value is stored in 8 bytes. only use low 7 bits from 1st byte.
557
long value = int_value;
558
559             return(
560                 (((long) (value & 0x7f) ) << 56) |
561                 (((long) InputStreamUtil.readUnsignedByte(in)) << 48) |
562                 (((long) InputStreamUtil.readUnsignedByte(in)) << 40) |
563                 (((long) InputStreamUtil.readUnsignedByte(in)) << 32) |
564                 (((long) InputStreamUtil.readUnsignedByte(in)) << 24) |
565                 (((long) InputStreamUtil.readUnsignedByte(in)) << 16) |
566                 (((long) InputStreamUtil.readUnsignedByte(in)) << 8) |
567                 (((long) InputStreamUtil.readUnsignedByte(in)) ));
568         }
569     }
570
571     public static final long readLong(
572     byte[] data,
573     int offset)
574     {
575         int int_value = data[offset++];
576
577         if ((int_value & ~0x3f) == 0)
578         {
579             // test for small case first - assuming this is usual case.
580
// this is stored in 2 bytes.
581

582             return((int_value << 8) | (data[offset] & 0xff));
583         }
584         else if ((int_value & 0x80) == 0)
585         {
586             // value is stored in 4 bytes. only use low 6 bits from 1st byte.
587

588             return(
589                 ((int_value & 0x3f) << 24) |
590                 ((data[offset++] & 0xff) << 16) |
591                 ((data[offset++] & 0xff) << 8) |
592                 ((data[offset] & 0xff) ));
593
594         }
595         else
596         {
597             // value is stored in 8 bytes. only use low 6 bits from 1st byte.
598
return(
599                 (((long) (int_value & 0x7f)) << 56) |
600                 (((long) (data[offset++] & 0xff)) << 48) |
601                 (((long) (data[offset++] & 0xff)) << 40) |
602                 (((long) (data[offset++] & 0xff)) << 32) |
603                 (((long) (data[offset++] & 0xff)) << 24) |
604                 (((long) (data[offset++] & 0xff)) << 16) |
605                 (((long) (data[offset++] & 0xff)) << 8) |
606                 (((long) (data[offset] & 0xff)) ));
607
608         }
609     }
610
611     /**
612         Skip a long previously written by writeLong().
613
614         @exception IOException an exception was thrown by a method on in.
615     */

616     public static final int skipLong(DataInput in) throws IOException {
617
618         long value = in.readUnsignedByte();
619
620         if ((value & 0x80) == 0x80)
621         {
622             in.skipBytes(7);
623             return 8;
624         }
625         
626         
627         if ((value & 0x40) == 0x40)
628         {
629             in.skipBytes(3);
630             return 4;
631
632         }
633
634         in.skipBytes(1);
635         return 2;
636     }
637
638     /**
639         Skip a long previously written by writeLong().
640
641         @exception IOException an exception was thrown by a method on in.
642     */

643     public static final int skipLong(InputStream in) throws IOException {
644
645         int value = InputStreamUtil.readUnsignedByte(in);
646
647         int skipBytes;
648
649         if ((value & 0x80) == 0x80) {
650             skipBytes = 7;
651         }
652         else if ((value & 0x40) == 0x40) {
653             skipBytes = 3;
654         }
655         else
656             skipBytes = 1;
657
658         if (in.skip(skipBytes) != skipBytes)
659             throw new EOFException();
660
661         return skipBytes + 1;
662     }
663
664     public static final int sizeLong(long value) {
665
666         if (value <= 0x3fff) {
667
668             return 2;
669         }
670
671         if (value <= 0x3fffffff) {
672             return 4;
673         }
674
675         return 8;
676     }
677
678 // /* FOR TESTING
679
// *****************************************************
680

681     private static byte[] holder = new byte[8];
682     private static ArrayOutputStream aos = new ArrayOutputStream(holder);
683     private static DataOutput out = new DataOutputStream(aos);
684
685     private static ArrayInputStream ais = new ArrayInputStream(holder);
686     private static DataInput in = new DataInputStream(ais);
687     private static InputStream in_stream = ais;
688
689
690     private static short checkInt(int i, short oldLength) throws IOException {
691
692         aos.setPosition(0);
693         int length = CompressedNumber.writeInt(out, i);
694         if (length != oldLength) {
695             System.out.println("changing length to " + length + " at value " + i + " 0x" + Integer.toHexString(i));
696
697             oldLength = (short) length;
698         }
699
700         int writtenBytes = aos.getPosition();
701         if (writtenBytes != length) {
702             System.out.println("MISMATCH written bytes expected " + length + " got " + writtenBytes);
703             System.exit(1);
704         }
705
706         if (length != CompressedNumber.sizeInt(i)) {
707             System.out.println("MISMATCH sizeInt() bytes expected " + length + " got " + CompressedNumber.sizeInt(i));
708             System.exit(1);
709         }
710
711         ais.setPosition(0);
712         int value = CompressedNumber.readInt(in);
713         if (value != i) {
714             System.out.println("MISMATCH value readInt(DataInput) expected " + i + " got " + value);
715             System.exit(1);
716         }
717
718         ais.setPosition(0);
719         value = ais.readCompressedInt();
720         if (value != i) {
721             System.out.println("MISMATCH value readInt(DataInput) expected " + i + " got " + value);
722             System.exit(1);
723         }
724
725         ais.setPosition(0);
726         value = CompressedNumber.readInt(in_stream);
727         if (value != i) {
728             System.out.println("MISMATCH value in readInt(InputStream) expected " + i + " got " + value);
729             System.exit(1);
730         }
731
732
733         value = CompressedNumber.readInt(holder, 0);
734         if (value != i) {
735             System.out.println(
736                 "MISMATCH frome readInt(byte[], offset) value expected " +
737                 i + " got " + value);
738             System.exit(1);
739         }
740
741         ais.setPosition(0);
742         int skipLength = CompressedNumber.skipInt(in);
743         if (skipLength != length) {
744             System.out.println("MISMATCH skip length expected " + length + " got " + skipLength);
745             System.exit(1);
746         }
747
748         int value_plus_int_length = readIntAndReturnIntPlusOverhead(holder, 0);
749         if (value_plus_int_length != (length + i + 1)) {
750             System.out.println("MISMATCH readIntAndReturnIntPlusOverhead() return expected " + (length + i) + " got " + value_plus_int_length);
751             System.exit(1);
752         }
753
754         int skipPosition = ais.getPosition();
755         if (skipPosition != length) {
756             System.out.println("MISMATCH skip position expected " + length + " got " + skipPosition);
757             System.exit(1);
758         }
759
760         return oldLength;
761     }
762
763     private static short checkLong(long i, short oldLength) throws IOException {
764
765         aos.setPosition(0);
766         int length = CompressedNumber.writeLong(out, i);
767         if (length != oldLength) {
768             System.out.println("changing length to " + length + " at value " + i + " 0x" + Long.toHexString(i));
769             oldLength = (short) length;
770         }
771
772         int writtenBytes = aos.getPosition();
773         if (writtenBytes != length) {
774             System.out.println("MISMATCH written bytes expected " + length + " got " + writtenBytes);
775             System.exit(1);
776         }
777
778         if (length != CompressedNumber.sizeLong(i)) {
779             System.out.println("MISMATCH sizeLong() bytes expected " + length + " got " + CompressedNumber.sizeLong(i));
780             System.exit(1);
781         }
782
783         long value = CompressedNumber.readLong(holder, 0);
784         if (value != i) {
785             for (int j = 0; j < 8; j++) {
786
787                 System.out.println(Integer.toHexString((int) holder[j]));
788             }
789
790             System.out.println(
791                 "MISMATCH in readLong(byte[], offset) value expected " +
792                 Long.toHexString(i) + " got " + value);
793             System.exit(1);
794         }
795
796         ais.setPosition(0);
797         value = CompressedNumber.readLong(in_stream);
798         if (value != i) {
799             for (int j = 0; j < 8; j++) {
800
801                 System.out.println(Integer.toHexString((int) holder[j]));
802             }
803             System.out.println("MISMATCH value in readLong(InputStream) expected " + Long.toHexString(i) + " got " + value);
804             System.exit(1);
805         }
806
807         ais.setPosition(0);
808         value = ais.readCompressedLong();
809         if (value != i) {
810             for (int j = 0; j < 8; j++) {
811
812                 System.out.println(Integer.toHexString((int) holder[j]));
813             }
814             System.out.println("MISMATCH value in readLong(InputStream) expected " + Long.toHexString(i) + " got " + value);
815             System.exit(1);
816         }
817
818
819         ais.setPosition(0);
820         value = CompressedNumber.readLong(in);
821         if (value != i) {
822             for (int j = 0; j < 8; j++) {
823
824                 System.out.println(Integer.toHexString((int) holder[j]));
825             }
826             System.out.println("MISMATCH value in readLong(DataInput) expected " + Long.toHexString(i) + " got " + value);
827             System.exit(1);
828         }
829
830         ais.setPosition(0);
831         int skipLength = CompressedNumber.skipLong(in);
832         if (skipLength != length) {
833             System.out.println("MISMATCH skip length expected " + length + " got " + skipLength);
834             System.exit(1);
835         }
836
837         int skipPosition = ais.getPosition();
838         if (skipPosition != length) {
839             System.out.println("MISMATCH skip position expected " + length + " got " + skipPosition);
840             System.exit(1);
841         }
842
843         return oldLength;
844     }
845
846     public static void main(String JavaDoc[] args) throws IOException {
847
848         short oldLength = -1;
849
850         System.out.println("** Testing Int");
851
852         oldLength = checkInt(0, oldLength);
853         oldLength = checkInt(1, oldLength);
854         oldLength = checkInt(2, oldLength);
855
856         oldLength = checkInt(0x3f - 4, oldLength);
857         oldLength = checkInt(0x3f - 3, oldLength);
858         oldLength = checkInt(0x3f - 2, oldLength);
859         oldLength = checkInt(0x3f - 1, oldLength);
860         oldLength = checkInt(0x3f , oldLength);
861         oldLength = checkInt(0x3f + 1, oldLength);
862         oldLength = checkInt(0x3f + 2, oldLength);
863         oldLength = checkInt(0x3f + 3, oldLength);
864         oldLength = checkInt(0x3f + 4, oldLength);
865
866         oldLength = checkInt(0x3f80 - 4, oldLength);
867         oldLength = checkInt(0x3f80 - 3, oldLength);
868         oldLength = checkInt(0x3f80 - 2, oldLength);
869         oldLength = checkInt(0x3f80 - 1, oldLength);
870         oldLength = checkInt(0x3f80 , oldLength);
871         oldLength = checkInt(0x3f80 + 1, oldLength);
872         oldLength = checkInt(0x3f80 + 2, oldLength);
873         oldLength = checkInt(0x3f80 + 3, oldLength);
874         oldLength = checkInt(0x3f80 + 4, oldLength);
875
876         oldLength = checkInt(0x3fff - 4, oldLength);
877         oldLength = checkInt(0x3fff - 3, oldLength);
878         oldLength = checkInt(0x3fff - 2, oldLength);
879         oldLength = checkInt(0x3fff - 1, oldLength);
880         oldLength = checkInt(0x3fff , oldLength);
881         oldLength = checkInt(0x3fff + 1, oldLength);
882         oldLength = checkInt(0x3fff + 2, oldLength);
883         oldLength = checkInt(0x3fff + 3, oldLength);
884         oldLength = checkInt(0x3fff + 4, oldLength);
885
886         oldLength = checkInt(Integer.MAX_VALUE - 4, oldLength);
887         oldLength = checkInt(Integer.MAX_VALUE - 3, oldLength);
888         oldLength = checkInt(Integer.MAX_VALUE - 2, oldLength);
889         oldLength = checkInt(Integer.MAX_VALUE - 1, oldLength);
890         oldLength = checkInt(Integer.MAX_VALUE , oldLength);
891
892         oldLength = -1;
893         for (int i = 0; i < 0xf0000; i++)
894         {
895             oldLength = checkInt(i, oldLength);
896         }
897
898         // takes 30 minutes to run.
899
//
900
// for (int i = 0; i < Integer.MAX_VALUE; i++)
901
// {
902
// if (i % 0x00800000 == 0)
903
// System.out.println("checking: " + i);
904
//
905
// oldLength = checkInt(i, oldLength);
906
// }
907

908
909         System.out.println("** Testing Long");
910
911         oldLength = -1;
912         for (int i = 0; i < 0xf0000; i++)
913         {
914             oldLength = checkLong(i, oldLength);
915         }
916     
917         oldLength = -1;
918         
919         oldLength = checkLong(0, oldLength);
920         oldLength = checkLong(1, oldLength);
921         oldLength = checkLong(2, oldLength);
922
923         oldLength = checkLong(0x3fff - 2, oldLength);
924         oldLength = checkLong(0x3fff - 1, oldLength);
925         oldLength = checkLong(0x3fff , oldLength);
926         oldLength = checkLong(0x3fff + 1, oldLength);
927         oldLength = checkLong(0x3fff + 2, oldLength);
928
929         oldLength = checkLong(0x3fffffff - 4, oldLength);
930         oldLength = checkLong(0x3fffffff - 3, oldLength);
931         oldLength = checkLong(0x3fffffff - 2, oldLength);
932         oldLength = checkLong(0x3fffffff - 1, oldLength);
933         oldLength = checkLong(0x3fffffff , oldLength);
934         oldLength = checkLong(0x3fffffff + 1, oldLength);
935         oldLength = checkLong(0x3fffffff + 2, oldLength);
936         oldLength = checkLong(0x3fffffff + 3, oldLength);
937         oldLength = checkLong(0x3fffffff + 4, oldLength);
938
939         oldLength = checkLong(0x70000000 - 2, oldLength);
940         oldLength = checkLong(0x70000000 - 1, oldLength);
941         oldLength = checkLong(0x70000000 , oldLength);
942         oldLength = checkLong(0x70000000 + 1, oldLength);
943         oldLength = checkLong(0x70000000 + 2, oldLength);
944
945
946         oldLength = checkLong(Long.MAX_VALUE - 2, oldLength);
947         oldLength = checkLong(Long.MAX_VALUE - 1, oldLength);
948         oldLength = checkLong(Long.MAX_VALUE , oldLength);
949
950
951     }
952 // ********************************************************/
953
}
954
Popular Tags