From: James Ahlborn Date: Fri, 14 Jun 2013 18:04:58 +0000 (+0000) Subject: make attachment decoding the default X-Git-Tag: jackcess-1.2.13~3 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0f29696f8db3fc38076a03d228006ad8d4a970df;p=jackcess.git make attachment decoding the default git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@735 f203690c-595d-4dc9-a70b-905162fa7fd2 --- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index d26c22d..a3e5c6f 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -13,8 +13,7 @@ Add more methods to Database for retrieving Relationships. - Add methods to get the actual attachment content, thanks to Lorenzo - Carrara. + Implement attachment decoding, thanks to Lorenzo Carrara. diff --git a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java index 18c361e..c569315 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java +++ b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java @@ -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(); diff --git a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java index 1d0595c..ec16d07 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java @@ -166,8 +166,8 @@ public class AttachmentColumnInfo extends ComplexColumnInfo 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 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 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 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 _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 */ 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 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 contentStream.write(typeBytes.array(), 0, typeBytes.remaining()); // write the _actual_ contents - contentStream.write(_decodedData); + contentStream.write(_data); contentStream.close(); contentStream = null; diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java index 13e6b7a..2e4b376 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java @@ -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; } diff --git a/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java b/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java index 2122b53..8fea667 100644 --- a/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/ComplexColumnTest.java @@ -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."); }