diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2009-12-05 14:56:47 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2009-12-05 14:56:47 +0000 |
commit | 1302a37c91dd9c8fe5d308125f77f2540b7bc4f9 (patch) | |
tree | 4dfbc6c5064d0bcd28441ca73d5f88dd8b879f37 /src/java | |
parent | 075780a2f3e3ca1926eaa57f813bb2843bf42e18 (diff) | |
download | jackcess-1302a37c91dd9c8fe5d308125f77f2540b7bc4f9.tar.gz jackcess-1302a37c91dd9c8fe5d308125f77f2540b7bc4f9.zip |
improve date handling, handle more binary/character input types
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@420 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/java')
-rw-r--r-- | src/java/com/healthmarketscience/jackcess/Column.java | 104 |
1 files changed, 93 insertions, 11 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index 35cab9b..2290ebb 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -27,14 +27,20 @@ King of Prussia, PA 19406 package com.healthmarketscience.jackcess; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; import java.io.ObjectStreamException; +import java.io.Reader; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.CharBuffer; +import java.sql.Blob; +import java.sql.Clob; import java.sql.SQLException; import java.util.Calendar; import java.util.Date; @@ -719,14 +725,22 @@ public class Column implements Comparable<Column> { // seems access stores dates in the local timezone. guess you just hope // you read it in the same timezone in which it was written! long dateBits = buffer.getLong(); - long time = (long)(Double.longBitsToDouble(dateBits) - * MILLISECONDS_PER_DAY); - time -= MILLIS_BETWEEN_EPOCH_AND_1900; - time -= getTimeZoneOffset(time); + long time = fromDateDouble(Double.longBitsToDouble(dateBits)); return new DateExt(time, dateBits); } /** + * Returns a java long time value converted from an access date double. + */ + private static long fromDateDouble(double value) + { + long time = Math.round(value * MILLISECONDS_PER_DAY); + time -= MILLIS_BETWEEN_EPOCH_AND_1900; + time -= getTimeZoneOffset(time); + return time; + } + + /** * Writes a date value. */ private void writeDateValue(ByteBuffer buffer, Object value) @@ -741,16 +755,26 @@ public class Column implements Comparable<Column> { } else { + buffer.putDouble(toDateDouble(value)); + } + } + + /** + * Returns an access date double converted from a java Date/Calendar/Number + * time value. + */ + private static double toDateDouble(Object value) + { // seems access stores dates in the local timezone. guess you just // hope you read it in the same timezone in which it was written! long time = ((value instanceof Date) ? ((Date)value).getTime() : - ((Number)value).longValue()); + ((value instanceof Calendar) ? + ((Calendar)value).getTimeInMillis() : + ((Number)value).longValue())); time += getTimeZoneOffset(time); time += MILLIS_BETWEEN_EPOCH_AND_1900; - double dTime = time / MILLISECONDS_PER_DAY; - buffer.putDouble(dTime); - } + return time / MILLISECONDS_PER_DAY; } /** @@ -1069,7 +1093,7 @@ public class Column implements Comparable<Column> { getType()); } - ByteBuffer buffer = ByteBuffer.wrap((byte[])obj); + ByteBuffer buffer = ByteBuffer.wrap(toByteArray(obj)); buffer.order(order); return buffer; } @@ -1089,7 +1113,7 @@ public class Column implements Comparable<Column> { } // create long value buffer - return writeLongValue((byte[]) obj, remainingRowLength); + return writeLongValue(toByteArray(obj), remainingRowLength); } /** @@ -1153,7 +1177,7 @@ public class Column implements Comparable<Column> { case BINARY: case UNKNOWN_0D: case UNKNOWN_11: - byte[] bytes = (byte[])obj; + byte[] bytes = toByteArray(obj); if(bytes.length != getLength()) { throw new IOException("Invalid fixed size binary data, size " + getLength() + ", got " + bytes.length); @@ -1439,16 +1463,74 @@ public class Column implements Comparable<Column> { * @return an appropriate CharSequence representation of the given object. */ public static CharSequence toCharSequence(Object value) + throws IOException { if(value == null) { return null; } else if(value instanceof CharSequence) { return (CharSequence)value; + } else if(value instanceof Clob) { + try { + Clob c = (Clob)value; + // note, start pos is 1-based + return c.getSubString(1L, (int)c.length()); + } catch(SQLException e) { + throw (IOException)(new IOException(e.getMessage())).initCause(e); + } + } else if(value instanceof Reader) { + char[] buf = new char[8 * 1024]; + StringBuilder sout = new StringBuilder(); + Reader in = (Reader)value; + int read = 0; + while((read = in.read(buf)) != -1) { + sout.append(buf, 0, read); + } + return sout; } + return value.toString(); } /** + * @return an appropriate byte[] representation of the given object. + */ + public static byte[] toByteArray(Object value) + throws IOException + { + if(value == null) { + return null; + } else if(value instanceof byte[]) { + return (byte[])value; + } else if(value instanceof Blob) { + try { + Blob b = (Blob)value; + // note, start pos is 1-based + return b.getBytes(1L, (int)b.length()); + } catch(SQLException e) { + throw (IOException)(new IOException(e.getMessage())).initCause(e); + } + } + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + if(value instanceof InputStream) { + byte[] buf = new byte[8 * 1024]; + InputStream in = (InputStream)value; + int read = 0; + while((read = in.read(buf)) != -1) { + bout.write(buf, 0, read); + } + } else { + // if all else fails, serialize it + ObjectOutputStream oos = new ObjectOutputStream(bout); + oos.writeObject(value); + oos.close(); + } + + return bout.toByteArray(); + } + + /** * Interpret a boolean value (null == false) */ public static boolean toBooleanValue(Object obj) { |