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;
* @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() {}
/**
* 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.
* @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) {
* @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);
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
offInc = -1;
offset += 2;
}
-
+
int rtn = getUnsignedByte(buffer, offset);
rtn += (getUnsignedByte(buffer, offset + (1 * offInc)) << 8);
rtn += (getUnsignedByte(buffer, offset + (2 * offInc)) << 16);
* @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
* @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
buffer.position(offset + 4);
return rtn;
}
-
+
/**
* @param buffer Buffer containing the bytes
* @param offset Offset at which to start reading the int
buffer.order(origOrder);
}
}
-
+
/**
* Writes an int at the current position in the given buffer, using the
* given ByteOrder
putInt(buffer, val, offset, order);
buffer.position(offset + 4);
}
-
+
/**
* Writes an int at the given position in the given buffer, using the
* given ByteOrder
* @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);
public static byte[] getBytes(ByteBuffer buffer, int len)
{
byte[] bytes = new byte[len];
- buffer.get(bytes);
+ buffer.get(bytes);
return bytes;
}
System.arraycopy(b2, 0, out, b1.length, b2.length);
return out;
}
-
+
/**
* Sets all bits in the given remaining byte range to 0.
*/
{
putRange(buffer, start, end, (byte)0xff);
}
-
+
/**
* Sets all bytes in the given byte range to the given byte value.
*/
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
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
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
*/
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
*/
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);
rtn.append("\n");
} else {
-
+
rtn.append(" ");
if ((next % NUM_BYTES_PER_BLOCK) == 0) {
*/
public static void toHexFile(
String fileName,
- ByteBuffer buffer,
+ ByteBuffer buffer,
int offset, int size)
throws IOException
{
/**
* @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;
}
* 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];
}
}
+ /**
+ * 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.
@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) {
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();
/**
* 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 = "/";
NPOIFSFileSystem.class.getName();
}
- public CompoundOleUtil()
+ public CompoundOleUtil()
{
}
* @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>();
entry = (DocumentEntry)tmpEntry;
} else {
break;
- }
+ }
}
-
+
if(entry == null) {
throw new FileNotFoundException("Could not find document " + entryName);
}
}
}
- private static final class CompoundContentImpl
+ private static final class CompoundContentImpl
extends EmbeddedPackageContentImpl
implements CompoundContent
{
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;
}
public EntryImpl getEntry(String entryName) throws IOException {
- return new EntryImpl(entryName,
+ return new EntryImpl(entryName,
getDocumentEntry(entryName, getFileSystem().getRoot()));
}
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) {
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 + ">");
}
.append("length", length())
.toString();
}
- }
+ }
}
}
_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);
}
{
/** 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";
private final Column _fileDataCol;
private final Column _fileTimeStampCol;
private final Column _fileFlagsCol;
-
+
public AttachmentColumnInfoImpl(Column column, int complexId,
Table typeObjTable, Table flatTable)
throws IOException
// ignore
}
}
-
+
_fileUrlCol = fileUrlCol;
_fileNameCol = fileNameCol;
_fileTypeCol = fileTypeCol;
public Column getFileUrlColumn() {
return _fileUrlCol;
}
-
+
public Column getFileNameColumn() {
return _fileNameCol;
}
public Column getFileTypeColumn() {
return _fileTypeCol;
}
-
+
public Column getFileDataColumn() {
return _fileDataCol;
}
-
+
public Column getFileTimeStampColumn() {
return _fileTimeStampCol;
}
-
+
public Column getFileFlagsColumn() {
return _fileFlagsCol;
- }
-
+ }
+
@Override
public ComplexDataType getType()
{
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());
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);
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)
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
{
_flags = flags;
_encodedData = encodedData;
}
-
+
public byte[] getFileData() throws IOException {
if((_data == null) && (_encodedData != null)) {
_data = decodeData();
public void setFileName(String fileName) {
_name = fileName;
}
-
+
public String getFileUrl() {
return _url;
}
public void setFileUrl(String fileUrl) {
_url = fileUrl;
}
-
+
public String getFileType() {
return _type;
}
public void setFileType(String fileType) {
_type = fileType;
}
-
+
public Date getFileTimeStamp() {
return _timeStamp;
}
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() {
} 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.
// 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();
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)
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() {}
}
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();