1 package org.simantics.databoard.util.binary;
\r
3 import java.io.DataInput;
\r
4 import java.io.DataOutput;
\r
5 import java.io.IOException;
\r
8 * DataInput and DataOutput serialize primitive numbers with big endian byte
\r
9 * order. This utility absolutely does nothing but facades byte operations.
\r
11 * @author Toni Kalajainen <toni.kalajainen@iki.fi>
\r
13 public class Endian {
\r
14 public static void writeUInt24(DataOutput out, int value) throws IOException {
\r
15 out.write((value >> 16) & 0xff);
\r
16 out.write((value >> 8) & 0xff);
\r
17 out.write( value & 0xff);
\r
20 public static int readUInt24(DataInput in) throws IOException {
\r
22 ( ( in.readByte() << 16) ) & 0xffffff |
\r
23 ( in.readByte() << 8) |
\r
30 * Write UInt32 with dynamic encoding (1-5 bytes).
\r
34 * @throws IOException
\r
36 public static void writeDynamicUInt32(DataOutput out, int length) throws IOException {
\r
38 out.write((byte)length);
\r
42 if(length < 0x4000) {
\r
43 out.write( ((length&0x3f) | 0x80) );
\r
44 out.write( (length>>>6) );
\r
48 if(length < 0x200000) {
\r
49 out.write( ((length&0x1f) | 0xc0) );
\r
50 out.write( ((length>>>5)&0xff) );
\r
51 out.write( ((length>>>13)&0xff) );
\r
55 if(length < 0x10000000) {
\r
56 out.write( ((length&0x0f) | 0xe0) );
\r
57 out.write( ((length>>>4)&0xff) );
\r
58 out.write( ((length>>>12)&0xff) );
\r
59 out.write( ((length>>>20)&0xff) );
\r
62 length -= 0x10000000;
\r
63 out.write( ((length&0x07) | 0xf0) );
\r
64 out.write( ((length>>>3)&0xff) );
\r
65 out.write( ((length>>>11)&0xff) );
\r
66 out.write( ((length>>>19)&0xff) );
\r
67 out.write( ((length>>>27)&0xff) );
\r
75 public static int readDynamicUInt32(DataInput in) throws IOException {
\r
76 int length = in.readByte()&0xff;
\r
77 if(length >= 0x80) {
\r
78 if(length >= 0xc0) {
\r
79 if(length >= 0xe0) {
\r
80 if(length >= 0xf0) {
\r
82 length += ((in.readByte()&0xff)<<3);
\r
83 length += ((in.readByte()&0xff)<<11);
\r
84 length += ((in.readByte()&0xff)<<19);
\r
85 length += 0x10204080;
\r
89 length += ((in.readByte()&0xff)<<4);
\r
90 length += ((in.readByte()&0xff)<<12);
\r
91 length += ((in.readByte()&0xff)<<20);
\r
97 length += ((in.readByte()&0xff)<<5);
\r
98 length += ((in.readByte()&0xff)<<13);
\r
104 length += ((in.readByte()&0xff)<<6);
\r
113 * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)
\r
115 * @param length length value
\r
116 * @return bytes required (1-5)
\r
118 public static int getDynamicUInt32Length(int length)
\r
120 if(length < 0x80) return 1;
\r
121 if(length < 0x4080) return 2;
\r
122 if(length < 0x204000) return 3;
\r
123 if(length < 0x10200000) return 4;
\r
129 * Decode an unsigned integer. The number of bytes read depends on maxValue.
\r
134 * @throws IOException
\r
136 public static int getUInt(DataInput in, int maxValue)
\r
139 if (maxValue==0) return 0;
\r
140 if (maxValue<0x100) {
\r
141 return in.readByte() & 0xFF;
\r
142 } else if (maxValue<0x10000) {
\r
143 return in.readShort() & 0xFFFF;
\r
144 } else if (maxValue<0x1000000) {
\r
145 return Endian.readUInt24(in) & 0xFFFFFF;
\r
147 return in.readInt();
\r
152 * Calculate unsigned integer encoding length.
\r
155 * @return 0-4 bytes
\r
157 public static int getUIntLength(int maxValue)
\r
161 } else if (maxValue<0x100) {
\r
163 } else if (maxValue<0x10000) {
\r
165 } else if (maxValue<0x1000000) {
\r
173 * Encode and write an unsigned integer. The number of bytes written
\r
174 * depends on the maxValue.
\r
179 * @throws IOException
\r
181 public static void putUInt(DataOutput out, int value, int maxValue)
\r
182 throws IOException {
\r
183 if (maxValue==0) {}
\r
184 else if (maxValue<0x100) {
\r
186 } else if (maxValue<0x10000) {
\r
187 out.writeShort(value);
\r
188 } else if (maxValue<0x1000000) {
\r
189 writeUInt24(out, value);
\r
191 out.writeInt(value);
\r