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 |
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 |