Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 50264 invoked from network); 14 Apr 2006 14:23:33 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 14 Apr 2006 14:23:33 -0000 Received: (qmail 57524 invoked by uid 500); 14 Apr 2006 14:23:29 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 57499 invoked by uid 500); 14 Apr 2006 14:23:29 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 57488 invoked by uid 99); 14 Apr 2006 14:23:29 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 14 Apr 2006 07:23:28 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Fri, 14 Apr 2006 07:23:28 -0700 Received: (qmail 49902 invoked by uid 65534); 14 Apr 2006 14:23:07 -0000 Message-ID: <20060414142307.49900.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r394109 - in /db/derby/code/trunk/java/engine/org/apache/derby/iapi/types: RawToBinaryFormatStream.java SQLBinary.java SQLBlob.java Date: Fri, 14 Apr 2006 14:23:05 -0000 To: derby-commits@db.apache.org From: djd@apache.org X-Mailer: svnmailer-1.0.7 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: djd Date: Fri Apr 14 07:23:03 2006 New Revision: 394109 URL: http://svn.apache.org/viewcvs?rev=394109&view=rev Log: DERBY-438 (partial) Ensure internal conversions of JDBC objects to BLOBs provide the conversion using RawToBinaryFormatStream from the raw binary stream to the on-disk format stream as required by the data type api. Make RawToBinaryFormatStream encode the length of the value in the first bytes as defined in the format described in SQLBinary. Ensure the code handles this encoded lenght correctly. Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/RawToBinaryFormatStream.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBlob.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/RawToBinaryFormatStream.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/RawToBinaryFormatStream.java?rev=394109&r1=394108&r2=394109&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/RawToBinaryFormatStream.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/RawToBinaryFormatStream.java Fri Apr 14 07:23:03 2006 @@ -31,13 +31,33 @@ /** Stream that takes a raw input stream and converts it to the on-disk format of the binary types by prepending the - length of the value. In this case 0 is always written. + length of the value. +

