src/share/classes/javax/sql/rowset/serial/SerialBlob.java

Print this page




  64     /**
  65      * The internal representation of the <code>Blob</code> object on which this
  66      * <code>SerialBlob</code> object is based.
  67      */
  68     private Blob blob;
  69 
  70     /**
  71      * The number of bytes in this <code>SerialBlob</code> object's
  72      * array of bytes.
  73      * @serial
  74      */
  75     private long len;
  76 
  77     /**
  78      * The orginal number of bytes in this <code>SerialBlob</code> object's
  79      * array of bytes when it was first established.
  80      * @serial
  81      */
  82     private long origLen;
  83 


  84     /**
  85      * Constructs a <code>SerialBlob</code> object that is a serialized version of
  86      * the given <code>byte</code> array.
  87      * <p>
  88      * The new <code>SerialBlob</code> object is initialized with the data from the
  89      * <code>byte</code> array, thus allowing disconnected <code>RowSet</code>
  90      * objects to establish serialized <code>Blob</code> objects without
  91      * touching the data source.
  92      *
  93      * @param b the <code>byte</code> array containing the data for the
  94      *        <code>Blob</code> object to be serialized
  95      * @throws SerialException if an error occurs during serialization
  96      * @throws SQLException if a SQL errors occurs
  97      */
  98     public SerialBlob(byte[] b) throws SerialException, SQLException {
  99 
 100         len = b.length;
 101         buf = new byte[(int)len];
 102         for(int i = 0; i < len; i++) {
 103            buf[i] = b[i];


 145      * Copies the specified number of bytes, starting at the given
 146      * position, from this <code>SerialBlob</code> object to
 147      * another array of bytes.
 148      * <P>
 149      * Note that if the given number of bytes to be copied is larger than
 150      * the length of this <code>SerialBlob</code> object's array of
 151      * bytes, the given number will be shortened to the array's length.
 152      *
 153      * @param pos the ordinal position of the first byte in this
 154      *            <code>SerialBlob</code> object to be copied;
 155      *            numbering starts at <code>1</code>; must not be less
 156      *            than <code>1</code> and must be less than or equal
 157      *            to the length of this <code>SerialBlob</code> object
 158      * @param length the number of bytes to be copied
 159      * @return an array of bytes that is a copy of a region of this
 160      *         <code>SerialBlob</code> object, starting at the given
 161      *         position and containing the given number of consecutive bytes
 162      * @throws SerialException if the given starting position is out of bounds
 163      */
 164     public byte[] getBytes(long pos, int length) throws SerialException {






 165         if (length > len) {
 166             length = (int)len;
 167         }
 168 
 169         if (pos < 1 || len - pos < 0 ) {
 170             throw new SerialException("Invalid arguments: position cannot be "
 171                     + "less than 1 or greater than the length of the SerialBlob");
 172         }
 173 
 174         pos--; // correct pos to array index
 175 
 176         byte[] b = new byte[length];
 177 
 178         for (int i = 0; i < length; i++) {
 179             b[i] = this.buf[(int)pos];
 180             pos++;
 181         }
 182         return b;
 183     }
 184 


 189      * @return a <code>long</code> indicating the length in bytes of this
 190      *         <code>SerialBlob</code> object's array of bytes
 191      * @throws SerialException if an error occurs
 192      */
 193     public long length() throws SerialException {
 194         return len;
 195     }
 196 
 197     /**
 198      * Returns this <code>SerialBlob</code> object as an input stream.
 199      * Unlike the related method, <code>setBinaryStream</code>,
 200      * a stream is produced regardless of whether the <code>SerialBlob</code>
 201      * was created with a <code>Blob</code> object or a <code>byte</code> array.
 202      *
 203      * @return a <code>java.io.InputStream</code> object that contains
 204      *         this <code>SerialBlob</code> object's array of bytes
 205      * @throws SerialException if an error occurs
 206      * @see #setBinaryStream
 207      */
 208     public java.io.InputStream getBinaryStream() throws SerialException {






 209          InputStream stream = new ByteArrayInputStream(buf);
 210          return stream;
 211     }
 212 
 213     /**
 214      * Returns the position in this <code>SerialBlob</code> object where
 215      * the given pattern of bytes begins, starting the search at the
 216      * specified position.
 217      *
 218      * @param pattern the pattern of bytes for which to search
 219      * @param start the position of the byte in this
 220      *              <code>SerialBlob</code> object from which to begin
 221      *              the search; the first position is <code>1</code>;
 222      *              must not be less than <code>1</code> nor greater than
 223      *              the length of this <code>SerialBlob</code> object
 224      * @return the position in this <code>SerialBlob</code> object
 225      *         where the given pattern begins, starting at the specified
 226      *         position; <code>-1</code> if the pattern is not found
 227      *         or the given starting position is out of bounds; position
 228      *         numbering for the return value starts at <code>1</code>
 229      * @throws SerialException if an error occurs when serializing the blob
 230      * @throws SQLException if there is an error accessing the <code>BLOB</code>
 231      *         value from the database
 232      */
 233     public long position(byte[] pattern, long start)
 234                 throws SerialException, SQLException {





 235         if (start < 1 || start > len) {
 236             return -1;
 237         }
 238 
 239         int pos = (int)start-1; // internally Blobs are stored as arrays.
 240         int i = 0;
 241         long patlen = pattern.length;
 242 
 243         while (pos < len) {
 244             if (pattern[i] == buf[pos]) {
 245                 if (i + 1 == patlen) {
 246                     return (pos + 1) - (patlen - 1);
 247                 }
 248                 i++; pos++; // increment pos, and i
 249             } else if (pattern[i] != buf[pos]) {
 250                 pos++; // increment pos only
 251             }
 252         }
 253         return -1; // not found
 254     }


 317      *     value
 318      * @param offset the offset in the <code>byte</code> array at which
 319      *     to start reading the bytes. The first offset position is
 320      *     <code>0</code>; must not be less than <code>0</code> nor greater
 321      *     than the length of the <code>byte</code> array
 322      * @param length the number of bytes to be written to the
 323      *     <code>BLOB</code> value from the array of bytes <i>bytes</i>.
 324      *
 325      * @return the number of bytes written
 326      * @throws SerialException if there is an error accessing the
 327      *     <code>BLOB</code> value; if an invalid position is set; if an
 328      *     invalid offset value is set; if number of bytes to be written
 329      *     is greater than the <code>SerialBlob</code> length; or the combined
 330      *     values of the length and offset is greater than the Blob buffer
 331      * @throws SQLException if there is an error accessing the <code>BLOB</code>
 332      *         value from the database.
 333      * @see #getBytes
 334      */
 335     public int setBytes(long pos, byte[] bytes, int offset, int length)
 336         throws SerialException, SQLException {





 337 
 338         if (offset < 0 || offset > bytes.length) {
 339             throw new SerialException("Invalid offset in byte array set");
 340         }
 341 
 342         if (pos < 1 || pos > this.length()) {
 343             throw new SerialException("Invalid position in BLOB object set");
 344         }
 345 
 346         if ((long)(length) > origLen) {
 347             throw new SerialException("Buffer is not sufficient to hold the value");
 348         }
 349 
 350         if ((length + offset) > bytes.length) {
 351             throw new SerialException("Invalid OffSet. Cannot have combined offset " +
 352                 "and length that is greater that the Blob buffer");
 353         }
 354 
 355         int i = 0;
 356         pos--; // correct to array indexing


 385         if (this.blob != null) {
 386             return this.blob.setBinaryStream(pos);
 387         } else {
 388             throw new SerialException("Unsupported operation. SerialBlob cannot " +
 389                 "return a writable binary stream, unless instantiated with a Blob object " +
 390                 "that provides a setBinaryStream() implementation");
 391         }
 392     }
 393 
 394     /**
 395      * Truncates the <code>BLOB</code> value that this <code>Blob</code>
 396      * object represents to be <code>len</code> bytes in length.
 397      *
 398      * @param length the length, in bytes, to which the <code>BLOB</code>
 399      *        value that this <code>Blob</code> object represents should be
 400      *        truncated
 401      * @throws SerialException if there is an error accessing the Blob value;
 402      *     or the length to truncate is greater that the SerialBlob length
 403      */
 404     public void truncate(long length) throws SerialException {





 405 
 406          if (length > len) {
 407             throw new SerialException
 408                ("Length more than what can be truncated");
 409          } else if((int)length == 0) {
 410               buf = new byte[0];
 411               len = length;
 412          } else {
 413               len = length;
 414               buf = this.getBytes(1, (int)len);
 415          }
 416     }
 417 
 418 
 419     /**
 420      * Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
 421      * starting  with the byte specified by pos, which is length bytes in length.
 422      *
 423      * @param pos the offset to the first byte of the partial value to be retrieved.
 424      *  The first byte in the <code>Blob</code> is at position 1
 425      * @param length the length in bytes of the partial value to be retrieved
 426      * @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
 427      * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
 428      * in the <code>Blob</code> or if pos + length is greater than the number of bytes
 429      * in the <code>Blob</code>
 430      *
 431      * @since 1.6
 432      */
 433     public InputStream getBinaryStream(long pos,long length) throws SQLException {
 434         throw new java.lang.UnsupportedOperationException("Not supported");












 435     }
 436 
 437 
 438     /**
 439      * This method frees the <code>Blob</code> object and releases the resources that it holds.
 440      * <code>Blob</code> object. The object is invalid once the <code>free</code>
 441      * method is called. If <code>free</code> is called multiple times, the subsequent
 442      * calls to <code>free</code> are treated as a no-op.
 443      *
 444      * @throws SQLException if an error occurs releasing
 445      * the Blob's resources
 446      * @since 1.6
 447      */
 448     public void free() throws SQLException {
 449         throw new java.lang.UnsupportedOperationException("Not supported");







 450     }
 451     /**
 452          * The identifier that assists in the serialization of this <code>SerialBlob</code>
 453      * object.
 454      */
 455 
 456     static final long serialVersionUID = -8144641928112860441L;
 457 }


  64     /**
  65      * The internal representation of the <code>Blob</code> object on which this
  66      * <code>SerialBlob</code> object is based.
  67      */
  68     private Blob blob;
  69 
  70     /**
  71      * The number of bytes in this <code>SerialBlob</code> object's
  72      * array of bytes.
  73      * @serial
  74      */
  75     private long len;
  76 
  77     /**
  78      * The orginal number of bytes in this <code>SerialBlob</code> object's
  79      * array of bytes when it was first established.
  80      * @serial
  81      */
  82     private long origLen;
  83 
  84     private transient boolean isFree = false;
  85 
  86     /**
  87      * Constructs a <code>SerialBlob</code> object that is a serialized version of
  88      * the given <code>byte</code> array.
  89      * <p>
  90      * The new <code>SerialBlob</code> object is initialized with the data from the
  91      * <code>byte</code> array, thus allowing disconnected <code>RowSet</code>
  92      * objects to establish serialized <code>Blob</code> objects without
  93      * touching the data source.
  94      *
  95      * @param b the <code>byte</code> array containing the data for the
  96      *        <code>Blob</code> object to be serialized
  97      * @throws SerialException if an error occurs during serialization
  98      * @throws SQLException if a SQL errors occurs
  99      */
 100     public SerialBlob(byte[] b) throws SerialException, SQLException {
 101 
 102         len = b.length;
 103         buf = new byte[(int)len];
 104         for(int i = 0; i < len; i++) {
 105            buf[i] = b[i];


 147      * Copies the specified number of bytes, starting at the given
 148      * position, from this <code>SerialBlob</code> object to
 149      * another array of bytes.
 150      * <P>
 151      * Note that if the given number of bytes to be copied is larger than
 152      * the length of this <code>SerialBlob</code> object's array of
 153      * bytes, the given number will be shortened to the array's length.
 154      *
 155      * @param pos the ordinal position of the first byte in this
 156      *            <code>SerialBlob</code> object to be copied;
 157      *            numbering starts at <code>1</code>; must not be less
 158      *            than <code>1</code> and must be less than or equal
 159      *            to the length of this <code>SerialBlob</code> object
 160      * @param length the number of bytes to be copied
 161      * @return an array of bytes that is a copy of a region of this
 162      *         <code>SerialBlob</code> object, starting at the given
 163      *         position and containing the given number of consecutive bytes
 164      * @throws SerialException if the given starting position is out of bounds
 165      */
 166     public byte[] getBytes(long pos, int length) throws SerialException {
 167         if (isFree == true) {
 168             throw new SerialException(
 169                     "Unsupported operation. SerialBlob cannot "
 170                             + "get bytes when it has already been freed with free()");
 171          }
 172 
 173         if (length > len) {
 174             length = (int)len;
 175         }
 176 
 177         if (pos < 1 || len - pos < 0 ) {
 178             throw new SerialException("Invalid arguments: position cannot be "
 179                     + "less than 1 or greater than the length of the SerialBlob");
 180         }
 181 
 182         pos--; // correct pos to array index
 183 
 184         byte[] b = new byte[length];
 185 
 186         for (int i = 0; i < length; i++) {
 187             b[i] = this.buf[(int)pos];
 188             pos++;
 189         }
 190         return b;
 191     }
 192 


 197      * @return a <code>long</code> indicating the length in bytes of this
 198      *         <code>SerialBlob</code> object's array of bytes
 199      * @throws SerialException if an error occurs
 200      */
 201     public long length() throws SerialException {
 202         return len;
 203     }
 204 
 205     /**
 206      * Returns this <code>SerialBlob</code> object as an input stream.
 207      * Unlike the related method, <code>setBinaryStream</code>,
 208      * a stream is produced regardless of whether the <code>SerialBlob</code>
 209      * was created with a <code>Blob</code> object or a <code>byte</code> array.
 210      *
 211      * @return a <code>java.io.InputStream</code> object that contains
 212      *         this <code>SerialBlob</code> object's array of bytes
 213      * @throws SerialException if an error occurs
 214      * @see #setBinaryStream
 215      */
 216     public java.io.InputStream getBinaryStream() throws SerialException {
 217          if (isFree == true) {
 218             throw new SerialException(
 219                     "Unsupported operation. SerialBlob cannot "
 220                             + "return a binary stream when it has already been freed with free()");
 221          }
 222 
 223          InputStream stream = new ByteArrayInputStream(buf);
 224          return stream;
 225     }
 226 
 227     /**
 228      * Returns the position in this <code>SerialBlob</code> object where
 229      * the given pattern of bytes begins, starting the search at the
 230      * specified position.
 231      *
 232      * @param pattern the pattern of bytes for which to search
 233      * @param start the position of the byte in this
 234      *              <code>SerialBlob</code> object from which to begin
 235      *              the search; the first position is <code>1</code>;
 236      *              must not be less than <code>1</code> nor greater than
 237      *              the length of this <code>SerialBlob</code> object
 238      * @return the position in this <code>SerialBlob</code> object
 239      *         where the given pattern begins, starting at the specified
 240      *         position; <code>-1</code> if the pattern is not found
 241      *         or the given starting position is out of bounds; position
 242      *         numbering for the return value starts at <code>1</code>
 243      * @throws SerialException if an error occurs when serializing the blob
 244      * @throws SQLException if there is an error accessing the <code>BLOB</code>
 245      *         value from the database
 246      */
 247     public long position(byte[] pattern, long start)
 248                 throws SerialException, SQLException {
 249         if (isFree == true) {
 250             throw new SerialException(
 251                     "Unsupported operation. SerialBlob has already been freed ");
 252         }
 253 
 254         if (start < 1 || start > len) {
 255             return -1;
 256         }
 257 
 258         int pos = (int)start-1; // internally Blobs are stored as arrays.
 259         int i = 0;
 260         long patlen = pattern.length;
 261 
 262         while (pos < len) {
 263             if (pattern[i] == buf[pos]) {
 264                 if (i + 1 == patlen) {
 265                     return (pos + 1) - (patlen - 1);
 266                 }
 267                 i++; pos++; // increment pos, and i
 268             } else if (pattern[i] != buf[pos]) {
 269                 pos++; // increment pos only
 270             }
 271         }
 272         return -1; // not found
 273     }


 336      *     value
 337      * @param offset the offset in the <code>byte</code> array at which
 338      *     to start reading the bytes. The first offset position is
 339      *     <code>0</code>; must not be less than <code>0</code> nor greater
 340      *     than the length of the <code>byte</code> array
 341      * @param length the number of bytes to be written to the
 342      *     <code>BLOB</code> value from the array of bytes <i>bytes</i>.
 343      *
 344      * @return the number of bytes written
 345      * @throws SerialException if there is an error accessing the
 346      *     <code>BLOB</code> value; if an invalid position is set; if an
 347      *     invalid offset value is set; if number of bytes to be written
 348      *     is greater than the <code>SerialBlob</code> length; or the combined
 349      *     values of the length and offset is greater than the Blob buffer
 350      * @throws SQLException if there is an error accessing the <code>BLOB</code>
 351      *         value from the database.
 352      * @see #getBytes
 353      */
 354     public int setBytes(long pos, byte[] bytes, int offset, int length)
 355         throws SerialException, SQLException {
 356         if (isFree == true) {
 357             throw new SerialException(
 358                     "Unsupported operation. SerialBlob cannot "
 359                             + "set a binary stream when it has already been freed with free()");
 360          }
 361 
 362         if (offset < 0 || offset > bytes.length) {
 363             throw new SerialException("Invalid offset in byte array set");
 364         }
 365 
 366         if (pos < 1 || pos > this.length()) {
 367             throw new SerialException("Invalid position in BLOB object set");
 368         }
 369 
 370         if ((long)(length) > origLen) {
 371             throw new SerialException("Buffer is not sufficient to hold the value");
 372         }
 373 
 374         if ((length + offset) > bytes.length) {
 375             throw new SerialException("Invalid OffSet. Cannot have combined offset " +
 376                 "and length that is greater that the Blob buffer");
 377         }
 378 
 379         int i = 0;
 380         pos--; // correct to array indexing


 409         if (this.blob != null) {
 410             return this.blob.setBinaryStream(pos);
 411         } else {
 412             throw new SerialException("Unsupported operation. SerialBlob cannot " +
 413                 "return a writable binary stream, unless instantiated with a Blob object " +
 414                 "that provides a setBinaryStream() implementation");
 415         }
 416     }
 417 
 418     /**
 419      * Truncates the <code>BLOB</code> value that this <code>Blob</code>
 420      * object represents to be <code>len</code> bytes in length.
 421      *
 422      * @param length the length, in bytes, to which the <code>BLOB</code>
 423      *        value that this <code>Blob</code> object represents should be
 424      *        truncated
 425      * @throws SerialException if there is an error accessing the Blob value;
 426      *     or the length to truncate is greater that the SerialBlob length
 427      */
 428     public void truncate(long length) throws SerialException {
 429         if (isFree == true) {
 430             throw new SerialException(
 431                     "Unsupported operation. SerialBlob cannot "
 432                             + "truncate a SerialBlob when it has already been freed with free()");
 433          }
 434 
 435          if (length > len) {
 436             throw new SerialException
 437                ("Length more than what can be truncated");
 438          } else if((int)length == 0) {
 439               buf = new byte[0];
 440               len = length;
 441          } else {
 442               len = length;
 443               buf = this.getBytes(1, (int)len);
 444          }
 445     }
 446 
 447 
 448     /**
 449      * Returns an <code>InputStream</code> object that contains a partial <code>Blob</code> value,
 450      * starting  with the byte specified by pos, which is length bytes in length.
 451      *
 452      * @param pos the offset to the first byte of the partial value to be retrieved.
 453      *  The first byte in the <code>Blob</code> is at position 1
 454      * @param length the length in bytes of the partial value to be retrieved
 455      * @return <code>InputStream</code> through which the partial <code>Blob</code> value can be read.
 456      * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes
 457      * in the <code>Blob</code> or if pos + length is greater than the number of bytes
 458      * in the <code>Blob</code>
 459      *
 460      * @since 1.6
 461      */
 462     public InputStream getBinaryStream(long pos,long length) throws SQLException {
 463         if (isFree == true) {
 464             throw new SerialException(
 465                     "Unsupported operation. SerialBlob cannot "
 466                             + "return a binary stream when it has already been freed with free()");
 467          }
 468 
 469         if (pos < 1 || pos > len || length > len - pos + 1) {
 470             throw new SerialException("Invalid pos in getBinaryStream");
 471         }
 472         if (length > len - pos + 1) {
 473             throw new SerialException("pos + length greater than total number of bytes");
 474         }
 475         return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
 476     }
 477 
 478 
 479     /**
 480      * This method frees the <code>Blob</code> object and releases the resources that it holds.
 481      * <code>Blob</code> object. The object is invalid once the <code>free</code>
 482      * method is called. If <code>free</code> is called multiple times, the subsequent
 483      * calls to <code>free</code> are treated as a no-op.
 484      *
 485      * @throws SQLException if an error occurs releasing
 486      * the Blob's resources
 487      * @since 1.6
 488      */
 489     public void free() throws SQLException {
 490         if (isFree == false) {
 491             len = -1;
 492             origLen = -1;
 493             buf = null;
 494             blob = null;
 495 
 496             isFree = true;
 497         }
 498     }
 499     /**
 500          * The identifier that assists in the serialization of this <code>SerialBlob</code>
 501      * object.
 502      */
 503 
 504     static final long serialVersionUID = -8144641928112860441L;
 505 }