Browse Source

make attachment decoding the default

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@735 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-1.2.13
James Ahlborn 11 years ago
parent
commit
0f29696f8d

+ 1
- 2
src/changes/changes.xml View File

@@ -13,8 +13,7 @@
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.
Implement attachment decoding, thanks to Lorenzo Carrara.
</action>
</release>
<release version="1.2.12" date="2013-05-09">

+ 2
- 2
src/java/com/healthmarketscience/jackcess/complex/Attachment.java View File

@@ -33,9 +33,9 @@ public interface Attachment extends ComplexValue

public void setFileData(byte[] data);

public byte[] getDecodedFileData() throws IOException;
public byte[] getEncodedFileData() throws IOException;

public void setDecodedFileData(byte[] data);
public void setEncodedFileData(byte[] data);

public String getFileName();


+ 33
- 32
src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java View File

@@ -166,8 +166,8 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
Date ts = (Date)getFileTimeStampColumn().getRowValue(rawValue);
byte[] data = (byte[])getFileDataColumn().getRowValue(rawValue);
return new AttachmentImpl(id, complexValueFk, url, name, type, data,
ts, flags, null);
return new AttachmentImpl(id, complexValueFk, url, name, type, null,
ts, flags, data);
}

@Override
@@ -180,7 +180,7 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
getFileTypeColumn().setRowValue(row, attachment.getFileType());
getFileFlagsColumn().setRowValue(row, attachment.getFileFlags());
getFileTimeStampColumn().setRowValue(row, attachment.getFileTimeStamp());
getFileDataColumn().setRowValue(row, attachment.getFileData());
getFileDataColumn().setRowValue(row, attachment.getEncodedFileData());
return row;
}

@@ -209,30 +209,30 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
data, timeStamp, flags, null);
}

