aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2013-07-27 03:02:06 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2013-07-27 03:02:06 +0000
commit286c6b06b5965daf1a33db2d0cf4e22c6c2cc758 (patch)
tree4afaa71e40e29226a4097d4033c24938249039af
parent77daac9f4b313c2f7c9617549f04a95786d59daf (diff)
downloadjackcess-286c6b06b5965daf1a33db2d0cf4e22c6c2cc758.tar.gz
jackcess-286c6b06b5965daf1a33db2d0cf4e22c6c2cc758.zip
enhance CodecHandler to better support impls which cannot decode pages inline
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/jackcess-2@753 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r--src/java/com/healthmarketscience/jackcess/impl/CodecHandler.java16
-rw-r--r--src/java/com/healthmarketscience/jackcess/impl/DefaultCodecProvider.java18
-rw-r--r--src/java/com/healthmarketscience/jackcess/impl/PageChannel.java28
-rw-r--r--test/src/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java22
4 files changed, 69 insertions, 15 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/impl/CodecHandler.java b/src/java/com/healthmarketscience/jackcess/impl/CodecHandler.java
index fd71f5d..944ac08 100644
--- a/src/java/com/healthmarketscience/jackcess/impl/CodecHandler.java
+++ b/src/java/com/healthmarketscience/jackcess/impl/CodecHandler.java
@@ -39,14 +39,24 @@ public interface CodecHandler
public boolean canEncodePartialPage();
/**
- * Decodes the given page buffer inline.
+ * Returns {@code true} if this handler can decode a page inline,
+ * {@code false} otherwise. If this method returns {@code false}, the
+ * {@link #decodePage} method will always be called with separate buffers.
+ */
+ public boolean canDecodeInline();
+
+ /**
+ * Decodes the given page buffer.
*
- * @param page the page to be decoded
+ * @param inPage the page to be decoded
+ * @param outPage the decoded page. if {@link #canDecodeInline} is {@code
+ * true}, this will be the same buffer as inPage.
* @param pageNumber the page number of the given page
*
* @throws IOException if an exception occurs during decoding
*/
- public void decodePage(ByteBuffer page, int pageNumber) throws IOException;
+ public void decodePage(ByteBuffer inPage, ByteBuffer outPage, int pageNumber)
+ throws IOException;
/**
* Encodes the given page buffer into a new page buffer and returns it. The
diff --git a/src/java/com/healthmarketscience/jackcess/impl/DefaultCodecProvider.java b/src/java/com/healthmarketscience/jackcess/impl/DefaultCodecProvider.java
index 1c08687..0e1de8f 100644
--- a/src/java/com/healthmarketscience/jackcess/impl/DefaultCodecProvider.java
+++ b/src/java/com/healthmarketscience/jackcess/impl/DefaultCodecProvider.java
@@ -87,7 +87,14 @@ public class DefaultCodecProvider implements CodecProvider
return true;
}
- public void decodePage(ByteBuffer page, int pageNumber) throws IOException {
+ public boolean canDecodeInline() {
+ return true;
+ }
+
+ public void decodePage(ByteBuffer inPage, ByteBuffer outPage,
+ int pageNumber)
+ throws IOException
+ {
// does nothing
}
@@ -111,7 +118,14 @@ public class DefaultCodecProvider implements CodecProvider
return true;
}
- public void decodePage(ByteBuffer page, int pageNumber) throws IOException {
+ public boolean canDecodeInline() {
+ return true;
+ }
+
+ public void decodePage(ByteBuffer inPage, ByteBuffer outPage,
+ int pageNumber)
+ throws IOException
+ {
throw new UnsupportedCodecException("Decoding not supported. Please choose a CodecProvider which supports reading the current database encoding.");
}
diff --git a/src/java/com/healthmarketscience/jackcess/impl/PageChannel.java b/src/java/com/healthmarketscience/jackcess/impl/PageChannel.java
index 2ea9d27..89e952d 100644
--- a/src/java/com/healthmarketscience/jackcess/impl/PageChannel.java
+++ b/src/java/com/healthmarketscience/jackcess/impl/PageChannel.java
@@ -79,8 +79,8 @@ public class PageChannel implements Channel, Flushable {
/** handler for the current database encoding type */
private CodecHandler _codecHandler = DefaultCodecProvider.DUMMY_HANDLER;
/** temp page buffer used when pages cannot be partially encoded */
- private final TempPageHolder _fullPageEncodeBufferH =
- TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
+ private TempPageHolder _fullPageEncodeBufferH;
+ private TempBufferHolder _tempDecodeBufferH;
private int _writeCount;
/**
@@ -118,6 +118,14 @@ public class PageChannel implements Channel, Flushable {
{
// initialize page en/decoding support
_codecHandler = codecProvider.createHandler(this, database.getCharset());
+ if(!_codecHandler.canEncodePartialPage()) {
+ _fullPageEncodeBufferH =
+ TempPageHolder.newHolder(TempBufferHolder.Type.SOFT);
+ }
+ if(!_codecHandler.canDecodeInline()) {
+ _tempDecodeBufferH = TempBufferHolder.newHolder(
+ TempBufferHolder.Type.SOFT, true);
+ }
// note the global usage map is a special map where any page outside of
// the current range is assumed to be "on"
@@ -206,10 +214,18 @@ public class PageChannel implements Channel, Flushable {
throws IOException
{
validatePageNumber(pageNumber);
- buffer.clear();
+
+ ByteBuffer inPage = buffer;
+ ByteBuffer outPage = buffer;
+ if((pageNumber != 0) && !_codecHandler.canDecodeInline()) {
+ inPage = _tempDecodeBufferH.getPageBuffer(this);
+ outPage.clear();
+ }
+
+ inPage.clear();
int bytesRead = _channel.read(
- buffer, (long) pageNumber * (long) getFormat().PAGE_SIZE);
- buffer.flip();
+ inPage, (long) pageNumber * (long) getFormat().PAGE_SIZE);
+ inPage.flip();
if(bytesRead != getFormat().PAGE_SIZE) {
throw new IOException("Failed attempting to read " +
getFormat().PAGE_SIZE + " bytes from page " +
@@ -220,7 +236,7 @@ public class PageChannel implements Channel, Flushable {
// de-mask header (note, page 0 never has additional encoding)
applyHeaderMask(buffer);
} else {
- _codecHandler.decodePage(buffer, pageNumber);
+ _codecHandler.decodePage(inPage, outPage, pageNumber);
}
}
diff --git a/test/src/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java b/test/src/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
index e3cf499..47a832a 100644
--- a/test/src/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
+++ b/test/src/java/com/healthmarketscience/jackcess/impl/CodecHandlerTest.java
@@ -236,9 +236,16 @@ public class CodecHandlerTest extends TestCase
public boolean canEncodePartialPage() {
return true;
}
+
+ public boolean canDecodeInline() {
+ return true;
+ }
- public void decodePage(ByteBuffer page, int pageNumber) throws IOException {
- byte[] arr = page.array();
+ public void decodePage(ByteBuffer inPage, ByteBuffer outPage,
+ int pageNumber)
+ throws IOException
+ {
+ byte[] arr = inPage.array();
simpleDecode(arr, arr, pageNumber);
}
@@ -267,9 +274,16 @@ public class CodecHandlerTest extends TestCase
public boolean canEncodePartialPage() {
return false;
}
+
+ public boolean canDecodeInline() {
+ return true;
+ }
- public void decodePage(ByteBuffer page, int pageNumber) throws IOException {
- byte[] arr = page.array();
+ public void decodePage(ByteBuffer inPage, ByteBuffer outPage,
+ int pageNumber)
+ throws IOException
+ {
+ byte[] arr = inPage.array();
fullDecode(arr, arr, pageNumber);
}