public Object read(byte[] data, ByteOrder order) throws IOException { ByteBuffer buffer = ByteBuffer.wrap(data); buffer.order(order); if (_type == DataType.BOOLEAN) { throw new IOException("Tried to read a boolean from data instead of null mask."); } else if (_type == DataType.BYTE) { return new Byte(buffer.get()); } else if (_type == DataType.INT) { return new Short(buffer.getShort()); } else if (_type == DataType.LONG) { return new Integer(buffer.getInt()); } else if (_type == DataType.DOUBLE) { return new Double(buffer.getDouble()); } else if (_type == DataType.FLOAT) { return new Float(buffer.getFloat()); } else if (_type == DataType.SHORT_DATE_TIME) {   double dval = buffer.getDouble(); dval *= MILLISECONDS_PER_DAY; dval -= (DAYS_BETWEEN_EPOCH_AND_1900 * MILLISECONDS_PER_DAY); long time = (long)dval; TimeZone tz = TimeZone.getDefault(); Date date = new Date(time - tz.getRawOffset()); if (tz.inDaylightTime(date)) { date = new Date(date.getTime() - tz.getDSTSavings()); } return date; } else if (_type == DataType.BINARY) { return data; } else if (_type == DataType.TEXT) { if (_compressedUnicode) { try { String rtn = new Expand().expand(data);     if (rtn.length() > 2 && (int) rtn.charAt(0) == 255 && (int) rtn.charAt(1) == 254) { rtn = rtn.substring(2); }  if (rtn.length() > 1 && (int) rtn.charAt(1) == 0) { char[] fixed = new char[rtn.length() / 2]; for (int i = 0; i < fixed.length; i ++) { fixed[i] = rtn.charAt(i * 2); } rtn = new String(fixed); } return rtn; } catch (IllegalInputException e) { throw new IOException("Can't expand text column"); } catch (EndOfInputException e) { throw new IOException("Can't expand text column"); } } else { return _format.CHARSET.decode(ByteBuffer.wrap(data)).toString(); } } else if (_type == DataType.MONEY) {  return null; } else if (_type == DataType.OLE) { if (data.length > 0) { return getLongBinaryValue(data); } else { return null; } } else if (_type == DataType.MEMO) { if (data.length > 0) { return getLongStringValue(data); } else { return null; } } else if (_type == DataType.NUMERIC) {  boolean negate = (buffer.get() != 0);  byte[] tmpArr = new byte[16]; buffer.get(tmpArr);  if(order != ByteOrder.BIG_ENDIAN) {  for(int i = 0; i < 4; ++i) { int idx = i * 4; byte b = tmpArr[idx + 0]; tmpArr[idx + 0] = tmpArr[idx + 3]; tmpArr[idx + 3] = b; b = tmpArr[idx + 1]; tmpArr[idx + 1] = tmpArr[idx + 2]; tmpArr[idx + 2] = b; } }  BigInteger intVal = new BigInteger(tmpArr); if(negate) { intVal = intVal.negate(); } return new BigDecimal(intVal, getScale());  } else if (_type == DataType.GUID) {  StringBuilder sb = new StringBuilder(22); sb.append("{"); sb.append(ByteUtil.toHexString(buffer, 0, 4, false)); sb.append("-"); sb.append(ByteUtil.toHexString(buffer, 4, 2, false)); sb.append("-"); sb.append(ByteUtil.toHexString(buffer, 6, 2, false)); sb.append("-"); sb.append(ByteUtil.toHexString(buffer, 8, 2, false)); sb.append("-"); sb.append(ByteUtil.toHexString(buffer, 10, 6, false)); sb.append("}"); return (sb.toString());  } else if (_type == DataType.UNKNOWN_0D) {  return null; } else { throw new IOException("Unrecognized data type: " + _type); }
public Object read(byte[] data) throws IOException { return read(data, ByteOrder.LITTLE_ENDIAN);
  public Object read(byte[] data, ByteOrder order) throws IOException {    ByteBuffer buffer = ByteBuffer.wrap(data);    buffer.order(order);    if (_type == DataType.BOOLEAN) {      throw new IOException("Tried to read a boolean from data instead of null mask.");    } else if (_type == DataType.BYTE) {      return new Byte(buffer.get());    } else if (_type == DataType.INT) {      return new Short(buffer.getShort());    } else if (_type == DataType.LONG) {      return new Integer(buffer.getInt());    } else if (_type == DataType.DOUBLE) {      return new Double(buffer.getDouble());    } else if (_type == DataType.FLOAT) {      return new Float(buffer.getFloat());    } else if (_type == DataType.SHORT_DATE_TIME) {      // seems access stores dates in the local timezone.  guess you just hope      // you read it in the same timezone in which it was written!      double dval = buffer.getDouble();      dval *= MILLISECONDS_PER_DAY;      dval -= (DAYS_BETWEEN_EPOCH_AND_1900 * MILLISECONDS_PER_DAY);      long time = (long)dval;      TimeZone tz = TimeZone.getDefault();      Date date = new Date(time - tz.getRawOffset());      if (tz.inDaylightTime(date))      {        date = new Date(date.getTime() - tz.getDSTSavings());      }      return date;    } else if (_type == DataType.BINARY) {      return data;    } else if (_type == DataType.TEXT) {      if (_compressedUnicode) {        try {          String rtn = new Expand().expand(data);          //SCSU expander isn't handling the UTF-8-looking 2-byte combo that          //prepends some of these strings.  Rather than dig into that code,          //I'm just stripping them off here.  However, this is probably not          //a great idea.          if (rtn.length() > 2 && (int) rtn.charAt(0) == 255 &&              (int) rtn.charAt(1) == 254)          {            rtn = rtn.substring(2);          }          //It also isn't handling short strings.          if (rtn.length() > 1 && (int) rtn.charAt(1) == 0) {            char[] fixed = new char[rtn.length() / 2];            for (int i = 0; i < fixed.length; i ++) {              fixed[i] = rtn.charAt(i * 2);            }            rtn = new String(fixed);          }          return rtn;        } catch (IllegalInputException e) {          throw new IOException("Can't expand text column");        } catch (EndOfInputException e) {          throw new IOException("Can't expand text column");        }      } else {        return _format.CHARSET.decode(ByteBuffer.wrap(data)).toString();      }    } else if (_type == DataType.MONEY) {      //XXX      return null;    } else if (_type == DataType.OLE) {      if (data.length > 0) {        return getLongBinaryValue(data);      } else {        return null;      }    } else if (_type == DataType.MEMO) {      if (data.length > 0) {        return getLongStringValue(data);      } else {        return null;      }    } else if (_type == DataType.NUMERIC) {      boolean negate = (buffer.get() != 0);      byte[] tmpArr = new byte[16];      buffer.get(tmpArr);      if(order != ByteOrder.BIG_ENDIAN) {        // fix endianness of each 4 byte segment        for(int i = 0; i < 4; ++i) {          int idx = i * 4;          byte b = tmpArr[idx + 0];          tmpArr[idx + 0] = tmpArr[idx + 3];          tmpArr[idx + 3] = b;          b = tmpArr[idx + 1];          tmpArr[idx + 1] = tmpArr[idx + 2];          tmpArr[idx + 2] = b;        }      }      BigInteger intVal = new BigInteger(tmpArr);      if(negate) {        intVal = intVal.negate();      }      return new BigDecimal(intVal, getScale());    } else if (_type == DataType.GUID) {            StringBuilder sb = new StringBuilder(22);      sb.append("{");      sb.append(ByteUtil.toHexString(buffer, 0, 4,                                     false));      sb.append("-");      sb.append(ByteUtil.toHexString(buffer, 4, 2,                                     false));      sb.append("-");      sb.append(ByteUtil.toHexString(buffer, 6, 2,                                     false));      sb.append("-");      sb.append(ByteUtil.toHexString(buffer, 8, 2,                                     false));      sb.append("-");      sb.append(ByteUtil.toHexString(buffer, 10, 6,                                     false));      sb.append("}");      return (sb.toString());          } else if (_type == DataType.UNKNOWN_0D) {            return null;    } else {      throw new IOException("Unrecognized data type: " + _type);    }  }