001package com.hfg.util; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.io.RandomAccessFile; 006import java.nio.*; 007 008import com.hfg.util.io.ByteSource; 009 010//------------------------------------------------------------------------------ 011/** 012 * General byte utility functions. 013 * 014 * @author J. Alex Taylor, hairyfatguy.com 015 */ 016//------------------------------------------------------------------------------ 017// com.hfg XML/HTML Coding Library 018// 019// This library is free software; you can redistribute it and/or 020// modify it under the terms of the GNU Lesser General Public 021// License as published by the Free Software Foundation; either 022// version 2.1 of the License, or (at your option) any later version. 023// 024// This library is distributed in the hope that it will be useful, 025// but WITHOUT ANY WARRANTY; without even the implied warranty of 026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 027// Lesser General Public License for more details. 028// 029// You should have received a copy of the GNU Lesser General Public 030// License along with this library; if not, write to the Free Software 031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 032// 033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 034// jataylor@hairyfatguy.com 035//------------------------------------------------------------------------------ 036 037public class ByteUtil 038{ 039 040 private static final int BIT1 = 1; 041 private static final int BIT2 = 2; 042 private static final int BIT3 = 4; 043 private static final int BIT4 = 8; 044 private static final int BIT5 = 16; 045 private static final int BIT6 = 32; 046 private static final int BIT7 = 64; 047 private static final int BIT8 = 128; 048 049 private static final byte[] bit = new byte[8]; 050 static 051 { 052 bit[0] = BIT1; 053 bit[1] = BIT2; 054 bit[2] = BIT3; 055 bit[3] = BIT4; 056 bit[4] = BIT5; 057 bit[5] = BIT6; 058 bit[6] = BIT7; 059 bit[7] = (byte)BIT8; 060 } 061 062 private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); 063 064 //************************************************************************** 065 // PUBLIC FUNCTIONS 066 //************************************************************************** 067 068 //-------------------------------------------------------------------------- 069 /** 070 Returns a string like "10110011" to represent the specified 8-bit byte. 071 @param inByte the byte to be represented as a bit string 072 @return the bit string representing the specified byte 073 */ 074 public static String getBitString(byte inByte) 075 { 076 StringBuilder buffer = new StringBuilder(); 077 buffer.append(((inByte & BIT8) > 0 ? "1" : "0")); 078 buffer.append(((inByte & BIT7) > 0 ? "1" : "0")); 079 buffer.append(((inByte & BIT6) > 0 ? "1" : "0")); 080 buffer.append(((inByte & BIT5) > 0 ? "1" : "0")); 081 buffer.append(((inByte & BIT4) > 0 ? "1" : "0")); 082 buffer.append(((inByte & BIT3) > 0 ? "1" : "0")); 083 buffer.append(((inByte & BIT2) > 0 ? "1" : "0")); 084 buffer.append(((inByte & BIT1) > 0 ? "1" : "0")); 085 086 return buffer.toString(); 087 } 088 089 //-------------------------------------------------------------------------- 090 /** 091 Returns the 8-bit byte corresponding to a specified string like "10110011". 092 @param inByteString the bit string to be converted to a byte 093 @return the byte represented by the specified bit string 094 */ 095 public static byte getByteFromBitString(String inByteString) 096 { 097 int outByte = 0; 098 for (int i = 0; i < 8; i++) 099 { 100 if (inByteString.charAt(i) == '1') outByte += bit[7 - i]; 101 } 102 103 return (byte) outByte; 104 } 105 106 //-------------------------------------------------------------------------- 107 /** 108 Decomposes a byte (8-bits) into two 4-bit bytes. 109 @param inByte the source byte to be converted 110 @return the byte array (length of 2) of 4-bit bytes 111 */ 112 public static byte[] get4bitBytes(byte inByte) 113 { 114 byte[] outBytes = new byte[2]; 115 116 outBytes[0] = (byte) ((inByte & 0xf0) >> 4); 117 outBytes[1] = (byte) (inByte & 0x0f); 118 119 return outBytes; 120 } 121 122 //-------------------------------------------------------------------------- 123 /** 124 Returns a hex string representing the given byte array. 125 @param inBytes the source byte array 126 @return the hexadecimal string represented by the the specified byte array. 127 */ 128 public static String getHexString(byte[] inBytes) 129 { 130 char[] chars = new char[2 * inBytes.length]; 131 for (int i = 0; i < inBytes.length; ++i) 132 { 133 chars[2 * i] = HEX_CHARS[(inBytes[i] & 0xF0) >>> 4]; 134 chars[2 * i + 1] = HEX_CHARS[inBytes[i] & 0x0F]; 135 } 136 137 return new String(chars); 138 } 139 140 //-------------------------------------------------------------------------- 141 /** 142 Returns an int from the given byte array. 143 @param inBytes the source byte array 144 @param inOffset the offset within the source byte array from which to extract the int 145 @param inByteOrder the byte order of the int 146 @return the integer represented by the the specified byte array. 147 */ 148 public static int getInt(byte[] inBytes, int inOffset, ByteOrder inByteOrder) 149 { 150 return ByteBuffer.wrap(inBytes, inOffset, 4).order(inByteOrder).getInt(); 151 } 152 153 //-------------------------------------------------------------------------- 154 /** 155 Returns an int from the given byte array. 156 @param inStream the InputStream source of bytes 157 @param inByteOrder the byte order of the int 158 @return the integer represented by the next 4 bytes from the specified InputStream 159 */ 160 public static int getInt(InputStream inStream, ByteOrder inByteOrder) 161 throws IOException 162 { 163 byte[] bytes = new byte[4]; 164 inStream.read(bytes); 165 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes, 0, 4); 166 167 return byteBuffer.order(inByteOrder).getInt(); 168 } 169 170 //-------------------------------------------------------------------------- 171 /** 172 Returns an int from the current position of the specified RandomAccessFile. 173 @param inRandomAccessFile the source of bytes 174 @return the integer represented in the next 4 bytes of the specified RandomAccessFile 175 */ 176 public static int getInt(RandomAccessFile inRandomAccessFile) 177 throws IOException 178 { 179 byte[] bytes = new byte[4]; 180 inRandomAccessFile.read(bytes); 181 182 return ByteBuffer.wrap(bytes, 0, 4).getInt(); 183 } 184 185 //-------------------------------------------------------------------------- 186 /** 187 Returns an int from the current position of the specified RandomAccessFile. 188 @param inRandomAccessFile the source of bytes 189 @param inByteOrder the byte order of the int 190 @return the integer represented in the next 4 bytes of the specified RandomAccessFile 191 */ 192 public static int getInt(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder) 193 throws IOException 194 { 195 byte[] bytes = new byte[4]; 196 inRandomAccessFile.read(bytes); 197 198 return ByteBuffer.wrap(bytes, 0, 4).order(inByteOrder).getInt(); 199 } 200 201 //-------------------------------------------------------------------------- 202 /** 203 Returns an int from the current position of the specified ByteSource. 204 @param inByteSource the source of bytes 205 @param inByteOrder the byte order of the int 206 @return the integer represented in the next 4 bytes of the specified ByteSource 207 */ 208 public static int getInt(ByteSource inByteSource, ByteOrder inByteOrder) 209 throws IOException 210 { 211 byte[] bytes = new byte[4]; 212 inByteSource.read(bytes); 213 214 return ByteBuffer.wrap(bytes, 0, 4).order(inByteOrder).getInt(); 215 } 216 217 //-------------------------------------------------------------------------- 218 /** 219 Returns an long from the current position of the specified RandomAccessFile. 220 @param inRandomAccessFile the source of bytes 221 @param inByteOrder the byte order of the long 222 @return the long represented in the next 8 bytes of the specified RandomAccessFile 223 */ 224 public static long getLong(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder) 225 throws IOException 226 { 227 byte[] bytes = new byte[8]; 228 inRandomAccessFile.read(bytes); 229 230 return ByteBuffer.wrap(bytes, 0, 8).order(inByteOrder).getLong(); 231 } 232 233 //-------------------------------------------------------------------------- 234 /** 235 Returns an long from the current position of the specified ByteSource. 236 @param inByteSource the source of bytes 237 @param inByteOrder the byte order of the long 238 @return the long represented in the next 8 bytes of the specified ByteSource 239 */ 240 public static long getLong(ByteSource inByteSource, ByteOrder inByteOrder) 241 throws IOException 242 { 243 byte[] bytes = new byte[8]; 244 inByteSource.read(bytes); 245 246 return ByteBuffer.wrap(bytes, 0, 8).order(inByteOrder).getLong(); 247 } 248 249 //-------------------------------------------------------------------------- 250 /** 251 Returns a 2-byte int from the given byte array. 252 @param inBytes the source byte array 253 @return the 2-byte integer represented in the first two bytes of the specified byte array 254 */ 255 public static int get2ByteInt(byte[] inBytes) 256 { 257 return get2ByteInt(inBytes, 0); 258 } 259 260 //-------------------------------------------------------------------------- 261 /** 262 Returns a 2-byte int from the given byte[]. 263 @param inBytes the source byte array 264 @param inByteOrder the byte order of the int 265 @return the 2-byte integer represented in the first two bytes of the specified byte array 266 */ 267 public static int get2ByteInt(byte[] inBytes, ByteOrder inByteOrder) 268 throws IOException 269 { 270 return get2ByteInt(inBytes, 0, inByteOrder); 271 } 272 273 //-------------------------------------------------------------------------- 274 /** 275 Returns a 2-byte int from the given byte[]. 276 @param inBytes the source byte array 277 @param inOffset the offset within the source byte array from which to extract the int 278 @param inByteOrder the byte order of the int 279 @return the 2-byte integer represented in the first two bytes of the specified byte array 280 */ 281 public static int get2ByteInt(byte[] inBytes, int inOffset, ByteOrder inByteOrder) 282 throws IOException 283 { 284 return (int) ByteBuffer.wrap(inBytes, inOffset, 2).order(inByteOrder).getShort(); 285 } 286 287 //-------------------------------------------------------------------------- 288 /** 289 Returns a 2-byte int from the given InputStream. 290 @param inStream the InputStream source of bytes 291 @return the 2-byte integer represented in the next two bytes of the specified stream 292 */ 293 public static int get2ByteInt(InputStream inStream) 294 throws IOException 295 { 296 byte[] bytes = new byte[2]; 297 inStream.read(bytes); 298 return get2ByteInt(bytes, 0); 299 } 300 301 //-------------------------------------------------------------------------- 302 /** 303 Returns a 2-byte int from the given InputStream. 304 @param inStream the InputStream source of bytes 305 @param inByteOrder the byte order of the int 306 @return the 2-byte integer represented in the next two bytes of the specified stream 307 */ 308 public static int get2ByteInt(InputStream inStream, ByteOrder inByteOrder) 309 throws IOException 310 { 311 byte[] bytes = new byte[2]; 312 inStream.read(bytes); 313 314 return (int) ByteBuffer.wrap(bytes, 0, 2).order(inByteOrder).getShort(); 315 } 316 317 //-------------------------------------------------------------------------- 318 /** 319 Returns a 2-byte int from the current position of the specified RandomAccessFile. 320 @param inRandomAccessFile the source of bytes 321 @param inByteOrder the byte order of the int 322 @return the 2-byte integer represented in the next two bytes of the specified stream 323 */ 324 public static int get2ByteInt(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder) 325 throws IOException 326 { 327 return get2ByteInt(new ByteSource(inRandomAccessFile), inByteOrder); 328 } 329 330 //-------------------------------------------------------------------------- 331 /** 332 Returns a 2-byte int from the current position of the specified ByteSource. 333 @param inByteSource the source of bytes 334 @param inByteOrder the byte order of the int 335 @return the 2-byte integer represented in the next two bytes of the specified ByteSource 336 */ 337 public static int get2ByteInt(ByteSource inByteSource, ByteOrder inByteOrder) 338 throws IOException 339 { 340 byte[] bytes = new byte[2]; 341 inByteSource.read(bytes); 342 343 return (int) ByteBuffer.wrap(bytes, 0, 2).order(inByteOrder).getShort(); 344 } 345 346 347 //-------------------------------------------------------------------------- 348 /** 349 Returns a 2-byte int from the given byte array. 350 @param inBytes the source byte array 351 @param inOffset the offset within the source byte array from which to extract the int 352 @return the 2-byte integer represented in the first two bytes at the specified offset of the specified byte array 353 */ 354 public static int get2ByteInt(byte[] inBytes, int inOffset) 355 { 356 return (int) ByteBuffer.wrap(inBytes, inOffset, inOffset + 2).getShort(); 357 } 358 359 //-------------------------------------------------------------------------- 360 /** 361 Returns a 1-byte int from the given byte array. 362 @param inBytes the source byte array 363 @param inOffset the offset within the source byte array from which to extract the int 364 @return the 1-byte integer represented in the first byte of the specified byte array 365 */ 366 public static int get1ByteInt(byte[] inBytes, int inOffset) 367 { 368 return inBytes[inOffset] & 0xff; 369 } 370 371 //-------------------------------------------------------------------------- 372 /** 373 Returns a short from the first 2 bytes of the given byte array. 374 @param inBytes the source byte array 375 @return the sort represented in the first two bytes of the specified byte array 376 */ 377 public static short getShort(byte[] inBytes) 378 { 379 return getShort(inBytes, 0); 380 } 381 382 //-------------------------------------------------------------------------- 383 /** 384 Returns a short from the first 2 bytes of the given byte array. 385 @param inBytes the source byte array 386 @param inOffset the offset within the source byte array from which to extract the int 387 @return the short represented in the first two bytes at the specified offset of the specified byte array 388 */ 389 public static short getShort(byte[] inBytes, int inOffset) 390 { 391 return (short) (inBytes[inOffset]<<8 | inBytes[inOffset + 1] & 0xFF); 392 } 393 394 //-------------------------------------------------------------------------- 395 /** 396 Returns a short from the first 2 bytes of the given byte array. 397 @param inBytes the source byte array 398 @param inOffset the offset within the source byte array from which to extract the int 399 @param inByteOrder the byte order of the short 400 @return the short represented in the first two bytes at the specified offset of the specified byte array 401 */ 402 public static short getShort(byte[] inBytes, int inOffset, ByteOrder inByteOrder) 403 { 404 return ByteBuffer.wrap(inBytes, inOffset, 2).order(inByteOrder).getShort(); 405 } 406 407 //-------------------------------------------------------------------------- 408 /** 409 Returns a float from the given byte array. 410 @param inStream the InputStream source of bytes 411 @param inByteOrder the byte order of the float 412 @return the float represented by the next 4 bytes from the specified InputStream 413 */ 414 public static float getFloat(InputStream inStream, ByteOrder inByteOrder) 415 throws IOException 416 { 417 byte[] bytes = new byte[4]; 418 inStream.read(bytes); 419 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes, 0, 4); 420 421 return byteBuffer.order(inByteOrder).getFloat(); 422 } 423 424 //-------------------------------------------------------------------------- 425 /** 426 Returns a string from the bytes. 427 @param inBytes the source byte array 428 @param inOffset the offset within the source byte array from which to extract the String 429 @param inLength the number of bytes to include in the String 430 @param inByteOrder the byte order of the string 431 @return the String represented at the specified offset of the specified byte array 432 */ 433 public static String getString(byte[] inBytes, int inOffset, int inLength, ByteOrder inByteOrder) 434 { 435 String result = ByteBuffer.wrap(inBytes, inOffset, inLength).order(inByteOrder).asCharBuffer().toString(); 436 int index = result.indexOf(0x00); 437 if (index >= 0) 438 { 439 result = result.substring(0, index); 440 } 441 442 return result; 443 } 444 445 //-------------------------------------------------------------------------- 446 /** 447 Returns a string from the bytes. 448 @param inStream the InputStream source of bytes 449 @param inLength the number of bytes to include in the String 450 @return the String represented at the specified offset of the specified byte array 451 */ 452 public static String getString(InputStream inStream, int inLength) 453 throws IOException 454 { 455 byte[] bytes = new byte[inLength]; 456 inStream.read(bytes); 457 String result = new String(bytes); 458 int index = result.indexOf(0x00); 459 if (index >= 0) 460 { 461 result = result.substring(0, index); 462 } 463 464 return result; 465 } 466 467 //-------------------------------------------------------------------------- 468 /** 469 Returns a String from the current position of the specified RandomAccessFile. 470 @param inRandomAccessFile the source of bytes 471 @param inLength the number of bytes to include in the String 472 @return the String represented at the specified offset of the specified RandomAccessFile 473 */ 474 public static String getString(RandomAccessFile inRandomAccessFile, int inLength) 475 throws IOException 476 { 477 byte[] bytes = new byte[inLength]; 478 inRandomAccessFile.read(bytes); 479 480 String result = new String(bytes); 481 int index = result.indexOf(0x00); 482 if (index >= 0) 483 { 484 result = result.substring(0, index); 485 } 486 487 return result; 488 } 489 490 //-------------------------------------------------------------------------- 491 /** 492 Returns a String from the current position of the specified ByteSource. 493 @param inByteSource the source of bytes 494 @param inLength the number of bytes to include in the String 495 @return the String represented at the specified offset of the specified ByteSource 496 */ 497 public static String getString(ByteSource inByteSource, int inLength) 498 throws IOException 499 { 500 byte[] bytes = new byte[inLength]; 501 inByteSource.read(bytes); 502 503 String result = new String(bytes); 504 int index = result.indexOf(0x00); 505 if (index >= 0) 506 { 507 result = result.substring(0, index); 508 } 509 510 return result; 511 } 512 513 //-------------------------------------------------------------------------- 514 /** 515 Returns a byte[] corresponding to an int. 516 @param inValue the int to decompose into an array of 4 bytes 517 @return the byte[] represented by the specified int 518 */ 519 public static byte[] getBytesFromInt(int inValue) 520 throws IOException 521 { 522 return ByteBuffer.allocate(4).putInt(inValue).array(); 523 } 524 525 //-------------------------------------------------------------------------- 526 /** 527 Returns a short[] derived from the specified byte[]. 528 @param inBytes the source byte array 529 @param inNumValues the number of shorts to extract from the source byte array 530 @param inByteOrder the byte order of the string 531 @return a short[] derived from the specified byte[] 532 */ 533 public static short[] getShortArray(byte[] inBytes, int inNumValues, ByteOrder inByteOrder) 534 { 535 short[] array = new short[inNumValues]; 536 for (int i = 0; i < inNumValues; i++) 537 { 538 array[i] = getShort(inBytes, i * 2, inByteOrder); 539 } 540 541 return array; 542 } 543 544 //-------------------------------------------------------------------------- 545 /** 546 Returns a short[] derived from the specified RandomAccessFile. 547 @param inRandomAccessFile the source of bytes; assumes that the file is already set to the proper position 548 @param inNumValues the number of shorts to extract from the source byte array 549 @param inByteOrder the byte order of the string 550 @return a short[] derived from the specified RandomAccessFile 551 */ 552 public static short[] getShortArray(RandomAccessFile inRandomAccessFile, int inNumValues, ByteOrder inByteOrder) 553 throws IOException 554 { 555 return getShortArray(new ByteSource(inRandomAccessFile), inNumValues, inByteOrder); 556 } 557 558 //-------------------------------------------------------------------------- 559 /** 560 Returns a short[] derived from the specified ByteSource. 561 @param inByteSource the source of bytes; assumes that the file is already set to the proper position 562 @param inNumValues the number of shorts to extract from the source byte array 563 @param inByteOrder the byte order of the string 564 @return a short[] derived from the specified ByteSource 565 */ 566 public static short[] getShortArray(ByteSource inByteSource, int inNumValues, ByteOrder inByteOrder) 567 throws IOException 568 { 569 byte[] bytes = new byte[2 * inNumValues]; 570 inByteSource.read(bytes); 571 572 return getShortArray(bytes, inNumValues, inByteOrder); 573 } 574 575 //-------------------------------------------------------------------------- 576 /** 577 Returns a char[] derived from the specified RandomAccessFile. 578 @param inRandomAccessFile the source of bytes; assumes that the file is already set to the proper position 579 @param inNumValues the number of shorts to extract from the source byte array 580 @return a char[] derived from the specified RandomAccessFile 581 */ 582 public static char[] getCharArray(RandomAccessFile inRandomAccessFile, int inNumValues) 583 throws IOException 584 { 585 return getCharArray(new ByteSource(inRandomAccessFile), inNumValues); 586 } 587 588 //-------------------------------------------------------------------------- 589 /** 590 Returns a char[] derived from the specified ByteSource. 591 @param inByteSource the source of bytes; assumes that the file is already set to the proper position 592 @param inNumValues the number of shorts to extract from the source byte array 593 @return a char[] derived from the specified ByteSource 594 */ 595 public static char[] getCharArray(ByteSource inByteSource, int inNumValues) 596 throws IOException 597 { 598 byte[] bytes = new byte[inNumValues]; 599 inByteSource.read(bytes); 600 601 char[] chars = new char[inNumValues]; 602 for (int i = 0; i < bytes.length; i++) 603 { 604 chars[i] = (char) bytes[i]; 605 } 606 607 return chars; 608 } 609}