public static Attachment newDecodedAttachment(byte[] decodedData) {
return newDecodedAttachment(INVALID_COMPLEX_VALUE_ID, decodedData);
public static Attachment newEncodedAttachment(byte[] encodedData) {
return newEncodedAttachment(INVALID_COMPLEX_VALUE_ID, encodedData);
}
public static Attachment newDecodedAttachment(
ComplexValueForeignKey complexValueFk, byte[] decodedData) {
return newDecodedAttachment(complexValueFk, null, null, null, decodedData,
public static Attachment newEncodedAttachment(
ComplexValueForeignKey complexValueFk, byte[] encodedData) {
return newEncodedAttachment(complexValueFk, null, null, null, encodedData,
null, null);
}

public static Attachment newDecodedAttachment(
String url, String name, String type, byte[] decodedData,
public static Attachment newEncodedAttachment(
String url, String name, String type, byte[] encodedData,
Date timeStamp, Integer flags)
{
return newDecodedAttachment(INVALID_COMPLEX_VALUE_ID, url, name, type,
decodedData, timeStamp, flags);
return newEncodedAttachment(INVALID_COMPLEX_VALUE_ID, url, name, type,
encodedData, timeStamp, flags);
}
public static Attachment newDecodedAttachment(
public static Attachment newEncodedAttachment(
ComplexValueForeignKey complexValueFk, String url, String name,
String type, byte[] decodedData, Date timeStamp, Integer flags)
String type, byte[] encodedData, Date timeStamp, Integer flags)
{
return new AttachmentImpl(INVALID_ID, complexValueFk, url, name, type,
null, timeStamp, flags, decodedData);
null, timeStamp, flags, encodedData);
}

@@ -288,11 +288,11 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
private byte[] _data;
private Date _timeStamp;
private Integer _flags;
private byte[] _decodedData;
private byte[] _encodedData;

private AttachmentImpl(int id, ComplexValueForeignKey complexValueFk,
String url, String name, String type, byte[] data,
Date timeStamp, Integer flags, byte[] decodedData)
Date timeStamp, Integer flags, byte[] encodedData)
{
super(id, complexValueFk);
_url = url;
@@ -301,30 +301,30 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
_data = data;
_timeStamp = timeStamp;
_flags = flags;
_decodedData = decodedData;
_encodedData = encodedData;
}
public byte[] getFileData() throws IOException {
if((_data == null) && (_decodedData != null)) {
_data = encodeData();
if((_data == null) && (_encodedData != null)) {
_data = decodeData();
}
return _data;
}

public void setFileData(byte[] data) {
_data = data;
_decodedData = null;
_encodedData = null;
}

public byte[] getDecodedFileData() throws IOException {
if((_decodedData == null) && (_data != null)) {
_decodedData = decodeData();
public byte[] getEncodedFileData() throws IOException {
if((_encodedData == null) && (_data != null)) {
_encodedData = encodeData();
}
return _decodedData;
return _encodedData;
}

public void setDecodedFileData(byte[] data) {
_decodedData = data;
public void setEncodedFileData(byte[] data) {
_encodedData = data;
_data = null;
}

@@ -397,20 +397,21 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
*/
private byte[] decodeData() throws IOException {

if(_data.length < WRAPPER_HEADER_SIZE) {
if(_encodedData.length < WRAPPER_HEADER_SIZE) {
// nothing we can do
throw new IOException("Unknown encoded attachment data format");
}

// read initial header info
ByteBuffer bb = PageChannel.wrap(_data);
ByteBuffer bb = PageChannel.wrap(_encodedData);
int typeFlag = bb.getInt();
int dataLen = bb.getInt();

DataInputStream contentStream = null;
try {
InputStream bin = new ByteArrayInputStream(
_data, WRAPPER_HEADER_SIZE, _data.length - WRAPPER_HEADER_SIZE);
_encodedData, WRAPPER_HEADER_SIZE,
_encodedData.length - WRAPPER_HEADER_SIZE);

if(typeFlag == DATA_TYPE_RAW) {
// nothing else to do
@@ -465,7 +466,7 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
type, JetFormat.VERSION_12.CHARSET);
int headerLen = typeBytes.remaining() + CONTENT_HEADER_SIZE;

int dataLen = _decodedData.length;
int dataLen = _data.length;
ByteUtil.ByteStream dataStream = new ByteUtil.ByteStream(
WRAPPER_HEADER_SIZE + headerLen + dataLen);

@@ -494,7 +495,7 @@ public class AttachmentColumnInfo extends ComplexColumnInfo<Attachment>
contentStream.write(typeBytes.array(), 0, typeBytes.remaining());

// write the _actual_ contents
contentStream.write(_decodedData);
contentStream.write(_data);
contentStream.close();
contentStream = null;


+ 6
- 6
src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java View File

@@ -215,20 +215,20 @@ public class ComplexValueForeignKey extends Number
return a;
}

public Attachment addDecodedAttachment(byte[] decodedData)
public Attachment addEncodedAttachment(byte[] encodedData)
throws IOException
{
return addDecodedAttachment(null, null, null, decodedData, null, null);
return addEncodedAttachment(null, null, null, encodedData, null, null);
}
public Attachment addDecodedAttachment(
String url, String name, String type, byte[] decodedData,
public Attachment addEncodedAttachment(
String url, String name, String type, byte[] encodedData,
Date timeStamp, Integer flags)
throws IOException
{
reset();
Attachment a = AttachmentColumnInfo.newDecodedAttachment(
this, url, name, type, decodedData, timeStamp, flags);
Attachment a = AttachmentColumnInfo.newEncodedAttachment(
this, url, name, type, encodedData, timeStamp, flags);
getAttachmentInfo().addValue(a);
return a;
}

+ 22
- 16
test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java View File

@@ -19,6 +19,7 @@ USA

package com.healthmarketscience.jackcess;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -189,8 +190,8 @@ public class ComplexColumnTest extends TestCase
row8ValFk.addAttachment(null, "test_data.txt", "txt",
getFileBytes("test_data.txt"), null, null);
checkAttachments(row8ValFk.get(), row8ValFk, "test_data.txt");
row8ValFk.addDecodedAttachment(null, "test_data2.txt", "txt",
getDecodedFileBytes("test_data2.txt"), null,
row8ValFk.addEncodedAttachment(null, "test_data2.txt", "txt",
getEncodedFileBytes("test_data2.txt"), null,
null);
checkAttachments(row8ValFk.get(), row8ValFk, "test_data.txt",
"test_data2.txt");
@@ -204,17 +205,22 @@ public class ComplexColumnTest extends TestCase
null);
checkAttachments(4, row4ValFk, "test_data2.txt", "test_data.txt");

a.setFileType("xml");
a.setFileName("some_data.xml");
byte[] newBytes = "this is not xml".getBytes("US-ASCII");
a.setFileType("zip");
a.setFileName("some_data.zip");
byte[] newBytes = "this is not a zip file".getBytes("US-ASCII");
a.setFileData(newBytes);
a.update();

Attachment updated = row4ValFk.getAttachments().get(1);
assertNotSame(updated, a);
assertEquals("xml", updated.getFileType());
assertEquals("some_data.xml", updated.getFileName());
assertEquals("zip", updated.getFileType());
assertEquals("some_data.zip", updated.getFileName());
assertTrue(Arrays.equals(newBytes, updated.getFileData()));
byte[] encBytes = updated.getEncodedFileData();
assertEquals(newBytes.length + 28, encBytes.length);
ByteBuffer bb = PageChannel.wrap(encBytes);
assertEquals(0, bb.getInt());
assertTrue(ByteUtil.matchesRange(bb, 28, newBytes));

updated.delete();
checkAttachments(4, row4ValFk, "test_data2.txt");
@@ -376,8 +382,8 @@ public class ComplexColumnTest extends TestCase
assertEquals(fname, a.getFileName());
assertEquals("txt", a.getFileType());
assertTrue(Arrays.equals(getFileBytes(fname), a.getFileData()));
assertTrue(Arrays.equals(getDecodedFileBytes(fname),
a.getDecodedFileData()));
assertTrue(Arrays.equals(getEncodedFileBytes(fname),
a.getEncodedFileData()));
}
}
}
@@ -436,13 +442,13 @@ public class ComplexColumnTest extends TestCase
throw new RuntimeException("unexpected bytes");
}
private static byte[] getDecodedFileBytes(String fname) throws Exception
private static byte[] getEncodedFileBytes(String fname) throws Exception
{
if("test_data.txt".equals(fname)) {
return TEST_DEC_BYTES;
return TEST_ENC_BYTES;
}
if("test_data2.txt".equals(fname)) {
return TEST2_DEC_BYTES;
return TEST2_ENC_BYTES;
}
throw new RuntimeException("unexpected bytes");
}
@@ -457,20 +463,20 @@ public class ComplexColumnTest extends TestCase
}
}
private static final byte[] TEST_BYTES = new byte[] {
private static final byte[] TEST_ENC_BYTES = new byte[] {
b(0x01),b(0x00),b(0x00),b(0x00),b(0x3A),b(0x00),b(0x00),b(0x00),b(0x78),b(0x5E),b(0x13),b(0x61),b(0x60),b(0x60),b(0x60),b(0x04),b(0x62),b(0x16),b(0x20),b(0x2E),b(0x61),b(0xA8),b(0x00),b(0x62),
b(0x20),b(0x9D),b(0x91),b(0x59),b(0xAC),b(0x00),b(0x44),b(0xC5),b(0xF9),b(0xB9),b(0xA9),b(0x0A),b(0x25),b(0xA9),b(0xC5),b(0x25),b(0x0A),b(0x29),b(0x89),b(0x25),b(0x89),b(0x0A),b(0x69),b(0xF9),
b(0x45),b(0x0A),b(0x89),b(0x25),b(0x25),b(0x89),b(0xC9),b(0x19),b(0xB9),b(0xA9),b(0x79),b(0x25),b(0x7A),b(0x00),b(0x52),b(0xA9),b(0x0F),b(0x7A)
};

private static final byte[] TEST_DEC_BYTES = getAsciiBytes("this is some test data for attachment.");
private static final byte[] TEST_BYTES = getAsciiBytes("this is some test data for attachment.");
private static final byte[] TEST2_BYTES = new byte[] {
private static final byte[] TEST2_ENC_BYTES = new byte[] {
b(0x01),b(0x00),b(0x00),b(0x00),b(0x3F),b(0x00),b(0x00),b(0x00),b(0x78),b(0x5E),b(0x13),b(0x61),b(0x60),b(0x60),b(0x60),b(0x04),b(0x62),b(0x16),b(0x20),b(0x2E),b(0x61),b(0xA8),b(0x00),b(0x62),
b(0x20),b(0x9D),b(0x91),b(0x59),b(0xAC),b(0x00),b(0x44),b(0xC5),b(0xF9),b(0xB9),b(0xA9),b(0x0A),b(0xB9),b(0xF9),b(0x45),b(0xA9),b(0x0A),b(0x25),b(0xA9),b(0xC5),b(0x25),b(0x0A),b(0x29),b(0x89),
b(0x25),b(0x89),b(0x0A),b(0x69),b(0xF9),b(0x45),b(0x0A),b(0x89),b(0x25),b(0x25),b(0x89),b(0xC9),b(0x19),b(0xB9),b(0xA9),b(0x79),b(0x25),b(0x7A),b(0x00),b(0xA5),b(0x0B),b(0x11),b(0x4D)
};

private static final byte[] TEST2_DEC_BYTES = getAsciiBytes("this is some more test data for attachment.");
private static final byte[] TEST2_BYTES = getAsciiBytes("this is some more test data for attachment.");
}

Loading…
Cancel
Save