]> source.dussan.org Git - jackcess.git/commitdiff
implement reading multi-page long binary values
authorJames Ahlborn <jtahlborn@yahoo.com>
Thu, 3 Aug 2006 19:57:50 +0000 (19:57 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Thu, 3 Aug 2006 19:57:50 +0000 (19:57 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@86 f203690c-595d-4dc9-a70b-905162fa7fd2

src/java/com/healthmarketscience/jackcess/Column.java

index a15bdc167678c6e263593650cf13e3cf6455311a..ac405889fe21956074322bc4224c7f534bc88738 100644 (file)
@@ -315,25 +315,75 @@ public class Column implements Comparable<Column> {
       case LONG_VALUE_TYPE_OTHER_PAGE:
         if (lvalDefinition.length != _format.SIZE_LONG_VALUE_DEF) {
           throw new IOException("Expected " + _format.SIZE_LONG_VALUE_DEF +
-              " bytes in long value definition, but found " + lvalDefinition.length);
+              " bytes in long value definition, but found " +
+                                lvalDefinition.length);
+        }
+
+        {
+          byte rowNum = def.get();
+          int pageNum = ByteUtil.get3ByteInt(def, def.position());
+          ByteBuffer lvalPage = _pageChannel.createPageBuffer();
+          _pageChannel.readPage(lvalPage, pageNum);
+
+          short rowStart = Table.findRowStart(lvalPage, rowNum, _format);
+          short rowEnd = Table.findRowEnd(lvalPage, rowNum, _format);
+
+          if((rowEnd - rowStart) != length) {
+            throw new IOException("Unexpected lval row length");
+          }
+        
+          lvalPage.position(rowStart);
+          lvalPage.get(rtn);
         }
-        byte rowNum = def.get();
-        int pageNum = ByteUtil.get3ByteInt(def, def.position());
-        ByteBuffer lvalPage = _pageChannel.createPageBuffer();
-        _pageChannel.readPage(lvalPage, pageNum);
-        short offset = lvalPage.getShort(14 +
-            rowNum * _format.SIZE_ROW_LOCATION);
-        lvalPage.position(offset);
-        lvalPage.get(rtn);
         break;
+        
       case LONG_VALUE_TYPE_THIS_PAGE:
         def.getInt();  //Skip over lval_dp
         def.getInt();  //Skip over unknown
         def.get(rtn);
         break;
+        
       case LONG_VALUE_TYPE_OTHER_PAGES:
-        //XXX
-        return null;
+
+        ByteBuffer rtnBuf = ByteBuffer.wrap(rtn);
+        
+        if (lvalDefinition.length != _format.SIZE_LONG_VALUE_DEF) {
+          throw new IOException("Expected " + _format.SIZE_LONG_VALUE_DEF +
+              " bytes in long value definition, but found " +
+                                lvalDefinition.length);
+        }
+        byte rowNum = def.get();
+        int pageNum = ByteUtil.get3ByteInt(def, def.position());
+        ByteBuffer lvalPage = _pageChannel.createPageBuffer();
+
+        int remainingLen = length;
+        while(remainingLen > 0) {
+          lvalPage.clear();
+          _pageChannel.readPage(lvalPage, pageNum);
+
+          short rowStart = Table.findRowStart(lvalPage, rowNum, _format);
+          short rowEnd = Table.findRowEnd(lvalPage, rowNum, _format);
+
+          
+          // read next page information
+          lvalPage.position(rowStart);
+          rowNum = lvalPage.get();
+          pageNum = ByteUtil.get3ByteInt(lvalPage);
+
+          // update rowEnd and remainingLen based on chunkLength
+          int chunkLength = (rowEnd - rowStart) - 4;
+          if(chunkLength > remainingLen) {
+            rowEnd = (short)(rowEnd - (chunkLength - remainingLen));
+            chunkLength = remainingLen;
+          }
+          remainingLen -= chunkLength;
+          
+          lvalPage.limit(rowEnd);
+          rtnBuf.put(lvalPage);
+        }
+        
+        break;
+        
       default:
         throw new IOException("Unrecognized long value type: " + type);
     }