001 /*
002 * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003 *
004 * http://uio.imagero.com
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 * o Redistributions of source code must retain the above copyright notice,
010 * this list of conditions and the following disclaimer.
011 *
012 * o Redistributions in binary form must reproduce the above copyright notice,
013 * this list of conditions and the following disclaimer in the documentation
014 * and/or other materials provided with the distribution.
015 *
016 * o Neither the name of Andrey Kuznetsov nor the names of
017 * its contributors may be used to endorse or promote products derived
018 * from this software without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032 package com.imagero.uio;
033
034 import com.imagero.uio.io.BitInputStream;
035 import com.imagero.uio.io.BitOutputStream;
036 import com.imagero.uio.io.ByteArrayOutputStreamExt;
037 import com.imagero.uio.RandomAccessInput;
038 import com.imagero.uio.xform.XTransformer;
039 import com.imagero.uio.xform.ByteToXBE;
040 import com.imagero.uio.xform.ByteToXLE;
041 import com.imagero.uio.xform.XtoByteBE;
042 import com.imagero.uio.xform.XtoByteLE;
043
044 import java.io.ByteArrayInputStream;
045 import java.io.IOException;
046
047 /**
048 * Primitive type conversion, array copying, etc.
049 *
050 * @author Andrey Kuznetsov
051 */
052 public class Transformer extends XTransformer {
053
054
055
056 public static final int byteToInt(byte[] source, int sourceOffset, int[] dest, int destOffset, boolean bigEndian) {
057 if (bigEndian) {
058 return ByteToXBE.byteToInt(source, sourceOffset, dest, destOffset);
059 } else {
060 return ByteToXLE.byteToInt(source, sourceOffset, dest, destOffset);
061 }
062 }
063
064 public static final void byteToInt(byte[] source, int sourceOffset, int count, int[] dest, int destOffset, boolean bigEndian) {
065 if (bigEndian) {
066 ByteToXBE.byteToInt(source, sourceOffset, count, dest, destOffset);
067 } else {
068 ByteToXLE.byteToInt(source, sourceOffset, count, dest, destOffset);
069 }
070 }
071
072 public static final int intToByte(int[] source, int sourceOffset, byte[] dest, int destOffset, boolean bigEndian) {
073 if (bigEndian) {
074 return XtoByteBE.intToByte(source, sourceOffset, dest, destOffset);
075 } else {
076 return XtoByteLE.intToByte(source, sourceOffset, dest, destOffset);
077 }
078 }
079
080 public static final void intToByte(int[] source, int srcOffset, int count, byte[] dest, int destOffset, boolean bigEndian) {
081 if (bigEndian) {
082 XtoByteBE.intToByte(source, srcOffset, count, dest, destOffset);
083 } else {
084 XtoByteLE.intToByte(source, srcOffset, count, dest, destOffset);
085 }
086 }
087
088 public static int intToByte(int v, byte[] dest, int destOffset, boolean bigEndian) {
089 if (bigEndian) {
090 return XtoByteBE.intToByte(v, dest, destOffset);
091 } else {
092 return XtoByteLE.intToByte(v, dest, destOffset);
093 }
094 }
095
096 public static final int byteToInt(byte[] source, int sourceOffset, boolean bigEndian) {
097 if (bigEndian) {
098 return ByteToXBE.byteToInt(source, sourceOffset);
099 } else {
100 return ByteToXLE.byteToInt(source, sourceOffset);
101 }
102 }
103
104
105 /* **********************************************************************/
106
107 public static int byteToChar(byte[] source, int sourceOffset, char[] dest, int destOffset, boolean bigEndian) {
108 if (bigEndian) {
109 return ByteToXBE.byteToChar(source, sourceOffset, dest, destOffset);
110 } else {
111 return ByteToXLE.byteToChar(source, sourceOffset, dest, destOffset);
112 }
113 }
114
115 public static void byteToChar(byte[] source, int sourceOffset, int count, char[] dest, int destOffset, boolean bigEndian) {
116 if (bigEndian) {
117 ByteToXBE.byteToChar(source, sourceOffset, count, dest, destOffset);
118 } else {
119 ByteToXLE.byteToChar(source, sourceOffset, count, dest, destOffset);
120 }
121 }
122
123 public static int byteToChar(byte[] source, int sourceOffset, boolean bigEndian) {
124 if (bigEndian) {
125 return ByteToXBE.byteToChar(source, sourceOffset);
126 } else {
127 return ByteToXLE.byteToChar(source, sourceOffset);
128 }
129 }
130
131 /* **********************************************************************/
132 public static int charToByte(char[] source, int srcOffset, byte[] dest, int destOffset, boolean bigEndian) {
133 if (bigEndian) {
134 return XtoByteBE.charToByte(source, srcOffset, dest, destOffset);
135 } else {
136 return XtoByteLE.charToByte(source, srcOffset, dest, destOffset);
137 }
138 }
139
140 public static int charToByte(char v, byte[] dest, int destOffset, boolean bigEndian) {
141 if (bigEndian) {
142 return XtoByteBE.charToByte(v, dest, destOffset);
143 } else {
144 return XtoByteLE.charToByte(v, dest, destOffset);
145 }
146 }
147
148 public static void charToByte(char[] source, int srcOffset, int count, byte[] dest, int destOffset, boolean bigEndian) {
149 if (bigEndian) {
150 XtoByteBE.charToByte(source, srcOffset, count, dest, destOffset);
151 } else {
152 XtoByteLE.charToByte(source, srcOffset, count, dest, destOffset);
153 }
154 }
155
156 /* **********************************************************************/
157
158 public static int byteToDouble(byte[] source, int sourceOffset, double[] dest, int destOffset, boolean bigEndian) {
159 if (bigEndian) {
160 return ByteToXBE.byteToDoubleBE(source, sourceOffset, dest, destOffset);
161 } else {
162 return ByteToXLE.byteToDoubleLE(source, sourceOffset, dest, destOffset);
163 }
164 }
165
166 public static void byteToDouble(byte[] source, int sourceOffset, int count, double[] dest, int destOffset, boolean bigEndian) {
167 if (bigEndian) {
168 ByteToXBE.byteToDoubleBE(source, sourceOffset, count, dest, destOffset);
169 } else {
170 ByteToXLE.byteToDoubleLE(source, sourceOffset, count, dest, destOffset);
171 }
172 }
173
174 public static double byteToDouble(byte[] source, int sourceOffset, boolean bigEndian) {
175 if (bigEndian) {
176 return ByteToXBE.byteToDoubleBE(source, sourceOffset);
177 } else {
178 return ByteToXLE.byteToDoubleLE(source, sourceOffset);
179 }
180 }
181
182 /* **********************************************************************/
183
184 public static int doubleToByte(double[] source, int srcOffset, byte[] dest, int destOffset, boolean bigEndian) {
185 if (bigEndian) {
186 return XtoByteBE.doubleToByteBE(source, srcOffset, dest, destOffset);
187 } else {
188 return XtoByteLE.doubleToByteLE(source, srcOffset, dest, destOffset);
189 }
190 }
191
192 public static void doubleToByte(double[] source, int srcOffset, int count, byte[] dest, int destOffset, boolean bigEndian) {
193 if (bigEndian) {
194 XtoByteBE.doubleToByteBE(source, srcOffset, count, dest, destOffset);
195 } else {
196 XtoByteLE.doubleToByteLE(source, srcOffset, count, dest, destOffset);
197 }
198 }
199
200 public static int doubleToByte(double d, byte[] dest, int destOffset, boolean bigEndian) {
201 if (bigEndian) {
202 return XtoByteBE.doubleToByteBE(d, dest, destOffset);
203 } else {
204 return XtoByteLE.doubleToByteLE(d, dest, destOffset);
205 }
206 }
207
208 /* **********************************************************************/
209
210 public static int byteToFloat(byte[] source, int sourceOffset, float[] dest, int destOffset, boolean bigEndian) {
211 if (bigEndian) {
212 return ByteToXBE.byteToFloatBE(source, sourceOffset, dest, destOffset);
213 } else {
214 return ByteToXLE.byteToFloatLE(source, sourceOffset, dest, destOffset);
215 }
216 }
217
218 public static void byteToFloat(byte[] source, int sourceOffset, int count, float[] dest, int destOffset, boolean bigEndian) {
219 if (bigEndian) {
220 ByteToXBE.byteToFloatBE(source, sourceOffset, count, dest, destOffset);
221 } else {
222 ByteToXLE.byteToFloatLE(source, sourceOffset, count, dest, destOffset);
223 }
224 }
225
226 public static float byteToFloat(byte[] source, int sourceOffset, boolean bigEndian) {
227 if (bigEndian) {
228 return ByteToXBE.byteToFloatBE(source, sourceOffset);
229 } else {
230 return ByteToXLE.byteToFloatLE(source, sourceOffset);
231 }
232 }
233
234 /* **********************************************************************/
235
236 public static int floatToByte(float[] source, int offset, byte[] dest, int destOffset, boolean bigEndian) {
237 if (bigEndian) {
238 return XtoByteBE.floatToByteBE(source, offset, dest, destOffset);
239 } else {
240 return XtoByteLE.floatToByteLE(source, offset, dest, destOffset);
241 }
242 }
243
244 public static void floatToByte(float[] source, int offset, int count, byte[] dest, int destOffset, boolean bigEndian) {
245 if (bigEndian) {
246 XtoByteBE.floatToByteBE(source, offset, count, dest, destOffset);
247 } else {
248 XtoByteLE.floatToByteLE(source, offset, count, dest, destOffset);
249 }
250 }
251
252 public static int floatToByte(float f, byte[] dest, int destOffset, boolean bigEndian) {
253 if (bigEndian) {
254 return XtoByteBE.floatToByteBE(f, dest, destOffset);
255 } else {
256 return XtoByteLE.floatToByteLE(f, dest, destOffset);
257 }
258 }
259
260 /* **********************************************************************/
261
262 public static int byteToLong(byte[] source, int sourceOffset, long[] dest, int destOffset, boolean bigEndian) {
263 if (bigEndian) {
264 return ByteToXBE.byteToLongBE(source, sourceOffset, dest, destOffset);
265 } else {
266 return ByteToXLE.byteToLongLE(source, sourceOffset, dest, destOffset);
267 }
268 }
269
270 public static void byteToLong(byte[] source, int sourceOffset, int count, long[] dest, int destOffset, boolean bigEndian) {
271 if (bigEndian) {
272 ByteToXBE.byteToLongBE(source, sourceOffset, count, dest, destOffset);
273 } else {
274 ByteToXLE.byteToLongLE(source, sourceOffset, count, dest, destOffset);
275 }
276 }
277
278 public static long byteToLong(byte[] source, int sourceOffset, boolean bigEndian) {
279 if (bigEndian) {
280 return ByteToXBE.byteToLongBE(source, sourceOffset);
281 } else {
282 return ByteToXLE.byteToLongLE(source, sourceOffset);
283 }
284 }
285
286 /* **********************************************************************/
287
288 public static int longToByte(long[] source, int offset, byte[] dest, int destOffset, boolean bigEndian) {
289 if (bigEndian) {
290 return XtoByteBE.longToByteBE(source, offset, dest, destOffset);
291 } else {
292 return XtoByteLE.longToByteLE(source, offset, dest, destOffset);
293 }
294 }
295
296 public static void longToByte(long[] source, int offset, int count, byte[] dest, int destOffset, boolean bigEndian) {
297 if (bigEndian) {
298 XtoByteBE.longToByteBE(source, offset, count, dest, destOffset);
299 } else {
300 XtoByteLE.longToByteLE(source, offset, count, dest, destOffset);
301 }
302 }
303
304 public static int longToByte(long v, byte[] dest, int destOffset, boolean bigEndian) {
305 if (bigEndian) {
306 return XtoByteBE.longToByteBE(v, dest, destOffset);
307 } else {
308 return XtoByteLE.longToByteLE(v, dest, destOffset);
309 }
310 }
311
312 /* **********************************************************************/
313
314
315 public static int byteToShort(byte[] source, int sourceOffset, short[] dest, int destOffset, boolean bigEndian) {
316 if (bigEndian) {
317 return ByteToXBE.byteToShortBE(source, sourceOffset, dest, destOffset);
318 } else {
319 return ByteToXLE.byteToShortLE(source, sourceOffset, dest, destOffset);
320 }
321 }
322
323 public static void byteToShort(byte[] source, int sourceOffset, int count, short[] dest, int destOffset, boolean bigEndian) {
324 if (bigEndian) {
325 ByteToXBE.byteToShortBE(source, sourceOffset, count, dest, destOffset);
326 } else {
327 ByteToXLE.byteToShortLE(source, sourceOffset, count, dest, destOffset);
328 }
329 }
330
331 public static int byteToShort(byte[] source, int sourceOffset, boolean bigEndian) {
332 if (bigEndian) {
333 return ByteToXBE.byteToShortBE(source, sourceOffset);
334 } else {
335 return ByteToXLE.byteToShortLE(source, sourceOffset);
336 }
337 }
338
339 /* **********************************************************************/
340
341 public static int shortToByte(short[] source, int offset, byte[] dest, int destOffset, boolean bigEndian) {
342 if (bigEndian) {
343 return XtoByteBE.shortToByteBE(source, offset, dest, destOffset);
344 } else {
345 return XtoByteBE.shortToByteBE(source, offset, dest, destOffset);
346 }
347 }
348
349 public static void shortToByte(short[] source, int offset, int count, byte[] dest, int destOffset, boolean bigEndian) {
350 if (bigEndian) {
351 XtoByteBE.shortToByteBE(source, offset, count, dest, destOffset);
352 } else {
353 XtoByteLE.shortToByteLE(source, offset, count, dest, destOffset);
354 }
355 }
356
357 public static int shortToByte(short v, byte[] dest, int destOffset, boolean bigEndian) {
358 if (bigEndian) {
359 return XtoByteBE.shortToByteBE(v, dest, destOffset);
360 } else {
361 return XtoByteLE.shortToByteLE(v, dest, destOffset);
362 }
363 }
364
365 public static final byte[] readByteLine(RandomAccessInput in) throws IOException {
366 long start = in.getFilePointer();
367 long end = start;
368 boolean finished = false;
369 boolean eof = false;
370 int length = 0;
371 while (!finished) {
372 int k = in.read();
373 switch (k) {
374 case -1:
375 eof = true;
376 finished = true;
377 break;
378 case '\n':
379 finished = true;
380 end = in.getFilePointer();
381 length = (int) (end - start);
382 break;
383 case '\r':
384 finished = true;
385 end = in.getFilePointer();
386 length = (int) (end - start);
387 if ((in.read()) == '\n') {
388 end = in.getFilePointer();
389 }
390 break;
391 default:
392 k = 0;
393 break;
394 }
395 }
396 if (eof && length == 0) {
397 return null;
398 }
399 byte[] b = new byte[length];
400 in.seek(start);
401 in.readFully(b);
402 in.seek(end);
403 return b;
404 }
405
406 public static final int readByteLine(RandomAccessInput in, byte[] dest) throws IOException {
407 long start = in.getFilePointer();
408 long end = start;
409 boolean finished = false;
410 boolean eof = false;
411 int length = 0;
412 int cnt = 0;
413 while (!finished) {
414 if (cnt++ >= dest.length) {
415 finished = true;
416 break;
417 }
418 switch (in.read()) {
419 case -1:
420 eof = true;
421 finished = true;
422 break;
423 case '\n':
424 finished = true;
425 end = in.getFilePointer();
426 length = (int) (end - start);
427 break;
428 case '\r':
429 finished = true;
430 end = in.getFilePointer();
431 length = (int) (end - start);
432 if ((in.read()) == '\n') {
433 end = in.getFilePointer();
434 }
435 break;
436 }
437 }
438
439 if (eof && length == 0) {
440 return 0;
441 }
442 if (length == 0) {
443 end = in.getFilePointer();
444 length = Math.min(dest.length, (int) (end - start));
445 }
446 in.seek(start);
447 in.readFully(dest, 0, length);
448 in.seek(end);
449 return length;
450 }
451
452 /**
453 * Make right shift for all bytes of given array
454 * @param src byte array
455 * @param first value used to fill empty bits of first byte in array
456 * @param shift shift amount (from 1 to 7)
457 * @throws java.io.IOException
458 */
459 public static void shiftRight(byte[] src, int first, int shift) throws IOException {
460 ByteArrayOutputStreamExt out = new ByteArrayOutputStreamExt(src.length + 1);
461 BitOutputStream bos = new BitOutputStream(out);
462
463 bos.write(first, shift);
464 for (int i = 0; i < src.length; i++) {
465 bos.write(src[i] & 0xFF);
466 }
467 bos.close();
468
469 byte[] dst = out.drain();
470 System.arraycopy(dst, 0, src, 0, src.length);
471 }
472
473 /**
474 * Make left shift for all bytes in given array
475 * @param src byte array
476 * @param shift shift amount (from 1 to 7)
477 * @throws java.io.IOException
478 */
479 public static void shiftLeft(byte[] src, int shift) throws IOException {
480 ByteArrayInputStream in = new ByteArrayInputStream(src);
481 BitInputStream bis = new BitInputStream(in);
482 bis.read(shift);
483 bis.setBitsToRead(8);
484 int a = bis.read();
485 int p = 0;
486 while (a != -1 && p < src.length) {
487 int b = bis.read();
488 src[p++] = (byte) a;
489 if (b == -1) {
490 break;
491 }
492 a = b;
493 }
494 }
495 }