]> source.dussan.org Git - jackcess.git/commitdiff
apply patches from joniles, 1423965, 1427848 (handling var length columns)
authorJames Ahlborn <jtahlborn@yahoo.com>
Thu, 9 Mar 2006 02:00:28 +0000 (02:00 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Thu, 9 Mar 2006 02:00:28 +0000 (02:00 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@37 f203690c-595d-4dc9-a70b-905162fa7fd2

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

index a6c1519d63d5a31289c9ad6ef2e40fb0ac36b33c..250c3cf8223e0c27629f94fe3e1e61f368ab8eeb 100644 (file)
@@ -273,13 +273,13 @@ public class Column implements Comparable<Column> {
       return null;
     } else if (_type == DataType.OLE) {
       if (data.length > 0) {
-        return getLongValue(data);
+        return getLongBinaryValue(data);
       } else {
         return null;
       }
     } else if (_type == DataType.MEMO) {
       if (data.length > 0) {
-        return _format.CHARSET.decode(ByteBuffer.wrap(getLongValue(data))).toString();
+        return getLongStringValue(data);
       } else {
         return null;
       }
@@ -315,16 +315,21 @@ public class Column implements Comparable<Column> {
       throw new IOException("Unrecognized data type: " + _type);
     }
   }
-  
+
   /**
    * @param lvalDefinition Column value that points to an LVAL record
    * @return The LVAL data
    */
   @SuppressWarnings("fallthrough")
-  private byte[] getLongValue(byte[] lvalDefinition) throws IOException {
+  private byte[] getLongBinaryValue(byte[] lvalDefinition) throws IOException {
     ByteBuffer def = ByteBuffer.wrap(lvalDefinition);
     def.order(ByteOrder.LITTLE_ENDIAN);
     short length = def.getShort();
+    // bail out gracefully here as we don't understand the format
+    if (length < 0)
+    {
+       return null;
+    }
     byte[] rtn = new byte[length];
     short type = def.getShort();
     switch (type) {
@@ -354,6 +359,49 @@ public class Column implements Comparable<Column> {
     return rtn;
   }
   
+  /**
+   * @param lvalDefinition Column value that points to an LVAL record
+   * @return The LVAL data
+   */
+  @SuppressWarnings("fallthrough")
+  private String getLongStringValue(byte[] lvalDefinition) throws IOException {
+    ByteBuffer def = ByteBuffer.wrap(lvalDefinition);
+    def.order(ByteOrder.LITTLE_ENDIAN);
+    short length = def.getShort();
+    byte[] rtn = new byte[length];
+    short type = def.getShort();
+    String result;
+    switch (type) {
+      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);
+        }
+        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);        
+        result = _format.CHARSET.decode(ByteBuffer.wrap(rtn)).toString();
+        break;
+      case LONG_VALUE_TYPE_THIS_PAGE:
+        rtn = new byte[length-2];
+        def.position(14);
+        def.get(rtn);
+        result = new String(rtn);
+        break;
+      case LONG_VALUE_TYPE_OTHER_PAGES:
+        //XXX
+        return null;
+      default:
+        throw new IOException("Unrecognized long value type: " + type);
+    }
+    return result;
+  }
+  
   /**
    * Write an LVAL column into a ByteBuffer inline (LONG_VALUE_TYPE_THIS_PAGE)
    * @param value Value of the LVAL column
index a9a6944cf6a2d80de5415389bba8bf9ce05c2f9c..575d374d592e93ed55a4419a03bf6558c76600dc 100644 (file)
@@ -229,13 +229,20 @@ public class Table {
       if (column.getType() == DataType.BOOLEAN) {
         value = new Boolean(!isNull);  //Boolean values are stored in the null mask
       } else {
-        if (!column.isVariableLength()) {
+        if (!column.isVariableLength()) 
+        {
           //Read in fixed length column data
-          columnData = new byte[column.size()];
+          columnData = new byte[column.getLength()];
           _buffer.get(columnData);
-        } else if (!isNull) {
-          //Refer to already-read-in variable length data
-          columnData = varColumnData[varColumnDataIndex--];
+        } 
+        else
+        {
+           if (!isNull) 
+           {
+             //Refer to already-read-in variable length data
+             columnData = varColumnData[varColumnDataIndex];
+           }
+           --varColumnDataIndex;
         }
         if (!isNull && columnData != null &&
             (columnNames == null || columnNames.contains(column.getName())))