jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SerialBlob.java
changeset 30641 701f6f90dc0b
parent 25991 e48157b42439
equal deleted inserted replaced
30640:3dba338b5d00 30641:701f6f90dc0b
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    65     /**
    65     /**
    66      * A serialized array of uninterpreted bytes representing the
    66      * A serialized array of uninterpreted bytes representing the
    67      * value of this <code>SerialBlob</code> object.
    67      * value of this <code>SerialBlob</code> object.
    68      * @serial
    68      * @serial
    69      */
    69      */
    70     private byte buf[];
    70     private byte[] buf;
    71 
    71 
    72     /**
    72     /**
    73      * The internal representation of the <code>Blob</code> object on which this
    73      * The internal representation of the <code>Blob</code> object on which this
    74      * <code>SerialBlob</code> object is based.
    74      * <code>SerialBlob</code> object is based.
    75      */
    75      */
   101      * @param b the <code>byte</code> array containing the data for the
   101      * @param b the <code>byte</code> array containing the data for the
   102      *        <code>Blob</code> object to be serialized
   102      *        <code>Blob</code> object to be serialized
   103      * @throws SerialException if an error occurs during serialization
   103      * @throws SerialException if an error occurs during serialization
   104      * @throws SQLException if a SQL errors occurs
   104      * @throws SQLException if a SQL errors occurs
   105      */
   105      */
   106     public SerialBlob(byte[] b) throws SerialException, SQLException {
   106     public SerialBlob(byte[] b)
       
   107             throws SerialException, SQLException {
   107 
   108 
   108         len = b.length;
   109         len = b.length;
   109         buf = new byte[(int)len];
   110         buf = new byte[(int)len];
   110         for(int i = 0; i < len; i++) {
   111         for(int i = 0; i < len; i++) {
   111            buf[i] = b[i];
   112             buf[i] = b[i];
   112         }
   113         }
   113         origLen = len;
   114         origLen = len;
   114     }
   115     }
   115 
   116 
   116 
   117 
   131      * @throws SerialException if an error occurs during serialization
   132      * @throws SerialException if an error occurs during serialization
   132      * @throws SQLException if the <code>Blob</code> passed to this
   133      * @throws SQLException if the <code>Blob</code> passed to this
   133      *     to this constructor is a <code>null</code>.
   134      *     to this constructor is a <code>null</code>.
   134      * @see java.sql.Blob
   135      * @see java.sql.Blob
   135      */
   136      */
   136     public SerialBlob (Blob blob) throws SerialException, SQLException {
   137     public SerialBlob (Blob blob)
       
   138             throws SerialException, SQLException {
   137 
   139 
   138         if (blob == null) {
   140         if (blob == null) {
   139             throw new SQLException("Cannot instantiate a SerialBlob " +
   141             throw new SQLException(
   140                  "object with a null Blob object");
   142                     "Cannot instantiate a SerialBlob object with a null Blob object");
   141         }
   143         }
   142 
   144 
   143         len = blob.length();
   145         len = blob.length();
   144         buf = blob.getBytes(1, (int)len );
   146         buf = blob.getBytes(1, (int)len );
   145         this.blob = blob;
   147         this.blob = blob;
   146 
       
   147          //if ( len < 10240000)
       
   148          // len = 10240000;
       
   149         origLen = len;
   148         origLen = len;
   150     }
   149     }
   151 
   150 
   152     /**
   151     /**
   153      * Copies the specified number of bytes, starting at the given
   152      * Copies the specified number of bytes, starting at the given
   244      * if {@code free} had previously been called on this object
   243      * if {@code free} had previously been called on this object
   245      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   244      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   246      *         value from the database
   245      *         value from the database
   247      */
   246      */
   248     public long position(byte[] pattern, long start)
   247     public long position(byte[] pattern, long start)
   249                 throws SerialException, SQLException {
   248             throws SerialException, SQLException {
       
   249 
   250         isValid();
   250         isValid();
   251         if (start < 1 || start > len) {
   251         if (start < 1 || start > len) {
   252             return -1;
   252             return -1;
   253         }
   253         }
   254 
   254 
   289      * if {@code free} had previously been called on this object
   289      * if {@code free} had previously been called on this object
   290      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   290      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   291      *         value from the database
   291      *         value from the database
   292      */
   292      */
   293     public long position(Blob pattern, long start)
   293     public long position(Blob pattern, long start)
   294        throws SerialException, SQLException {
   294             throws SerialException, SQLException {
   295         isValid();
   295         isValid();
   296         return position(pattern.getBytes(1, (int)(pattern.length())), start);
   296         return position(pattern.getBytes(1, (int)(pattern.length())), start);
   297     }
   297     }
   298 
   298 
   299     /**
   299     /**
   315      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   315      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   316      *         value from the database
   316      *         value from the database
   317      * @see #getBytes
   317      * @see #getBytes
   318      */
   318      */
   319     public int setBytes(long pos, byte[] bytes)
   319     public int setBytes(long pos, byte[] bytes)
   320         throws SerialException, SQLException {
   320             throws SerialException, SQLException {
   321         return (setBytes(pos, bytes, 0, bytes.length));
   321         return setBytes(pos, bytes, 0, bytes.length);
   322     }
   322     }
   323 
   323 
   324     /**
   324     /**
   325      * Writes all or part of the given <code>byte</code> array to the
   325      * Writes all or part of the given <code>byte</code> array to the
   326      * <code>BLOB</code> value that this <code>Blob</code> object represents
   326      * <code>BLOB</code> value that this <code>Blob</code> object represents
   351      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   351      * @throws SQLException if there is an error accessing the <code>BLOB</code>
   352      *         value from the database.
   352      *         value from the database.
   353      * @see #getBytes
   353      * @see #getBytes
   354      */
   354      */
   355     public int setBytes(long pos, byte[] bytes, int offset, int length)
   355     public int setBytes(long pos, byte[] bytes, int offset, int length)
   356         throws SerialException, SQLException {
   356             throws SerialException, SQLException {
   357 
   357 
   358         isValid();
   358         isValid();
   359         if (offset < 0 || offset > bytes.length) {
   359         if (offset < 0 || offset > bytes.length) {
   360             throw new SerialException("Invalid offset in byte array set");
   360             throw new SerialException("Invalid offset in byte array set");
   361         }
   361         }
   368             throw new SerialException("Buffer is not sufficient to hold the value");
   368             throw new SerialException("Buffer is not sufficient to hold the value");
   369         }
   369         }
   370 
   370 
   371         if ((length + offset) > bytes.length) {
   371         if ((length + offset) > bytes.length) {
   372             throw new SerialException("Invalid OffSet. Cannot have combined offset " +
   372             throw new SerialException("Invalid OffSet. Cannot have combined offset " +
   373                 "and length that is greater that the Blob buffer");
   373                     "and length that is greater that the Blob buffer");
   374         }
   374         }
   375 
   375 
   376         int i = 0;
   376         int i = 0;
   377         pos--; // correct to array indexing
   377         pos--; // correct to array indexing
   378         while ( i < length || (offset + i +1) < (bytes.length-offset) ) {
   378         while ( i < length || (offset + i +1) < (bytes.length-offset) ) {
   401      *     <code>Blob</code> object that supports <code>setBinaryStream()</code>;
   401      *     <code>Blob</code> object that supports <code>setBinaryStream()</code>;
   402      * if {@code free} had previously been called on this object
   402      * if {@code free} had previously been called on this object
   403      * @see #getBinaryStream
   403      * @see #getBinaryStream
   404      */
   404      */
   405     public java.io.OutputStream setBinaryStream(long pos)
   405     public java.io.OutputStream setBinaryStream(long pos)
   406         throws SerialException, SQLException {
   406             throws SerialException, SQLException {
       
   407 
   407         isValid();
   408         isValid();
   408         if (this.blob != null) {
   409         if (this.blob != null) {
   409             return this.blob.setBinaryStream(pos);
   410             return this.blob.setBinaryStream(pos);
   410         } else {
   411         } else {
   411             throw new SerialException("Unsupported operation. SerialBlob cannot " +
   412             throw new SerialException("Unsupported operation. SerialBlob cannot " +
   424      * @throws SerialException if there is an error accessing the Blob value;
   425      * @throws SerialException if there is an error accessing the Blob value;
   425      *     or the length to truncate is greater that the SerialBlob length;
   426      *     or the length to truncate is greater that the SerialBlob length;
   426      * if {@code free} had previously been called on this object
   427      * if {@code free} had previously been called on this object
   427      */
   428      */
   428     public void truncate(long length) throws SerialException {
   429     public void truncate(long length) throws SerialException {
   429 
       
   430         isValid();
   430         isValid();
   431         if (length > len) {
   431         if (length > len) {
   432            throw new SerialException
   432             throw new SerialException(
   433               ("Length more than what can be truncated");
   433                     "Length more than what can be truncated");
   434         } else if((int)length == 0) {
   434         } else if((int)length == 0) {
   435              buf = new byte[0];
   435             buf = new byte[0];
   436              len = length;
   436             len = length;
   437         } else {
   437         } else {
   438              len = length;
   438             len = length;
   439              buf = this.getBytes(1, (int)len);
   439             buf = this.getBytes(1, (int)len);
   440         }
   440         }
   441     }
   441     }
   442 
   442 
   443 
   443 
   444     /**
   444     /**
   465         isValid();
   465         isValid();
   466         if (pos < 1 || pos > this.length()) {
   466         if (pos < 1 || pos > this.length()) {
   467             throw new SerialException("Invalid position in BLOB object set");
   467             throw new SerialException("Invalid position in BLOB object set");
   468         }
   468         }
   469         if (length < 1 || length > len - pos + 1) {
   469         if (length < 1 || length > len - pos + 1) {
   470             throw new SerialException("length is < 1 or pos + length >"
   470             throw new SerialException(
   471                     + "total number of bytes");
   471                     "length is < 1 or pos + length > total number of bytes");
   472         }
   472         }
   473         return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
   473         return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
   474     }
   474     }
   475 
   475 
   476 
   476 
   535      * @return  a clone of this SerialBlob
   535      * @return  a clone of this SerialBlob
   536      */
   536      */
   537     public Object clone() {
   537     public Object clone() {
   538         try {
   538         try {
   539             SerialBlob sb = (SerialBlob) super.clone();
   539             SerialBlob sb = (SerialBlob) super.clone();
   540             sb.buf =  (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
   540             sb.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
   541             sb.blob = null;
   541             sb.blob = null;
   542             return sb;
   542             return sb;
   543         } catch (CloneNotSupportedException ex) {
   543         } catch (CloneNotSupportedException ex) {
   544             // this shouldn't happen, since we are Cloneable
   544             // this shouldn't happen, since we are Cloneable
   545             throw new InternalError();
   545             throw new InternalError();
   546         }
   546         }
   547 
       
   548     }
   547     }
   549 
   548 
   550     /**
   549     /**
   551      * readObject is called to restore the state of the SerialBlob from
   550      * readObject is called to restore the state of the SerialBlob from
   552      * a stream.
   551      * a stream.
   553      */
   552      */
   554     private void readObject(ObjectInputStream s)
   553     private void readObject(ObjectInputStream s)
   555             throws IOException, ClassNotFoundException {
   554             throws IOException, ClassNotFoundException {
   556 
   555 
   557         ObjectInputStream.GetField fields = s.readFields();
   556         ObjectInputStream.GetField fields = s.readFields();
   558        byte[] tmp = (byte[])fields.get("buf", null);
   557         byte[] tmp = (byte[])fields.get("buf", null);
   559        if (tmp == null)
   558         if (tmp == null)
   560            throw new InvalidObjectException("buf is null and should not be!");
   559             throw new InvalidObjectException("buf is null and should not be!");
   561        buf = tmp.clone();
   560         buf = tmp.clone();
   562        len = fields.get("len", 0L);
   561         len = fields.get("len", 0L);
   563        if (buf.length != len)
   562         if (buf.length != len)
   564            throw new InvalidObjectException("buf is not the expected size");
   563             throw new InvalidObjectException("buf is not the expected size");
   565        origLen = fields.get("origLen", 0L);
   564         origLen = fields.get("origLen", 0L);
   566        blob = (Blob) fields.get("blob", null);
   565         blob = (Blob) fields.get("blob", null);
   567     }
   566     }
   568 
   567 
   569     /**
   568     /**
   570      * writeObject is called to save the state of the SerialBlob
   569      * writeObject is called to save the state of the SerialBlob
   571      * to a stream.
   570      * to a stream.
   589      *
   588      *
   590      * @throws SerialException
   589      * @throws SerialException
   591      */
   590      */
   592     private void isValid() throws SerialException {
   591     private void isValid() throws SerialException {
   593         if (buf == null) {
   592         if (buf == null) {
   594             throw new SerialException("Error: You cannot call a method on a "
   593             throw new SerialException("Error: You cannot call a method on a " +
   595                     + "SerialBlob instance once free() has been called.");
   594                     "SerialBlob instance once free() has been called.");
   596         }
   595         }
   597     }
   596     }
   598 
   597 
   599     /**
   598     /**
   600      * The identifier that assists in the serialization of this
   599      * The identifier that assists in the serialization of this