diff --git a/src/com/bytezone/diskbrowser/applefile/SHRPictureFile2.java b/src/com/bytezone/diskbrowser/applefile/SHRPictureFile2.java index 9adeaba..9f95c5b 100644 --- a/src/com/bytezone/diskbrowser/applefile/SHRPictureFile2.java +++ b/src/com/bytezone/diskbrowser/applefile/SHRPictureFile2.java @@ -171,7 +171,7 @@ public class SHRPictureFile2 extends HiResImage failureReason = "Buffer should be 38,400 bytes"; return; } - int maxTables = (buffer.length - 3200) / COLOR_TABLE_SIZE; + int maxTables = (buffer.length - 32000) / COLOR_TABLE_SIZE; colorTables = new ColorTable[maxTables]; for (int i = 0; i < colorTables.length; i++) { diff --git a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java index 75a2739..fedc933 100755 --- a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java +++ b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java @@ -1,542 +1,542 @@ -package com.bytezone.diskbrowser.utilities; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.GregorianCalendar; - -// -----------------------------------------------------------------------------------// -public class HexFormatter -// -----------------------------------------------------------------------------------// -{ - private static String[] hex = - { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; - private static MathContext mathContext = new MathContext (9); - - // ---------------------------------------------------------------------------------// - public static String format (byte[] buffer) - // ---------------------------------------------------------------------------------// - { - return format (buffer, 0, buffer.length); - } - - // ---------------------------------------------------------------------------------// - public static String formatNoHeader (byte[] buffer) - // ---------------------------------------------------------------------------------// - { - return formatNoHeader (buffer, 0, buffer.length); - } - - // ---------------------------------------------------------------------------------// - public static String format (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - return format (buffer, offset, length, true, 0); - } - - // ---------------------------------------------------------------------------------// - public static String format (byte[] buffer, int offset, int length, int startingAddress) - // ---------------------------------------------------------------------------------// - { - return format (buffer, offset, length, true, startingAddress); - } - - // ---------------------------------------------------------------------------------// - public static String formatNoHeader (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - return format (buffer, offset, length, false, 0); - } - - // ---------------------------------------------------------------------------------// - public static String formatNoHeader (byte[] buffer, int offset, int length, - int startingAddress) - // ---------------------------------------------------------------------------------// - { - return format (buffer, offset, length, false, startingAddress); - } - - // ---------------------------------------------------------------------------------// - public static String format (byte[] buffer, int offset, int length, boolean header, - int startingAddress) - // ---------------------------------------------------------------------------------// - { - StringBuilder line = new StringBuilder (); - int[] freq = new int[256]; - boolean startedOnBoundary = offset % 0x100 == 0; - - if (header) - { - line.append (" "); - for (int i = 0; i < 16; i++) - line.append (" " + hex[i]); - if (offset == 0) - line.append ("\n"); - } - - for (int i = offset; i < offset + length; i += 16) - { - if (line.length () > 0 && i > 0) - line.append ("\n"); - if (i > offset && startedOnBoundary && (i % 0x200) == 0) - line.append ("\n"); - - // print offset - line.append (String.format ("%05X : ", (startingAddress + i - offset))); - - // print hex values - StringBuffer trans = new StringBuffer (); - StringBuffer hexLine = new StringBuffer (); - - int max = Math.min (i + 16, offset + length); - max = Math.min (max, buffer.length); - for (int j = i; j < max; j++) - { - int c = buffer[j] & 0xFF; - freq[c]++; - hexLine.append (String.format ("%02X ", c)); - - if (c > 127) - { - if (c < 160) - c -= 64; - else - c -= 128; - } - if (c < 32 || c == 127) // non-printable - trans.append ("."); - else // standard ascii - trans.append ((char) c); - } - while (hexLine.length () < 48) - hexLine.append (" "); - - line.append (hexLine.toString () + ": " + trans.toString ()); - } - - if (false) - { - line.append ("\n\n"); - int totalBits = 0; - for (int i = 0; i < freq.length; i++) - if (freq[i] > 0) - { - totalBits += (Integer.bitCount (i) * freq[i]); - line.append ( - String.format ("%02X %3d %d%n", i, freq[i], Integer.bitCount (i))); - } - line.append (String.format ("%nTotal bits : %d%n", totalBits)); - } - return line.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String sanitiseString (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - StringBuilder trans = new StringBuilder (); - for (int j = offset; j < offset + length; j++) - { - int c = buffer[j] & 0xFF; - - if (c > 127) - { - if (c < 160) - c -= 64; - else - c -= 128; - } - - if (c < 32 || c == 127) // non-printable - trans.append ("."); - else - trans.append ((char) c); // standard ascii - } - return trans.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String getString (byte[] buffer) - // ---------------------------------------------------------------------------------// - { - return getString (buffer, 0, buffer.length); - } - - // ---------------------------------------------------------------------------------// - public static String getString (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - StringBuilder text = new StringBuilder (); - - for (int i = offset; i < offset + length; i++) - { - int c = buffer[i] & 0xFF; - if (c > 127) - { - if (c < 160) - c -= 64; - else - c -= 128; - } - if (c == 13) - text.append ("\n"); - else if (c < 32) // non-printable - text.append ("."); - else // standard ascii - text.append ((char) c); - } - return text.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String getString2 (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - StringBuilder text = new StringBuilder (); - - for (int i = offset; i < offset + length; i++) - { - int c = buffer[i] & 0xFF; - if (c == 136) - { - if (text.length () > 0) - text.deleteCharAt (text.length () - 1); - continue; - } - if (c > 127) - { - if (c < 160) - c -= 64; - else - c -= 128; - } - if (c < 32) // non-printable - text.append ((char) (c + 64)); - else // standard ascii - text.append ((char) c); - } - return text.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String getHexString (byte[] buffer, int offset, int length) - // ---------------------------------------------------------------------------------// - { - return getHexString (buffer, offset, length, true); - } - - // ---------------------------------------------------------------------------------// - public static String getHexString (byte[] buffer) - // ---------------------------------------------------------------------------------// - { - return getHexString (buffer, 0, buffer.length); - } - - // ---------------------------------------------------------------------------------// - public static String getHexString (byte[] buffer, int offset, int length, boolean space) - // ---------------------------------------------------------------------------------// - { - StringBuilder hex = new StringBuilder (); - int max = Math.min (offset + length, buffer.length); - for (int i = offset; i < max; i++) - { - hex.append (String.format ("%02X", buffer[i])); - if (space) - hex.append (' '); - } - if (length > 0 && space) - hex.deleteCharAt (hex.length () - 1); - return hex.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String getHexStringReversed (byte[] buffer, int offset, int length, - boolean space) - // ---------------------------------------------------------------------------------// - { - StringBuilder hex = new StringBuilder (); - for (int i = length - 1; i >= 0; i--) - { - hex.append (String.format ("%02X", buffer[offset + i])); - if (space) - hex.append (' '); - } - if (length > 0 && space) - hex.deleteCharAt (hex.length () - 1); - return hex.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String getBitString (byte b) - // ---------------------------------------------------------------------------------// - { - String s = "0000000" + Integer.toBinaryString (b & 0xFF); - s = s.replaceAll ("0", "."); - return s.substring (s.length () - 8); - } - - // ---------------------------------------------------------------------------------// - public static char byteValue (byte b) - // ---------------------------------------------------------------------------------// - { - int c = b & 0xFF; - if (c > 127) - c -= 128; - if (c > 95) - c -= 64; - if (c < 32) // non-printable - return '.'; - return (char) c; // standard ascii - - } - - // ---------------------------------------------------------------------------------// - public static String format4 (int value) - // ---------------------------------------------------------------------------------// - { - if (value < 0) - return "***err**"; - StringBuffer text = new StringBuffer (); - for (int i = 0, weight = 4096; i < 4; i++) - { - int digit = value / weight; - if (digit < 0 || digit > 15) - return "***err**"; - text.append (hex[digit]); - value %= weight; - weight /= 16; - } - return text.toString (); - } - - // ---------------------------------------------------------------------------------// - public static String format3 (int value) - // ---------------------------------------------------------------------------------// - { - return format4 (value).substring (1); - } - - // ---------------------------------------------------------------------------------// - public static String format2 (int value) - // ---------------------------------------------------------------------------------// - { - if (value < 0) - value += 256; - String text = hex[value / 16] + hex[value % 16]; - return text; - } - - // ---------------------------------------------------------------------------------// - public static String format1 (int value) - // ---------------------------------------------------------------------------------// - { - String text = hex[value]; - return text; - } - - // ---------------------------------------------------------------------------------// - public static int intValue (byte b1, byte b2) - // ---------------------------------------------------------------------------------// - { - return (b1 & 0xFF) + (b2 & 0xFF) * 256; - } - - // ---------------------------------------------------------------------------------// - public static int intValue (byte b1, byte b2, byte b3) - // ---------------------------------------------------------------------------------// - { - return (b1 & 0xFF) + (b2 & 0xFF) * 256 + (b3 & 0xFF) * 65536; - } - - // ---------------------------------------------------------------------------------// - public static int unsignedLong (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - int val = 0; - for (int i = 3; i >= 0; i--) - { - val <<= 8; - val += buffer[ptr + i] & 0xFF; - } - return val; - } - - // ---------------------------------------------------------------------------------// - public static int signedLong (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - return (((buffer[ptr] & 0xFF) << 24) | ((buffer[ptr] & 0xFF) << 16) - | ((buffer[ptr] & 0xFF) << 8) | (buffer[ptr + 1] & 0xFF)); - } - - // ---------------------------------------------------------------------------------// - public static int getLongBigEndian (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - int val = 0; - for (int i = 0; i < 4; i++) - { - val <<= 8; - val += buffer[ptr + i] & 0xFF; - } - return val; - } - - // ---------------------------------------------------------------------------------// - public static int unsignedShort (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - if (ptr >= buffer.length) - { - System.out.println ("index out of range: " + ptr); - return 0; - } - return (buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8); - } - - // ---------------------------------------------------------------------------------// - public static int signedShort (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - if (ptr >= buffer.length) - { - System.out.println ("index out of range: " + ptr); - return 0; - } - return (short) ((buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8)); - } - - // ---------------------------------------------------------------------------------// - public static int getShortBigEndian (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - int val = 0; - for (int i = 0; i < 2; i++) - { - val <<= 8; - val |= buffer[ptr + i] & 0xFF; - } - return val; - } - - // ---------------------------------------------------------------------------------// - public static double getSANEDouble (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - long bits = 0; - for (int i = 7; i >= 0; i--) - { - bits <<= 8; - bits |= buffer[offset + i] & 0xFF; - } - - return Double.longBitsToDouble (bits); - } - - // ---------------------------------------------------------------------------------// - public static double floatValueOld (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - double val = 0; - - int exponent = (buffer[offset] & 0xFF) - 0x80; - - int mantissa = - (buffer[offset + 1] & 0x7F) * 0x1000000 + (buffer[offset + 2] & 0xFF) * 0x10000 - + (buffer[offset + 3] & 0xFF) * 0x100 + (buffer[offset + 4] & 0xFF); - - int weight1 = 1; - long weight2 = 2147483648L; - double multiplier = 0; - - for (int i = 0; i < 32; i++) - { - if ((mantissa & weight2) > 0) - multiplier += (1.0 / weight1); - weight2 /= 2; - weight1 *= 2; - } - val = Math.pow (2, exponent - 1) * (multiplier + 1); - - return val; - } - - // ---------------------------------------------------------------------------------// - public static double floatValue (byte[] buffer, int ptr) - // ---------------------------------------------------------------------------------// - { - int exponent = buffer[ptr] & 0x7F; // biased 128 - if (exponent == 0) - return 0.0; - - int mantissa = (buffer[ptr + 1] & 0x7F) << 24 | (buffer[ptr + 2] & 0xFF) << 16 - | (buffer[ptr + 3] & 0xFF) << 8 | (buffer[ptr + 4] & 0xFF); - boolean negative = (buffer[ptr + 1] & 0x80) > 0; - double value = 0.5; - for (int i = 2, weight = 0x40000000; i <= 32; i++, weight >>>= 1) - if ((mantissa & weight) > 0) - value += Math.pow (0.5, i); - value *= Math.pow (2, exponent); - BigDecimal bd = new BigDecimal (value); - double rounded = bd.round (mathContext).doubleValue (); - return negative ? rounded * -1 : rounded; - } - - // ---------------------------------------------------------------------------------// - public static GregorianCalendar getAppleDate (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - int date = HexFormatter.intValue (buffer[offset], buffer[offset + 1]); - if (date > 0) - { - int year = (date & 0xFE00) >> 9; - int month = (date & 0x01E0) >> 5; - int day = date & 0x001F; - int hour = buffer[offset + 3] & 0x1F; - int minute = buffer[offset + 2] & 0x3F; - if (year < 70) - year += 2000; - else - year += 1900; - return new GregorianCalendar (year, month - 1, day, hour, minute); - } - return null; - } - - // ---------------------------------------------------------------------------------// - public static GregorianCalendar getPascalDate (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - int year = (buffer[offset + 1] & 0xFF); - int day = (buffer[offset] & 0xF0) >> 4; - int month = buffer[offset] & 0x0F; - if (day == 0 || month == 0) - return null; - if (year % 2 > 0) - day += 16; - year /= 2; - if (year < 70) - year += 2000; - else - year += 1900; - return new GregorianCalendar (year, month - 1, day); - } - - // ---------------------------------------------------------------------------------// - public static String getPascalString (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - int length = buffer[offset] & 0xFF; - return HexFormatter.getString (buffer, offset + 1, length); - } - - // ---------------------------------------------------------------------------------// - public static String getCString (byte[] buffer, int offset) - // ---------------------------------------------------------------------------------// - { - int end = offset; - while (buffer[end] != 0) - end++; - - return HexFormatter.getString (buffer, offset, end - offset); - } -} +package com.bytezone.diskbrowser.utilities; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.GregorianCalendar; + +// -----------------------------------------------------------------------------------// +public class HexFormatter +// -----------------------------------------------------------------------------------// +{ + private static String[] hex = + { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; + private static MathContext mathContext = new MathContext (9); + + // ---------------------------------------------------------------------------------// + public static String format (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + return format (buffer, 0, buffer.length); + } + + // ---------------------------------------------------------------------------------// + public static String formatNoHeader (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + return formatNoHeader (buffer, 0, buffer.length); + } + + // ---------------------------------------------------------------------------------// + public static String format (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + return format (buffer, offset, length, true, 0); + } + + // ---------------------------------------------------------------------------------// + public static String format (byte[] buffer, int offset, int length, int startingAddress) + // ---------------------------------------------------------------------------------// + { + return format (buffer, offset, length, true, startingAddress); + } + + // ---------------------------------------------------------------------------------// + public static String formatNoHeader (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + return format (buffer, offset, length, false, 0); + } + + // ---------------------------------------------------------------------------------// + public static String formatNoHeader (byte[] buffer, int offset, int length, + int startingAddress) + // ---------------------------------------------------------------------------------// + { + return format (buffer, offset, length, false, startingAddress); + } + + // ---------------------------------------------------------------------------------// + public static String format (byte[] buffer, int offset, int length, boolean header, + int startingAddress) + // ---------------------------------------------------------------------------------// + { + StringBuilder line = new StringBuilder (); + int[] freq = new int[256]; + boolean startedOnBoundary = offset % 0x100 == 0; + + if (header) + { + line.append (" "); + for (int i = 0; i < 16; i++) + line.append (" " + hex[i]); + if (offset == 0) + line.append ("\n"); + } + + for (int i = offset; i < offset + length; i += 16) + { + if (line.length () > 0 && i > 0) + line.append ("\n"); + if (i > offset && startedOnBoundary && (i % 0x200) == 0) + line.append ("\n"); + + // print offset + line.append (String.format ("%05X : ", (startingAddress + i - offset))); + + // print hex values + StringBuffer trans = new StringBuffer (); + StringBuffer hexLine = new StringBuffer (); + + int max = Math.min (i + 16, offset + length); + max = Math.min (max, buffer.length); + for (int j = i; j < max; j++) + { + int c = buffer[j] & 0xFF; + freq[c]++; + hexLine.append (String.format ("%02X ", c)); + + if (c > 127) + { + if (c < 160) + c -= 64; + else + c -= 128; + } + if (c < 32 || c == 127) // non-printable + trans.append ("."); + else // standard ascii + trans.append ((char) c); + } + while (hexLine.length () < 48) + hexLine.append (" "); + + line.append (hexLine.toString () + ": " + trans.toString ()); + } + + if (false) + { + line.append ("\n\n"); + int totalBits = 0; + for (int i = 0; i < freq.length; i++) + if (freq[i] > 0) + { + totalBits += (Integer.bitCount (i) * freq[i]); + line.append ( + String.format ("%02X %3d %d%n", i, freq[i], Integer.bitCount (i))); + } + line.append (String.format ("%nTotal bits : %d%n", totalBits)); + } + return line.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String sanitiseString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + StringBuilder trans = new StringBuilder (); + for (int j = offset; j < offset + length; j++) + { + int c = buffer[j] & 0xFF; + + if (c > 127) + { + if (c < 160) + c -= 64; + else + c -= 128; + } + + if (c < 32 || c == 127) // non-printable + trans.append ("."); + else + trans.append ((char) c); // standard ascii + } + return trans.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String getString (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + return getString (buffer, 0, buffer.length); + } + + // ---------------------------------------------------------------------------------// + public static String getString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + StringBuilder text = new StringBuilder (); + + for (int i = offset; i < offset + length; i++) + { + int c = buffer[i] & 0xFF; + if (c > 127) + { + if (c < 160) + c -= 64; + else + c -= 128; + } + if (c == 13) + text.append ("\n"); + else if (c < 32) // non-printable + text.append ("."); + else // standard ascii + text.append ((char) c); + } + return text.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String getString2 (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + StringBuilder text = new StringBuilder (); + + for (int i = offset; i < offset + length; i++) + { + int c = buffer[i] & 0xFF; + if (c == 136) + { + if (text.length () > 0) + text.deleteCharAt (text.length () - 1); + continue; + } + if (c > 127) + { + if (c < 160) + c -= 64; + else + c -= 128; + } + if (c < 32) // non-printable + text.append ((char) (c + 64)); + else // standard ascii + text.append ((char) c); + } + return text.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String getHexString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// + { + return getHexString (buffer, offset, length, true); + } + + // ---------------------------------------------------------------------------------// + public static String getHexString (byte[] buffer) + // ---------------------------------------------------------------------------------// + { + return getHexString (buffer, 0, buffer.length); + } + + // ---------------------------------------------------------------------------------// + public static String getHexString (byte[] buffer, int offset, int length, boolean space) + // ---------------------------------------------------------------------------------// + { + StringBuilder hex = new StringBuilder (); + int max = Math.min (offset + length, buffer.length); + for (int i = offset; i < max; i++) + { + hex.append (String.format ("%02X", buffer[i])); + if (space) + hex.append (' '); + } + if (length > 0 && space) + hex.deleteCharAt (hex.length () - 1); + return hex.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String getHexStringReversed (byte[] buffer, int offset, int length, + boolean space) + // ---------------------------------------------------------------------------------// + { + StringBuilder hex = new StringBuilder (); + for (int i = length - 1; i >= 0; i--) + { + hex.append (String.format ("%02X", buffer[offset + i])); + if (space) + hex.append (' '); + } + if (length > 0 && space) + hex.deleteCharAt (hex.length () - 1); + return hex.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String getBitString (byte b) + // ---------------------------------------------------------------------------------// + { + String s = "0000000" + Integer.toBinaryString (b & 0xFF); + s = s.replaceAll ("0", "."); + return s.substring (s.length () - 8); + } + + // ---------------------------------------------------------------------------------// + public static char byteValue (byte b) + // ---------------------------------------------------------------------------------// + { + int c = b & 0xFF; + if (c > 127) + c -= 128; + if (c > 95) + c -= 64; + if (c < 32) // non-printable + return '.'; + return (char) c; // standard ascii + + } + + // ---------------------------------------------------------------------------------// + public static String format4 (int value) + // ---------------------------------------------------------------------------------// + { + if (value < 0) + return "***err**"; + StringBuffer text = new StringBuffer (); + for (int i = 0, weight = 4096; i < 4; i++) + { + int digit = value / weight; + if (digit < 0 || digit > 15) + return "***err**"; + text.append (hex[digit]); + value %= weight; + weight /= 16; + } + return text.toString (); + } + + // ---------------------------------------------------------------------------------// + public static String format3 (int value) + // ---------------------------------------------------------------------------------// + { + return format4 (value).substring (1); + } + + // ---------------------------------------------------------------------------------// + public static String format2 (int value) + // ---------------------------------------------------------------------------------// + { + if (value < 0) + value += 256; + String text = hex[value / 16] + hex[value % 16]; + return text; + } + + // ---------------------------------------------------------------------------------// + public static String format1 (int value) + // ---------------------------------------------------------------------------------// + { + String text = hex[value]; + return text; + } + + // ---------------------------------------------------------------------------------// + public static int intValue (byte b1, byte b2) + // ---------------------------------------------------------------------------------// + { + return (b1 & 0xFF) + (b2 & 0xFF) * 256; + } + + // ---------------------------------------------------------------------------------// + public static int intValue (byte b1, byte b2, byte b3) + // ---------------------------------------------------------------------------------// + { + return (b1 & 0xFF) + (b2 & 0xFF) * 256 + (b3 & 0xFF) * 65536; + } + + // ---------------------------------------------------------------------------------// + public static int unsignedLong (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + int val = 0; + for (int i = 3; i >= 0; i--) + { + val <<= 8; + val += buffer[ptr + i] & 0xFF; + } + return val; + } + + // ---------------------------------------------------------------------------------// + public static int signedLong (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + return (((buffer[ptr] & 0xFF) << 24) | ((buffer[ptr] & 0xFF) << 16) + | ((buffer[ptr] & 0xFF) << 8) | (buffer[ptr + 1] & 0xFF)); + } + + // ---------------------------------------------------------------------------------// + public static int getLongBigEndian (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + int val = 0; + for (int i = 0; i < 4; i++) + { + val <<= 8; + val += buffer[ptr + i] & 0xFF; + } + return val; + } + + // ---------------------------------------------------------------------------------// + public static int unsignedShort (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + if (ptr >= buffer.length) + { + System.out.println ("Index out of range (unsigned short): " + ptr); + return 0; + } + return (buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8); + } + + // ---------------------------------------------------------------------------------// + public static int signedShort (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + if (ptr >= buffer.length) + { + System.out.println ("Index out of range (signed short): " + ptr); + return 0; + } + return (short) ((buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8)); + } + + // ---------------------------------------------------------------------------------// + public static int getShortBigEndian (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + int val = 0; + for (int i = 0; i < 2; i++) + { + val <<= 8; + val |= buffer[ptr + i] & 0xFF; + } + return val; + } + + // ---------------------------------------------------------------------------------// + public static double getSANEDouble (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + long bits = 0; + for (int i = 7; i >= 0; i--) + { + bits <<= 8; + bits |= buffer[offset + i] & 0xFF; + } + + return Double.longBitsToDouble (bits); + } + + // ---------------------------------------------------------------------------------// + public static double floatValueOld (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + double val = 0; + + int exponent = (buffer[offset] & 0xFF) - 0x80; + + int mantissa = + (buffer[offset + 1] & 0x7F) * 0x1000000 + (buffer[offset + 2] & 0xFF) * 0x10000 + + (buffer[offset + 3] & 0xFF) * 0x100 + (buffer[offset + 4] & 0xFF); + + int weight1 = 1; + long weight2 = 2147483648L; + double multiplier = 0; + + for (int i = 0; i < 32; i++) + { + if ((mantissa & weight2) > 0) + multiplier += (1.0 / weight1); + weight2 /= 2; + weight1 *= 2; + } + val = Math.pow (2, exponent - 1) * (multiplier + 1); + + return val; + } + + // ---------------------------------------------------------------------------------// + public static double floatValue (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// + { + int exponent = buffer[ptr] & 0x7F; // biased 128 + if (exponent == 0) + return 0.0; + + int mantissa = (buffer[ptr + 1] & 0x7F) << 24 | (buffer[ptr + 2] & 0xFF) << 16 + | (buffer[ptr + 3] & 0xFF) << 8 | (buffer[ptr + 4] & 0xFF); + boolean negative = (buffer[ptr + 1] & 0x80) > 0; + double value = 0.5; + for (int i = 2, weight = 0x40000000; i <= 32; i++, weight >>>= 1) + if ((mantissa & weight) > 0) + value += Math.pow (0.5, i); + value *= Math.pow (2, exponent); + BigDecimal bd = new BigDecimal (value); + double rounded = bd.round (mathContext).doubleValue (); + return negative ? rounded * -1 : rounded; + } + + // ---------------------------------------------------------------------------------// + public static GregorianCalendar getAppleDate (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + int date = HexFormatter.intValue (buffer[offset], buffer[offset + 1]); + if (date > 0) + { + int year = (date & 0xFE00) >> 9; + int month = (date & 0x01E0) >> 5; + int day = date & 0x001F; + int hour = buffer[offset + 3] & 0x1F; + int minute = buffer[offset + 2] & 0x3F; + if (year < 70) + year += 2000; + else + year += 1900; + return new GregorianCalendar (year, month - 1, day, hour, minute); + } + return null; + } + + // ---------------------------------------------------------------------------------// + public static GregorianCalendar getPascalDate (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + int year = (buffer[offset + 1] & 0xFF); + int day = (buffer[offset] & 0xF0) >> 4; + int month = buffer[offset] & 0x0F; + if (day == 0 || month == 0) + return null; + if (year % 2 > 0) + day += 16; + year /= 2; + if (year < 70) + year += 2000; + else + year += 1900; + return new GregorianCalendar (year, month - 1, day); + } + + // ---------------------------------------------------------------------------------// + public static String getPascalString (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + int length = buffer[offset] & 0xFF; + return HexFormatter.getString (buffer, offset + 1, length); + } + + // ---------------------------------------------------------------------------------// + public static String getCString (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// + { + int end = offset; + while (buffer[end] != 0) + end++; + + return HexFormatter.getString (buffer, offset, end - offset); + } +}