1 package org.simantics.databoard.util.binary;
3 import java.io.DataInput;
4 import java.io.DataOutput;
5 import java.io.IOException;
8 * DataInput and DataOutput serialize primitive numbers with big endian byte
9 * order. This utility gives little endian read and write.
11 * @author Toni Kalajainen <toni.kalajainen@iki.fi>
13 public class LittleEndian {
15 public static short readShort(DataInput in) throws IOException {
16 return (short) (in.readUnsignedByte() | (in.readUnsignedByte() << 8));
19 public static void writeShort(DataOutput out, int v) throws IOException {
20 v = (((v & 0xFF00) >> 8) | (v << 8));
24 public static int readUnsignedShort(DataInput in) throws IOException {
25 int v = in.readUnsignedShort();
26 return (((v & 0xFF00) >> 8) | (v << 8));
29 public static int readInt(DataInput in) throws IOException {
30 return Integer.reverseBytes( in.readInt() );
33 public static void writeInt(DataOutput out, int v) throws IOException {
34 out.writeInt( Integer.reverseBytes( v ) );
37 public static long readLong(DataInput in) throws IOException {
38 return Long.reverseBytes( in.readLong() );
41 public static void writeLong(DataOutput out, long v) throws IOException {
42 out.writeLong( Long.reverseBytes(v) );
45 public static double readDouble(DataInput in) throws IOException {
46 return Double.longBitsToDouble( Long.reverseBytes( in.readLong() ) );
49 public static void writeDouble(DataOutput out, double d) throws IOException {
50 out.writeLong( Long.reverseBytes( Double.doubleToLongBits(d) ) );
53 public static float readFloat(DataInput in) throws IOException {
54 return Float.intBitsToFloat( Integer.reverseBytes( in.readInt() ) );
57 public static void writeFloat(DataOutput out, float v) throws IOException {
58 out.writeInt( Integer.reverseBytes( Float.floatToIntBits(v) ) );
61 public static void writeUInt24(DataOutput out, int value) throws IOException {
62 out.write((byte)value);
63 out.write((byte)(value >> 8));
64 out.write((byte)(value >> 16));
67 public static int readUInt24(DataInput in) throws IOException {
70 ( in.readByte() << 8) |
71 ( in.readByte() << 16) ) & 0xffffff;
77 * Write UInt32 with dynamic encoding (1-5 bytes).
83 public static void writeDynamicUInt32(DataOutput out, int length) throws IOException {
85 out.write((byte)length);
90 out.write((byte)((length&0x3f) | 0x80));
91 out.write((byte)(length>>>6));
95 if(length < 0x200000) {
96 out.write((byte)((length&0x1f) | 0xc0));
97 out.write((byte)((length>>>5)&0xff));
98 out.write((byte)((length>>>13)&0xff));
102 if(length < 0x10000000) {
103 out.write((byte)((length&0x0f) | 0xe0));
104 out.write((byte)((length>>>4)&0xff));
105 out.write((byte)((length>>>12)&0xff));
106 out.write((byte)((length>>>20)&0xff));
109 length -= 0x10000000;
110 out.write((byte)((length&0x07) | 0xf0));
111 out.write((byte)((length>>>3)&0xff));
112 out.write((byte)((length>>>11)&0xff));
113 out.write((byte)((length>>>19)&0xff));
114 out.write((byte)((length>>>27)&0xff));
122 public static int readDynamicUInt32(DataInput in) throws IOException {
123 int length = in.readByte()&0xff;
129 length += ((in.readByte()&0xff)<<3);
130 length += ((in.readByte()&0xff)<<11);
131 length += ((in.readByte()&0xff)<<19);
132 length += 0x10204080;
136 length += ((in.readByte()&0xff)<<4);
137 length += ((in.readByte()&0xff)<<12);
138 length += ((in.readByte()&0xff)<<20);
144 length += ((in.readByte()&0xff)<<5);
145 length += ((in.readByte()&0xff)<<13);
151 length += ((in.readByte()&0xff)<<6);
160 * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)
162 * @param length length value
163 * @return bytes required (1-5)
165 public static int getDynamicUInt32Length(int length)
167 if(length < 0x80) return 1;
168 if(length < 0x4080) return 2;
169 if(length < 0x204000) return 3;
170 if(length < 0x10200000) return 4;
176 * Decode an unsigned integer. The number of bytes read depends on maxValue.
181 * @throws IOException
183 public static int getUInt(DataInput in, int maxValue)
186 if (maxValue==0) return 0;
187 if (maxValue<0x100) {
188 return in.readByte() & 0xFF;
189 } else if (maxValue<0x10000) {
190 return LittleEndian.readShort(in) & 0xFFFF;
191 } else if (maxValue<0x1000000) {
192 return LittleEndian.readUInt24(in) & 0xFFFFFF;
199 * Calculate unsigned integer encoding length.
204 public static int getUIntLength(int maxValue)
208 } else if (maxValue<0x100) {
210 } else if (maxValue<0x10000) {
212 } else if (maxValue<0x1000000) {
220 * Encode and write an unsigned integer. The number of bytes written
221 * depends on the maxValue.
226 * @throws IOException
228 public static void putUInt(DataOutput out, int value, int maxValue)
231 else if (maxValue<0x100) {
233 } else if (maxValue<0x10000) {
234 LittleEndian.writeShort(out, value);
235 } else if (maxValue<0x1000000) {
236 LittleEndian.writeUInt24(out, value);