From b1defc16c3e31fe4334add5937401d653989a79a Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sat, 15 Mar 2008 20:30:37 +0000 Subject: [PATCH] refactor some common code for encoding/decoding uncompressed strings git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@277 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../healthmarketscience/jackcess/Column.java | 57 ++++++++++------- .../healthmarketscience/jackcess/Table.java | 62 +++++++++++++------ 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index 312c141..474cc54 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -907,7 +907,7 @@ public class Column implements Comparable { if (text.length() > maxChars) { throw new IOException("Text is too big for column"); } - byte[] encodedData = encodeUncompressedText(text).array(); + byte[] encodedData = encodeUncompressedText(text, getFormat()).array(); obj = encodedData; break; @@ -930,7 +930,7 @@ public class Column implements Comparable { // should already be "encoded" break; case MEMO: - obj = encodeUncompressedText(toCharSequence(obj)).array(); + obj = encodeUncompressedText(toCharSequence(obj), getFormat()).array(); break; default: throw new RuntimeException("unexpected var length, long value type: " + @@ -1046,7 +1046,7 @@ public class Column implements Comparable { } - return decodeUncompressedText(data); + return decodeUncompressedText(data, getFormat()); } catch (IllegalInputException e) { throw (IOException) @@ -1079,34 +1079,19 @@ public class Column implements Comparable { textBuf.append(expander.expand(tmpData)); } else { // handle uncompressed data - textBuf.append(decodeUncompressedText(data, dataStart, dataLength)); + textBuf.append(decodeUncompressedText(data, dataStart, dataLength, + getFormat())); } } - /** - * @param text Text to encode - * @return A buffer with the text encoded - */ - private ByteBuffer encodeUncompressedText(CharSequence text) { - return getFormat().CHARSET.encode(CharBuffer.wrap(text)); - } - - /** - * @param textBytes bytes of text to decode - * @return the decoded string - */ - private String decodeUncompressedText(byte[] textBytes) { - return decodeUncompressedText(textBytes, 0, textBytes.length).toString(); - } - /** * @param textBytes bytes of text to decode * @return the decoded string */ - private CharBuffer decodeUncompressedText(byte[] textBytes, int startPost, - int length) { - return getFormat().CHARSET.decode(ByteBuffer.wrap(textBytes, startPost, - length)); + private static CharBuffer decodeUncompressedText( + byte[] textBytes, int startPos, int length, JetFormat format) + { + return format.CHARSET.decode(ByteBuffer.wrap(textBytes, startPos, length)); } @Override @@ -1128,6 +1113,30 @@ public class Column implements Comparable { return rtn.toString(); } + /** + * @param textBytes bytes of text to decode + * @param format relevant db format + * @return the decoded string + */ + public static String decodeUncompressedText(byte[] textBytes, + JetFormat format) + { + return decodeUncompressedText(textBytes, 0, textBytes.length, format) + .toString(); + } + + /** + * @param text Text to encode + * @param format relevant db format + * @return A buffer with the text encoded + */ + public static ByteBuffer encodeUncompressedText(CharSequence text, + JetFormat format) + { + return format.CHARSET.encode(CharBuffer.wrap(text)); + } + + public int compareTo(Column other) { if (_columnNumber > other.getColumnNumber()) { return 1; diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java index 0c30d79..9f07f36 100644 --- a/src/java/com/healthmarketscience/jackcess/Table.java +++ b/src/java/com/healthmarketscience/jackcess/Table.java @@ -842,12 +842,23 @@ public class Table } } for (Column col : columns) { - ByteBuffer colName = format.CHARSET.encode(col.getName()); - buffer.putShort((short) colName.remaining()); - buffer.put(colName); + writeName(buffer, col.getName(), format); } } + /** + * Writes the given name into the given buffer in the format as expected by + * {@link #readName}. + */ + private static void writeName(ByteBuffer buffer, String name, + JetFormat format) + { + ByteBuffer encName = Column.encodeUncompressedText( + name, format); + buffer.putShort((short) encName.remaining()); + buffer.put(encName); + } + /** * Constructs a byte containing the flags for the given column. */ @@ -936,11 +947,11 @@ public class Table i * getFormat().SIZE_INDEX_DEFINITION + 4)); } - int offset = getFormat().OFFSET_INDEX_DEF_BLOCK + + int colOffset = getFormat().OFFSET_INDEX_DEF_BLOCK + _indexCount * getFormat().SIZE_INDEX_DEFINITION; for (int i = 0; i < columnCount; i++) { Column column = new Column(this, tableBuffer, - offset + i * getFormat().SIZE_COLUMN_HEADER); + colOffset + (i * getFormat().SIZE_COLUMN_HEADER)); _columns.add(column); if(column.isVariableLength()) { // also shove it in the variable columns list, which is ordered @@ -948,16 +959,11 @@ public class Table _varColumns.add(column); } } - offset += columnCount * getFormat().SIZE_COLUMN_HEADER; + tableBuffer.position(colOffset + + (columnCount * getFormat().SIZE_COLUMN_HEADER)); for (int i = 0; i < columnCount; i++) { Column column = _columns.get(i); - short nameLength = tableBuffer.getShort(offset); - offset += 2; - byte[] nameBytes = new byte[nameLength]; - tableBuffer.position(offset); - tableBuffer.get(nameBytes, 0, nameLength); - column.setName(getFormat().CHARSET.decode(ByteBuffer.wrap(nameBytes)).toString()); - offset += nameLength; + column.setName(readName(tableBuffer)); } Collections.sort(_columns); @@ -1000,20 +1006,15 @@ public class Table // read actual index names for (int i = 0; i < _indexSlotCount; i++) { - int nameLen = tableBuffer.getShort(); - if(i < firstRealIdx) { // for each empty index slot, there is some weird sort of name, skip // it - tableBuffer.position(tableBuffer.position() + nameLen); + skipName(tableBuffer); continue; } - byte[] nameBytes = new byte[nameLen]; - tableBuffer.get(nameBytes); _indexes.get(i - firstRealIdx) - .setName(getFormat().CHARSET.decode( - ByteBuffer.wrap(nameBytes)).toString()); + .setName(readName(tableBuffer)); } int idxEndOffset = tableBuffer.position(); @@ -1045,6 +1046,27 @@ public class Table ++_modCount; } + /** + * Returns a name read from the buffer at the current position. The + * expected name format is the name length as a short followed by (length * + * 2) bytes encoded using the {@link JetFormat#CHARSET} + */ + private String readName(ByteBuffer buffer) { + short nameLength = buffer.getShort(); + byte[] nameBytes = new byte[nameLength]; + buffer.get(nameBytes); + return Column.decodeUncompressedText(nameBytes, getFormat()); + } + + /** + * Skips past a name int the buffer at the current position. The + * expected name format is the same as that for {@link #readName}. + */ + private void skipName(ByteBuffer buffer) { + short nameLength = buffer.getShort(); + buffer.position(buffer.position() + nameLength); + } + /** * Converts a map of columnName -> columnValue to an array of row values * appropriate for a call to {@link #addRow(Object...)}. -- 2.39.5