+ If the length of the stream is known then it is encoded + as the first bytes in the stream in the defined format. +
+ If the length is unknown then the first four bytes will + be zero, indicating unknown length. +
Note: This stream cannot be re-used. Once end of file is reached, the next read call will throw an EOFException + + @see SQLBinary */ -public class RawToBinaryFormatStream extends LimitInputStream { +public final class RawToBinaryFormatStream extends LimitInputStream { - private int dummyBytes = 4; + /** + * Number of bytes of length encoding. + * + */ + private int encodedOffset; + + /** + * Encoding of the length in bytes which will be + * seen as the first encodedLength.length bytes of + * this stream. + */ + private byte[] encodedLength; // flag to indicate the stream has already been read // and eof reached @@ -49,9 +69,37 @@ */ public RawToBinaryFormatStream(InputStream in, int length) { super(in); + if (length >= 0) { setLimit(length); + + if (length <= 31) + { + encodedLength = new byte[1]; + encodedLength[0] = (byte) (0x80 | (length & 0xff)); + } + else if (length <= 0xFFFF) + { + encodedLength = new byte[3]; + encodedLength[0] = (byte) 0xA0; + encodedLength[1] = (byte)(length >> 8); + encodedLength[2] = (byte)(length); + } + else + { + encodedLength = new byte[5]; + encodedLength[0] = (byte) 0xC0; + encodedLength[1] = (byte)(length >> 24); + encodedLength[2] = (byte)(length >> 16); + encodedLength[3] = (byte)(length >> 8); + encodedLength[4] = (byte)(length); + } } + else + { + // unknown length, four zero bytes + encodedLength = new byte[4]; + } } /** @@ -65,14 +113,13 @@ throw new EOFException(MessageService.getTextMessage (SQLState.STREAM_EOF)); - if (dummyBytes != 0) { - dummyBytes--; - return 0; - } + if (encodedOffset < encodedLength.length) { + return encodedLength[encodedOffset++] & 0xff; + } int ret = super.read(); - if (ret < 0) + if (ret == -1) checkSufficientData(); return ret; @@ -109,7 +156,7 @@ catch (IOException ioe) { c = -1; } - if (c >= 0) + if (c != -1) throw new IOException(MessageService.getTextMessage(SQLState.SET_STREAM_INEXACT_LENGTH_DATA)); } } @@ -124,31 +171,34 @@ if ( eof ) throw new EOFException(MessageService.getTextMessage(SQLState.STREAM_EOF)); - int dlen = dummyBytes; - - if (dlen != 0) { - if (len < dlen) - dlen = len; - for (int i = 0; i < dlen; i++) { - b[off+i] = 0; - } - dummyBytes -= dlen; + int elen = encodedLength.length - encodedOffset; - off += dlen; - len -= dlen; + if (elen != 0) { + if (len < elen) + elen = len; + System.arraycopy(encodedLength, encodedOffset, + b, off, elen); + + encodedOffset += elen; + + off += elen; + len -= elen; + + if (len == 0) + return elen; } int realRead = super.read(b, off, len); if (realRead < 0) { - if (dlen != 0) - return dlen; + if (elen != 0) + return elen; checkSufficientData(); return realRead; } - return dlen + realRead; + return elen + realRead; } } Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java?rev=394109&r1=394108&r2=394109&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java Fri Apr 14 07:23:03 2006 @@ -205,22 +205,14 @@ try { if ((dataValue == null) && (stream != null)) { - + if (stream instanceof FormatIdInputStream) { readExternal((FormatIdInputStream) stream); - } else if ( stream instanceof NewByteArrayInputStream ) - { - // this piece of code handles the case that a stream has been - // opened on the bit value. the stream will have already called - // readExternal() on the underlying FormatableBitSet. we just need to - // retrieve the byte array from that stream. - NewByteArrayInputStream nbais = (NewByteArrayInputStream) stream; - dataValue = nbais.getData(); } else { readExternal(new FormatIdInputStream(stream)); } - stream = null; + stream = null; streamValueLength = -1; } @@ -346,25 +338,28 @@ int bl = in.read(); if (bl == -1) throw new java.io.EOFException(); + + byte li = (byte) bl; int len; - if ((bl & 0x80) != 0) + if ((li & ((byte) 0x80)) != 0) { - if (bl == 0xC0) - { + if (li == ((byte) 0xC0)) + { len = in.readInt(); - } - else if (bl == 0xA0) + } + else if (li == ((byte) 0xA0)) { len = in.readUnsignedShort(); } else { - len = bl & 0x1F; + len = li & 0x1F; } } else { + // old length in bits int v2 = in.read(); int v3 = in.read(); @@ -376,7 +371,7 @@ len = lenInBits / 8; if ((lenInBits % 8) != 0) len++; - } + } return len; } Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBlob.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBlob.java?rev=394109&r1=394108&r2=394109&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBlob.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBlob.java Fri Apr 14 07:23:03 2006 @@ -164,14 +164,17 @@ * @see DataValueDescriptor#setValueFromResultSet * * @exception SQLException Thrown on error + * @throws StandardException */ public void setValueFromResultSet(ResultSet resultSet, int colNumber, boolean isNullable) - throws SQLException + throws SQLException, StandardException { - stream = resultSet.getBinaryStream(colNumber); - streamValueLength = -1; // unknown - dataValue = null; + Blob blob = resultSet.getBlob(colNumber); + if (blob == null) + setToNull(); + else + setObject(blob); } @@ -205,13 +208,19 @@ throws StandardException { Blob vb = (Blob) theValue; + try { - stream = vb.getBinaryStream(); + long vbl = vb.length(); + if (vbl < 0L || vbl > Integer.MAX_VALUE) + throw this.outOfRange(); + + setValue(new RawToBinaryFormatStream( + vb.getBinaryStream(), (int) vbl), + (int) vbl); + } catch (SQLException e) { throw dataTypeConversion("DAN-438-tmp"); } - streamValueLength = -1; // unknown - dataValue = null; } }