aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2013-06-02 02:23:36 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2013-06-02 02:23:36 +0000
commit52df2373c7bb61b784b3d983c6ee42ae4b1cb030 (patch)
tree12f0679c793fe97f8ca9e44e9c21fa10db205890 /src
parent99f648a340dd45967550a511f8a27a16c2c5b5f3 (diff)
downloadjackcess-52df2373c7bb61b784b3d983c6ee42ae4b1cb030.tar.gz
jackcess-52df2373c7bb61b784b3d983c6ee42ae4b1cb030.zip
add methods to get the actual attachment content
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@733 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src')
-rw-r--r--src/changes/changes.xml4
-rw-r--r--src/java/com/healthmarketscience/jackcess/Column.java3
-rw-r--r--src/java/com/healthmarketscience/jackcess/Database.java3
-rw-r--r--src/java/com/healthmarketscience/jackcess/PageChannel.java8
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/Attachment.java5
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java127
-rw-r--r--src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java18
7 files changed, 160 insertions, 8 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index c5b9575..d26c22d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -12,6 +12,10 @@
<action dev="jahlborn" type="update">
Add more methods to Database for retrieving Relationships.
</action>
+ <action dev="jahlborn" type="update">
+ Add methods to get the actual attachment content, thanks to Lorenzo
+ Carrara.
+ </action>
</release>
<release version="1.2.12" date="2013-05-09">
<action dev="jahlborn" type="fix" system="SourceForge2" issue="94">
diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java
index 3c0274f..5f445b1 100644
--- a/src/java/com/healthmarketscience/jackcess/Column.java
+++ b/src/java/com/healthmarketscience/jackcess/Column.java
@@ -899,8 +899,7 @@ public class Column implements Comparable<Column> {
private byte[] readLongValue(byte[] lvalDefinition)
throws IOException
{
- ByteBuffer def = ByteBuffer.wrap(lvalDefinition)
- .order(PageChannel.DEFAULT_BYTE_ORDER);
+ ByteBuffer def = PageChannel.wrap(lvalDefinition);
int lengthWithFlags = def.getInt();
int length = lengthWithFlags & (~LONG_VALUE_TYPE_MASK);
diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java
index 3a720b2..450c9b9 100644
--- a/src/java/com/healthmarketscience/jackcess/Database.java
+++ b/src/java/com/healthmarketscience/jackcess/Database.java
@@ -2409,8 +2409,7 @@ public class Database
double dateVal = Double.longBitsToDouble(buffer.getLong());
byte[] pwdMask = new byte[4];
- ByteBuffer.wrap(pwdMask).order(PageChannel.DEFAULT_BYTE_ORDER)
- .putInt((int)dateVal);
+ PageChannel.wrap(pwdMask).putInt((int)dateVal);
return pwdMask;
}
diff --git a/src/java/com/healthmarketscience/jackcess/PageChannel.java b/src/java/com/healthmarketscience/jackcess/PageChannel.java
index 58b4017..27cb0ab 100644
--- a/src/java/com/healthmarketscience/jackcess/PageChannel.java
+++ b/src/java/com/healthmarketscience/jackcess/PageChannel.java
@@ -380,4 +380,12 @@ public class PageChannel implements Channel, Flushable {
.position(position)
.mark();
}
+
+ /**
+ * Returns a ByteBuffer wrapping the given bytes and configured with the
+ * default byte order.
+ */
+ public static ByteBuffer wrap(byte[] bytes) {
+ return ByteBuffer.wrap(bytes).order(DEFAULT_BYTE_ORDER);
+ }
}
diff --git a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java
index 2f4b046..be7e302 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java
@@ -19,6 +19,7 @@ USA
package com.healthmarketscience.jackcess.complex;
+import java.io.IOException;
import java.util.Date;
/**
@@ -32,6 +33,10 @@ public interface Attachment extends ComplexValue
public void setFileData(byte[] data);
+ public byte[] getDecodedFileData() throws IOException;
+
+ public void setDecodedFileData(byte[] data);
+
public String getFileName();
public void setFileName(String fileName);
diff --git a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java
index 5410e41..eb3ca73 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java
@@ -19,13 +19,19 @@ USA
package com.healthmarketscience.jackcess.complex;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.zip.InflaterInputStream;
import com.healthmarketscience.jackcess.ByteUtil;
import com.healthmarketscience.jackcess.Column;
+import com.healthmarketscience.jackcess.PageChannel;
import com.healthmarketscience.jackcess.Table;
@@ -39,6 +45,9 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
private static final String FILE_NAME_COL_NAME = "FileName";
private static final String FILE_TYPE_COL_NAME = "FileType";
+ private static final int DATA_TYPE_RAW = 0;
+ private static final int DATA_TYPE_COMPRESSED = 1;
+
private final Column _fileUrlCol;
private final Column _fileNameCol;
private final Column _fileTypeCol;
@@ -142,7 +151,7 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
byte[] data = (byte[])getFileDataColumn().getRowValue(rawValue);
return new AttachmentImpl(id, complexValueFk, url, name, type, data,
- ts, flags);
+ ts, flags, null);
}
@Override
@@ -179,7 +188,33 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
String type, byte[] data, Date timeStamp, Integer flags)
{
return new AttachmentImpl(INVALID_ID, complexValueFk, url, name, type,
- data, timeStamp, flags);
+ data, timeStamp, flags, null);
+ }
+
+ public static Attachment newDecodedAttachment(byte[] decodedData) {
+ return newDecodedAttachment(INVALID_COMPLEX_VALUE_ID, decodedData);
+ }
+
+ public static Attachment newDecodedAttachment(
+ ComplexValueForeignKey complexValueFk, byte[] decodedData) {
+ return newDecodedAttachment(complexValueFk, null, null, null, decodedData,
+ null, null);
+ }
+
+ public static Attachment newDecodedAttachment(
+ String url, String name, String type, byte[] decodedData,
+ Date timeStamp, Integer flags)
+ {
+ return newDecodedAttachment(INVALID_COMPLEX_VALUE_ID, url, name, type,
+ decodedData, timeStamp, flags);
+ }
+
+ public static Attachment newDecodedAttachment(
+ ComplexValueForeignKey complexValueFk, String url, String name,
+ String type, byte[] decodedData, Date timeStamp, Integer flags)
+ {
+ return new AttachmentImpl(INVALID_ID, complexValueFk, url, name, type,
+ null, timeStamp, flags, decodedData);
}
@@ -235,10 +270,11 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
private byte[] _data;
private Date _timeStamp;
private Integer _flags;
+ private byte[] _decodedData;
private AttachmentImpl(int id, ComplexValueForeignKey complexValueFk,
String url, String name, String type, byte[] data,
- Date timeStamp, Integer flags)
+ Date timeStamp, Integer flags, byte[] decodedData)
{
super(id, complexValueFk);
_url = url;
@@ -247,14 +283,31 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
_data = data;
_timeStamp = timeStamp;
_flags = flags;
+ _decodedData = decodedData;
}
public byte[] getFileData() {
+ if((_data == null) && (_decodedData != null)) {
+ _data = encodeData();
+ }
return _data;
}
public void setFileData(byte[] data) {
_data = data;
+ _decodedData = null;
+ }
+
+ public byte[] getDecodedFileData() throws IOException {
+ if((_decodedData == null) && (_data != null)) {
+ _decodedData = decodeData();
+ }
+ return _decodedData;
+ }
+
+ public void setDecodedFileData(byte[] data) {
+ _decodedData = data;
+ _data = null;
}
public String getFileName() {
@@ -313,6 +366,72 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
+ ", " + getFileTimeStamp() + ", " + getFileFlags() + ", " +
ByteUtil.toHexString(getFileData());
}
+
+ /**
+ * Decodes the raw attachment file data to get the _actual_ content.
+ */
+ private byte[] decodeData() throws IOException {
+
+ if(_data.length < 8) {
+ // nothing we can do
+ throw new IOException("Unknown encoded attachment data format");
+ }
+
+ // read initial header info
+ ByteBuffer bb = PageChannel.wrap(_data);
+ int typeFlag = bb.getInt();
+ int dataLen = bb.getInt();
+
+ DataInputStream contentStream = null;
+ try {
+ InputStream bin = new ByteArrayInputStream(
+ _data, 8, _data.length - 8);
+
+ if(typeFlag == DATA_TYPE_RAW) {
+ // nothing else to do
+ } else if(typeFlag == DATA_TYPE_COMPRESSED) {
+ // actual content is deflate compressed
+ bin = new InflaterInputStream(bin);
+ } else {
+ throw new IOException(
+ "Unknown encoded attachment data type " + typeFlag);
+ }
+
+ contentStream = new DataInputStream(bin);
+
+ // header is the "file extension" of the data. no clue why we need
+ // that again since it's already a separate field in the attachment
+ // table. just skip it
+ byte[] tmpBytes = new byte[4];
+ contentStream.readFully(tmpBytes);
+ int headerLen = PageChannel.wrap(tmpBytes).getInt();
+ contentStream.skipBytes(headerLen - 4);
+
+ // calculate actual data length and read it (note, header length
+ // includes the bytes for the length)
+ tmpBytes = new byte[dataLen - headerLen];
+ contentStream.readFully(tmpBytes);
+
+ return tmpBytes;
+
+ } finally {
+ if(contentStream != null) {
+ try {
+ contentStream.close();
+ } catch(IOException e) {
+ // ignored
+ }
+ }
+ }
+ }
+
+ /**
+ * Encodes the actual attachment file data to get the raw, stored format.
+ */
+ private byte[] encodeData() {
+ // FIXME, writeme
+ throw new UnsupportedOperationException();
+ }
}
-
+
}
diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
index 80735e3..170a92f 100644
--- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
+++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java
@@ -215,6 +215,24 @@ public class ComplexValueForeignKey extends Number
return a;
}
+ public Attachment addDecodedAttachment(byte[] decodedData)
+ throws IOException
+ {
+ return addDecodedAttachment(null, null, null, decodedData, null, null);
+ }
+
+ public Attachment addDecodedAttachment(
+ String url, String name, String type, byte[] decodedData,
+ Date timeStamp, Integer flags)
+ throws IOException
+ {
+ reset();
+ Attachment a = AttachmentColumnInfo.newDecodedAttachment(
+ this, url, name, type, decodedData, timeStamp, flags);
+ getAttachmentInfo().addValue(a);
+ return a;
+ }
+
public Attachment updateAttachment(Attachment attachment)
throws IOException
{