diff options
Diffstat (limited to 'src')
6 files changed, 100 insertions, 86 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ByteUtil.java b/src/main/java/com/healthmarketscience/jackcess/impl/ByteUtil.java index efb5587..a989f2e 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/ByteUtil.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ByteUtil.java @@ -17,6 +17,7 @@ limitations under the License. package com.healthmarketscience.jackcess.impl; import java.io.Closeable; +import java.io.DataInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; @@ -31,14 +32,14 @@ import java.util.Arrays; * @author Tim McCune */ public final class ByteUtil { - + private static final String[] HEX_CHARS = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; private static final int NUM_BYTES_PER_BLOCK = 4; private static final int NUM_BYTES_PER_LINE = 24; - + private ByteUtil() {} /** @@ -46,26 +47,26 @@ public final class ByteUtil { * integer. * @param buffer buffer into which to insert the int * @param val Int to convert - */ + */ public static void put3ByteInt(ByteBuffer buffer, int val) { put3ByteInt(buffer, val, buffer.order()); } - + /** * Put an integer into the given buffer at the given offset as a 3-byte * integer. * @param buffer buffer into which to insert the int * @param val Int to convert * @param order the order to insert the bytes of the int - */ + */ public static void put3ByteInt(ByteBuffer buffer, int val, ByteOrder order) { int pos = buffer.position(); put3ByteInt(buffer, val, pos, order); buffer.position(pos + 3); } - + /** * Put an integer into the given buffer at the given offset as a 3-byte * integer. @@ -73,7 +74,7 @@ public final class ByteUtil { * @param val Int to convert * @param offset offset at which to insert the int * @param order the order to insert the bytes of the int - */ + */ public static void put3ByteInt(ByteBuffer buffer, int val, int offset, ByteOrder order) { @@ -103,7 +104,7 @@ public final class ByteUtil { * @param order the order of the bytes of the int * @return The int */ - public static int get3ByteInt(ByteBuffer buffer, ByteOrder order) { + public static int get3ByteInt(ByteBuffer buffer, ByteOrder order) { int pos = buffer.position(); int rtn = get3ByteInt(buffer, pos, order); buffer.position(pos + 3); @@ -119,7 +120,7 @@ public final class ByteUtil { public static int get3ByteInt(ByteBuffer buffer, int offset) { return get3ByteInt(buffer, offset, buffer.order()); } - + /** * Read a 3 byte int from a buffer * @param buffer Buffer containing the bytes @@ -135,7 +136,7 @@ public final class ByteUtil { offInc = -1; offset += 2; } - + int rtn = getUnsignedByte(buffer, offset); rtn += (getUnsignedByte(buffer, offset + (1 * offInc)) << 8); rtn += (getUnsignedByte(buffer, offset + (2 * offInc)) << 16); @@ -160,10 +161,10 @@ public final class ByteUtil { * @param offset Offset at which to read the byte * @return The unsigned byte as an int */ - public static int getUnsignedByte(ByteBuffer buffer, int offset) { + public static int getUnsignedByte(ByteBuffer buffer, int offset) { return asUnsignedByte(buffer.get(offset)); } - + /** * Read an unsigned short from a buffer * @param buffer Buffer containing the short @@ -182,11 +183,11 @@ public final class ByteUtil { * @param offset Offset at which to read the short * @return The unsigned short as an int */ - public static int getUnsignedShort(ByteBuffer buffer, int offset) { + public static int getUnsignedShort(ByteBuffer buffer, int offset) { return asUnsignedShort(buffer.getShort(offset)); } - + /** * @param buffer Buffer containing the bytes * @param order the order of the bytes of the int @@ -199,7 +200,7 @@ public final class ByteUtil { buffer.position(offset + 4); return rtn; } - + /** * @param buffer Buffer containing the bytes * @param offset Offset at which to start reading the int @@ -215,7 +216,7 @@ public final class ByteUtil { buffer.order(origOrder); } } - + /** * Writes an int at the current position in the given buffer, using the * given ByteOrder @@ -228,7 +229,7 @@ public final class ByteUtil { putInt(buffer, val, offset, order); buffer.position(offset + 4); } - + /** * Writes an int at the given position in the given buffer, using the * given ByteOrder @@ -266,8 +267,8 @@ public final class ByteUtil { * @param offset Offset at which to read the value * @return The unsigned int */ - public static int getUnsignedVarInt(ByteBuffer buffer, int offset, - int numBytes) { + public static int getUnsignedVarInt(ByteBuffer buffer, int offset, + int numBytes) { switch(numBytes) { case 1: return getUnsignedByte(buffer, offset); @@ -292,7 +293,7 @@ public final class ByteUtil { public static byte[] getBytes(ByteBuffer buffer, int len) { byte[] bytes = new byte[len]; - buffer.get(bytes); + buffer.get(bytes); return bytes; } @@ -324,7 +325,7 @@ public final class ByteUtil { System.arraycopy(b2, 0, out, b1.length, b2.length); return out; } - + /** * Sets all bits in the given remaining byte range to 0. */ @@ -354,7 +355,7 @@ public final class ByteUtil { { putRange(buffer, start, end, (byte)0xff); } - + /** * Sets all bytes in the given byte range to the given byte value. */ @@ -412,7 +413,7 @@ public final class ByteUtil { Arrays.fill(buf, pos, pos + len, (byte)0); buffer.limit(limit + len); } - + /** * Convert a byte buffer to a hexadecimal string for display * @param buffer Buffer to display, starting at offset 0 @@ -422,7 +423,7 @@ public final class ByteUtil { public static String toHexString(ByteBuffer buffer, int size) { return toHexString(buffer, 0, size); } - + /** * Convert a byte array to a hexadecimal string for display * @param array byte array to display, starting at offset 0 @@ -431,7 +432,7 @@ public final class ByteUtil { public static String toHexString(byte[] array) { return toHexString(ByteBuffer.wrap(array), 0, array.length); } - + /** * Convert a byte buffer to a hexadecimal string for display * @param buffer Buffer to display, starting at offset 0 @@ -441,7 +442,7 @@ public final class ByteUtil { */ public static String toHexString(ByteBuffer buffer, int offset, int size) { return toHexString(buffer, offset, size, true); - } + } /** * Convert a byte buffer to a hexadecimal string for display @@ -453,10 +454,10 @@ public final class ByteUtil { */ public static String toHexString(ByteBuffer buffer, int offset, int size, boolean formatted) { - + int bufLen = size * 2; if(formatted) { - bufLen += size + + bufLen += size + (7 * ((size + NUM_BYTES_PER_LINE - 1) / NUM_BYTES_PER_LINE)); } StringBuilder rtn = new StringBuilder(bufLen); @@ -481,7 +482,7 @@ public final class ByteUtil { rtn.append("\n"); } else { - + rtn.append(" "); if ((next % NUM_BYTES_PER_BLOCK) == 0) { @@ -530,7 +531,7 @@ public final class ByteUtil { */ public static void toHexFile( String fileName, - ByteBuffer buffer, + ByteBuffer buffer, int offset, int size) throws IOException { @@ -546,14 +547,14 @@ public final class ByteUtil { /** * @return the byte value converted to an unsigned int value */ - public static int asUnsignedByte(byte b) { + public static int asUnsignedByte(byte b) { return b & 0xFF; } - + /** * @return the short value converted to an unsigned int value */ - public static int asUnsignedShort(short s) { + public static int asUnsignedShort(short s) { return s & 0xFFFF; } @@ -637,7 +638,7 @@ public final class ByteUtil { * Returns a copy of the given array of the given length starting at the * given position. */ - public static byte[] copyOf(byte[] arr, int offset, int newLength, + public static byte[] copyOf(byte[] arr, int offset, int newLength, int dstOffset) { byte[] newArr = new byte[newLength]; @@ -670,6 +671,18 @@ public final class ByteUtil { } /** + * Skips the given number of bytes in the given stream + */ + public static void skipFully(DataInputStream din, int len) + throws IOException + { + do { + int skipped = din.skipBytes(len); + len -= skipped; + } while(len > 0); + } + + /** * Utility byte stream similar to ByteArrayOutputStream but with extended * accessibility to the bytes. */ diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColValidatorEvalContext.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColValidatorEvalContext.java index 521fe4d..794def1 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/ColValidatorEvalContext.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColValidatorEvalContext.java @@ -50,7 +50,7 @@ public class ColValidatorEvalContext extends ColEvalContext @Override protected Object internalValidate(Column col, Object val) throws IOException { - return ColValidatorEvalContext.this.validate(col, val); + return ColValidatorEvalContext.this.validate(val); } @Override protected void appendToString(StringBuilder sb) { @@ -78,7 +78,7 @@ public class ColValidatorEvalContext extends ColEvalContext return getThisColumnValue(); } - private Object validate(Column col, Object val) throws IOException { + private Object validate(Object val) throws IOException { try { _val = val; Boolean result = (Boolean)eval(); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/CompoundOleUtil.java b/src/main/java/com/healthmarketscience/jackcess/impl/CompoundOleUtil.java index ff27908..8440f81 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/CompoundOleUtil.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/CompoundOleUtil.java @@ -41,14 +41,14 @@ import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; /** * Utility code for working with OLE data which is in the compound storage * format. This functionality relies on the optional POI library. - * <p/> + * <p/> * Note that all POI usage is restricted to this file so that the basic ole * support in OleUtil can be utilized without requiring POI. * * @author James Ahlborn * @usage _advanced_class_ */ -public class CompoundOleUtil implements OleUtil.CompoundPackageFactory +public class CompoundOleUtil implements CompoundPackageFactory { private static final String ENTRY_NAME_CHARSET = "UTF-8"; private static final String ENTRY_SEPARATOR = "/"; @@ -60,7 +60,7 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory NPOIFSFileSystem.class.getName(); } - public CompoundOleUtil() + public CompoundOleUtil() { } @@ -87,8 +87,8 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory * @throws IOException if some other io error occurs */ public static DocumentEntry getDocumentEntry(String entryName, - DirectoryEntry dir) - throws IOException + DirectoryEntry dir) + throws IOException { // split entry name into individual components and decode them List<String> entryNames = new ArrayList<String>(); @@ -109,9 +109,9 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory entry = (DocumentEntry)tmpEntry; } else { break; - } + } } - + if(entry == null) { throw new FileNotFoundException("Could not find document " + entryName); } @@ -135,7 +135,7 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory } } - private static final class CompoundContentImpl + private static final class CompoundContentImpl extends EmbeddedPackageContentImpl implements CompoundContent { @@ -143,10 +143,10 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory private CompoundContentImpl( OleBlobImpl blob, String prettyName, String className, - String typeName, int position, int length) + String typeName, int position, int length) { super(blob, prettyName, className, typeName, position, length); - } + } public ContentType getType() { return ContentType.COMPOUND_STORAGE; @@ -169,7 +169,7 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory } public EntryImpl getEntry(String entryName) throws IOException { - return new EntryImpl(entryName, + return new EntryImpl(entryName, getDocumentEntry(entryName, getFileSystem().getRoot())); } @@ -181,7 +181,7 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory return getEntry(CONTENTS_ENTRY); } - private List<Entry> getEntries(List<Entry> entries, DirectoryEntry dir, + private List<Entry> getEntries(List<Entry> entries, DirectoryEntry dir, String prefix) { for(org.apache.poi.poifs.filesystem.Entry entry : dir) { if (entry instanceof DirectoryEntry) { @@ -210,10 +210,10 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory try { sb.append("hasContentsEntry", hasContentsEntry()); - sb.append("entries", getEntries(new ArrayList<Entry>(), + sb.append("entries", getEntries(new ArrayList<Entry>(), getFileSystem().getRoot(), ENTRY_SEPARATOR)); - } catch(IOException e) { + } catch(IOException e) { sb.append("entries", "<" + e + ">"); } @@ -270,7 +270,7 @@ public class CompoundOleUtil implements OleUtil.CompoundPackageFactory .append("length", length()) .toString(); } - } + } } } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DBEvalContext.java b/src/main/java/com/healthmarketscience/jackcess/impl/DBEvalContext.java index ab8a2d4..4361cac 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/DBEvalContext.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/DBEvalContext.java @@ -82,7 +82,7 @@ public class DBEvalContext implements Expressionator.ParseContext, EvalConfig _sdfs = new SimpleCache<String,SimpleDateFormat>(MAX_CACHE_SIZE); } SimpleDateFormat sdf = _sdfs.get(formatStr); - if(formatStr == null) { + if(sdf == null) { sdf = _db.createDateFormat(formatStr); _sdfs.put(formatStr, sdf); } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/complex/AttachmentColumnInfoImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/complex/AttachmentColumnInfoImpl.java index 755183b..6642a69 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/complex/AttachmentColumnInfoImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/complex/AttachmentColumnInfoImpl.java @@ -54,7 +54,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> { /** some file formats which may not be worth re-compressing */ private static final Set<String> COMPRESSED_FORMATS = new HashSet<String>( - Arrays.asList("jpg", "zip", "gz", "bz2", "z", "7z", "cab", "rar", + Arrays.asList("jpg", "zip", "gz", "bz2", "z", "7z", "cab", "rar", "mp3", "mpg")); private static final String FILE_NAME_COL_NAME = "FileName"; @@ -73,7 +73,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> private final Column _fileDataCol; private final Column _fileTimeStampCol; private final Column _fileFlagsCol; - + public AttachmentColumnInfoImpl(Column column, int complexId, Table typeObjTable, Table flatTable) throws IOException @@ -119,7 +119,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> // ignore } } - + _fileUrlCol = fileUrlCol; _fileNameCol = fileNameCol; _fileTypeCol = fileTypeCol; @@ -131,7 +131,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public Column getFileUrlColumn() { return _fileUrlCol; } - + public Column getFileNameColumn() { return _fileNameCol; } @@ -139,19 +139,19 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public Column getFileTypeColumn() { return _fileTypeCol; } - + public Column getFileDataColumn() { return _fileDataCol; } - + public Column getFileTimeStampColumn() { return _fileTimeStampCol; } - + public Column getFileFlagsColumn() { return _fileFlagsCol; - } - + } + @Override public ComplexDataType getType() { @@ -168,14 +168,14 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> Integer flags = (Integer)getFileFlagsColumn().getRowValue(rawValue); Date ts = (Date)getFileTimeStampColumn().getRowValue(rawValue); byte[] data = (byte[])getFileDataColumn().getRowValue(rawValue); - + return new AttachmentImpl(id, complexValueFk, url, name, type, null, ts, flags, data); } @Override - protected Object[] asRow(Object[] row, Attachment attachment) - throws IOException + protected Object[] asRow(Object[] row, Attachment attachment) + throws IOException { super.asRow(row, attachment); getFileUrlColumn().setRowValue(row, attachment.getFileUrl()); @@ -190,7 +190,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public static Attachment newAttachment(byte[] data) { return newAttachment(INVALID_FK, data); } - + public static Attachment newAttachment(ComplexValueForeignKey complexValueFk, byte[] data) { return newAttachment(complexValueFk, null, null, null, data, null, null); @@ -203,7 +203,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> return newAttachment(INVALID_FK, url, name, type, data, timeStamp, flags); } - + public static Attachment newAttachment( ComplexValueForeignKey complexValueFk, String url, String name, String type, byte[] data, Date timeStamp, Integer flags) @@ -215,30 +215,30 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public static Attachment newEncodedAttachment(byte[] encodedData) { return newEncodedAttachment(INVALID_FK, encodedData); } - + public static Attachment newEncodedAttachment( ComplexValueForeignKey complexValueFk, byte[] encodedData) { return newEncodedAttachment(complexValueFk, null, null, null, encodedData, null, null); } - + public static Attachment newEncodedAttachment( String url, String name, String type, byte[] encodedData, Date timeStamp, Integer flags) { - return newEncodedAttachment(INVALID_FK, url, name, type, + return newEncodedAttachment(INVALID_FK, url, name, type, encodedData, timeStamp, flags); } - + public static Attachment newEncodedAttachment( ComplexValueForeignKey complexValueFk, String url, String name, String type, byte[] encodedData, Date timeStamp, Integer flags) { return new AttachmentImpl(INVALID_ID, complexValueFk, url, name, type, null, timeStamp, flags, encodedData); - } + } + - private static class AttachmentImpl extends ComplexValueImpl implements Attachment { @@ -263,7 +263,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> _flags = flags; _encodedData = encodedData; } - + public byte[] getFileData() throws IOException { if((_data == null) && (_encodedData != null)) { _data = decodeData(); @@ -295,7 +295,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public void setFileName(String fileName) { _name = fileName; } - + public String getFileUrl() { return _url; } @@ -303,7 +303,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public void setFileUrl(String fileUrl) { _url = fileUrl; } - + public String getFileType() { return _type; } @@ -311,7 +311,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public void setFileType(String fileType) { _type = fileType; } - + public Date getFileTimeStamp() { return _timeStamp; } @@ -319,23 +319,23 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> public void setFileTimeStamp(Date fileTimeStamp) { _timeStamp = fileTimeStamp; } - + public Integer getFileFlags() { return _flags; } public void setFileFlags(Integer fileFlags) { _flags = fileFlags; - } + } public void update() throws IOException { getComplexValueForeignKey().updateAttachment(this); } - + public void delete() throws IOException { getComplexValueForeignKey().deleteAttachment(this); } - + @Override public String toString() { @@ -345,12 +345,12 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> } catch(IOException e) { dataStr = e.toString(); } - + return "Attachment(" + getComplexValueForeignKey() + "," + getId() + ") " + getFileUrl() + ", " + getFileName() + ", " + getFileType() + ", " + getFileTimeStamp() + ", " + getFileFlags() + ", " + dataStr; - } + } /** * Decodes the raw attachment file data to get the _actual_ content. @@ -361,7 +361,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> // nothing we can do throw new IOException("Unknown encoded attachment data format"); } - + // read initial header info ByteBuffer bb = PageChannel.wrap(_encodedData); int typeFlag = bb.getInt(); @@ -391,7 +391,7 @@ public class AttachmentColumnInfoImpl extends ComplexColumnInfoImpl<Attachment> byte[] tmpBytes = new byte[4]; contentStream.readFully(tmpBytes); int headerLen = PageChannel.wrap(tmpBytes).getInt(); - contentStream.skipBytes(headerLen - 4); + ByteUtil.skipFully(contentStream, headerLen - 4); // calculate actual data length and read it (note, header length // includes the bytes for the length) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java index 75fa68c..e60c956 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java @@ -45,7 +45,6 @@ public class DefaultDateFunctions private static final long SECONDS_PER_HOUR = 60L * 60L; private static final long SECONDS_PER_MINUTE = 60L; - private static final long MILLIS_PER_SECOND = 1000L; private DefaultDateFunctions() {} @@ -203,10 +202,12 @@ public class DefaultDateFunctions } private static Calendar nonNullToCalendar(EvalContext ctx, Value param) { + Value origParam = param; param = nonNullToDateValue(ctx, param); if(param == null) { // not a date/time - throw new EvalException("Invalid date/time expression '" + param + "'"); + throw new EvalException("Invalid date/time expression '" + + origParam + "'"); } Calendar cal = getDateValueFormat(ctx, param).getCalendar(); |