src/share/classes/javax/sql/rowset/serial/SerialBlob.java
Print this page
@@ -79,10 +79,12 @@
* array of bytes when it was first established.
* @serial
*/
private long origLen;
+ private boolean isFree = false;
+
/**
* Constructs a <code>SerialBlob</code> object that is a serialized version of
* the given <code>byte</code> array.
* <p>
* The new <code>SerialBlob</code> object is initialized with the data from the
@@ -158,12 +160,15 @@
* @param length the number of bytes to be copied
* @return an array of bytes that is a copy of a region of this
* <code>SerialBlob</code> object, starting at the given
* position and containing the given number of consecutive bytes
* @throws SerialException if the given starting position is out of bounds
+ * or called after free() has been called.
*/
public byte[] getBytes(long pos, int length) throws SerialException {
+ isFreed();
+
if (length > len) {
length = (int)len;
}
if (pos < 1 || len - pos < 0 ) {
@@ -186,13 +191,14 @@
* Retrieves the number of bytes in this <code>SerialBlob</code>
* object's array of bytes.
*
* @return a <code>long</code> indicating the length in bytes of this
* <code>SerialBlob</code> object's array of bytes
- * @throws SerialException if an error occurs
+ * @throws SerialException if an error occurs or called after free() has been called.
*/
public long length() throws SerialException {
+ isFreed();
return len;
}
/**
* Returns this <code>SerialBlob</code> object as an input stream.
@@ -200,14 +206,17 @@
* a stream is produced regardless of whether the <code>SerialBlob</code>
* was created with a <code>Blob</code> object or a <code>byte</code> array.
*
* @return a <code>java.io.InputStream</code> object that contains
* this <code>SerialBlob</code> object's array of bytes
- * @throws SerialException if an error occurs
+ * @throws SerialException if an error occurs or called after free() has
+ * been called.
* @see #setBinaryStream
*/
public java.io.InputStream getBinaryStream() throws SerialException {
+ isFreed();
+
InputStream stream = new ByteArrayInputStream(buf);
return stream;
}
/**
@@ -224,16 +233,19 @@
* @return the position in this <code>SerialBlob</code> object
* where the given pattern begins, starting at the specified
* position; <code>-1</code> if the pattern is not found
* or the given starting position is out of bounds; position
* numbering for the return value starts at <code>1</code>
- * @throws SerialException if an error occurs when serializing the blob
+ * @throws SerialException if an error occurs when serializing the blob or
+ * called after free() has been called.
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database
*/
public long position(byte[] pattern, long start)
throws SerialException, SQLException {
+ isFreed();
+
if (start < 1 || start > len) {
return -1;
}
int pos = (int)start-1; // internally Blobs are stored as arrays.
@@ -267,16 +279,18 @@
* @return the position in this <code>SerialBlob</code> object
* where the given <code>Blob</code> object begins, starting
* at the specified position; <code>-1</code> if the pattern is
* not found or the given starting position is out of bounds;
* position numbering for the return value starts at <code>1</code>
- * @throws SerialException if an error occurs when serializing the blob
+ * @throws SerialException if an error occurs when serializing the blob or
+ * called after free() has been called.
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database
*/
public long position(Blob pattern, long start)
throws SerialException, SQLException {
+ isFreed();
return position(pattern.getBytes(1, (int)(pattern.length())), start);
}
/**
* Writes the given array of bytes to the <code>BLOB</code> value that
@@ -290,17 +304,18 @@
* @param bytes the array of bytes to be written to the <code>BLOB</code>
* value that this <code>Blob</code> object represents
* @return the number of bytes written
* @throws SerialException if there is an error accessing the
* <code>BLOB</code> value; or if an invalid position is set; if an
- * invalid offset value is set
+ * invalid offset value is set or called after free() has been called.
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database
* @see #getBytes
*/
public int setBytes(long pos, byte[] bytes)
throws SerialException, SQLException {
+ isFreed();
return (setBytes(pos, bytes, 0, bytes.length));
}
/**
* Writes all or part of the given <code>byte</code> array to the
@@ -325,17 +340,19 @@
* @return the number of bytes written
* @throws SerialException if there is an error accessing the
* <code>BLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialBlob</code> length; or the combined
- * values of the length and offset is greater than the Blob buffer
+ * values of the length and offset is greater than the Blob buffer or
+ * called after free() has been called.
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* value from the database.
* @see #getBytes
*/
public int setBytes(long pos, byte[] bytes, int offset, int length)
throws SerialException, SQLException {
+ isFreed();
if (offset < 0 || offset > bytes.length) {
throw new SerialException("Invalid offset in byte array set");
}
@@ -376,14 +393,17 @@
* be written
* @throws SQLException if there is an error accessing the
* <code>BLOB</code> value
* @throws SerialException if the SerialBlob in not instantiated with a
* <code>Blob</code> object that supports <code>setBinaryStream()</code>
+ * or called after free() has been called.
* @see #getBinaryStream
*/
public java.io.OutputStream setBinaryStream(long pos)
throws SerialException, SQLException {
+ isFreed();
+
if (this.blob != null) {
return this.blob.setBinaryStream(pos);
} else {
throw new SerialException("Unsupported operation. SerialBlob cannot " +
"return a writable binary stream, unless instantiated with a Blob object " +
@@ -397,13 +417,15 @@
*
* @param length the length, in bytes, to which the <code>BLOB</code>
* value that this <code>Blob</code> object represents should be
* truncated
* @throws SerialException if there is an error accessing the Blob value;
- * or the length to truncate is greater that the SerialBlob length
+ * or the length to truncate is greater that the SerialBlob length or
+ * called after free() has been called.
*/
public void truncate(long length) throws SerialException {
+ isFreed();
if (length > len) {
throw new SerialException
("Length more than what can be truncated");
} else if((int)length == 0) {
@@ -422,34 +444,68 @@
*
* @param pos the offset to the first byte of the partial value to be retrieved.
* The first byte in the <code>Blob</code> is at position 1
* @param length the length in bytes of the partial value to be retrieved
* @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
+ * @throws SerialException if called after free() has been called.
* @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
* in the <code>Blob</code> or if pos + length is greater than the number of bytes
* in the <code>Blob</code>
*
* @since 1.6
*/
- public InputStream getBinaryStream(long pos,long length) throws SQLException {
- throw new java.lang.UnsupportedOperationException("Not supported");
+ public InputStream getBinaryStream(long pos,long length) throws SerialException, SQLException {
+ isFreed();
+
+ if (pos < 1 || pos > len) {
+ throw new SerialException("Invalid pos in getBinaryStream");
+ }
+ if ((pos - 1) + length > len) {
+ throw new SerialException(
+ "pos + length greater than total number of bytes");
+ }
+ return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
}
/**
- * This method frees the <code>Blob</code> object and releases the resources that it holds.
- * <code>Blob</code> object. The object is invalid once the <code>free</code>
- * method is called. If <code>free</code> is called multiple times, the subsequent
- * calls to <code>free</code> are treated as a no-op.
+ * This method frees the <code>Blob</code> object and releases the
+ * resources that it holds. <code>Blob</code> object. The object is
+ * invalid once the <code>free</code> method is called. After
+ * <code>free</code> has been called, any attempt to invoke a method
+ * other than <code>free</code> will result in a
+ * <code>SerialException</code> being thrown. If <code>free</code> is
+ * called multiple times, the subsequent calls to <code>free</code>
+ * are treated as a no-op.
*
- * @throws SQLException if an error occurs releasing
- * the Blob's resources
+ * @throws SQLException if an error occurs releasing the Blob's resources
* @since 1.6
*/
public void free() throws SQLException {
- throw new java.lang.UnsupportedOperationException("Not supported");
+ if (isFree == false) {
+ len = -1;
+ origLen = -1;
+ buf = null;
+
+ if (blob != null) {
+ blob.free();
+ blob = null;
+ }
+
+ isFree = true;
+ }
}
+
+ private void isFreed() throws SerialException {
+ if (isFree == true) {
+ throw new SerialException(
+ "Unsupported operation. SerialBlob cannot "
+ + "execute this operation when it"
+ + "has already been freed by free()");
+ }
+ }
+
/**
* The identifier that assists in the serialization of this <code>SerialBlob</code>
* object.
*/