1 21 22 package org.apache.derby.client.am; 23 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.sql.SQLException ; 27 import java.util.ArrayList ; 28 29 import org.apache.derby.shared.common.reference.SQLState; 30 31 public class Blob extends Lob implements java.sql.Blob { 32 33 private boolean isValid = true; 36 37 39 byte[] binaryString_ = null; 40 41 java.io.InputStream binaryStream_ = null; 44 int dataOffset_; 45 46 48 public Blob(byte[] binaryString, 49 Agent agent, 50 int dataOffset) { 51 super(agent); 52 binaryString_ = binaryString; 53 dataType_ |= BINARY_STRING; 54 sqlLength_ = binaryString.length - dataOffset; 55 lengthObtained_ = true; 56 dataOffset_ = dataOffset; 57 } 58 59 public Blob(Agent agent, 61 java.io.InputStream binaryStream, 62 int length) { 63 super(agent); 64 binaryStream_ = binaryStream; 65 dataType_ |= BINARY_STREAM; 66 sqlLength_ = length; 67 lengthObtained_ = true; 68 } 69 70 90 public Blob(Agent agent, java.io.InputStream binaryStream) { 91 super(agent); 92 binaryStream_ = binaryStream; 93 dataType_ |= BINARY_STREAM; 94 sqlLength_ = -1; 95 lengthObtained_ = false; 96 } 97 98 100 public long length() throws SQLException { 101 checkValidity(); 104 try 105 { 106 synchronized (agent_.connection_) { 107 if (agent_.loggingEnabled()) { 108 agent_.logWriter_.traceEntry(this, "length"); 109 } 110 if (!lengthObtained_) { 112 binaryStream_ = super.materializeStream(binaryStream_, 113 "java.sql.Blob"); 114 } 115 long retVal = super.sqlLength(); 116 if (agent_.loggingEnabled()) { 117 agent_.logWriter_.traceExit(this, "length", retVal); 118 } 119 return retVal; 120 } 121 } 122 catch ( SqlException se ) 123 { 124 throw se.getSQLException(); 125 } 126 } 127 128 151 public byte[] getBytes(long pos, int length) throws SQLException { 152 checkValidity(); 155 try 156 { 157 synchronized (agent_.connection_) { 158 if (agent_.loggingEnabled()) { 159 agent_.logWriter_.traceEntry(this, "getBytes", (int) pos, length); 160 } 161 if (pos <= 0) { 162 throw new SqlException(agent_.logWriter_, 163 new ClientMessageId(SQLState.BLOB_BAD_POSITION), 164 new Long (pos)); 165 } 166 if (pos > this.length() + 1) { 167 throw new SqlException(agent_.logWriter_, 168 new ClientMessageId(SQLState.BLOB_POSITION_TOO_LARGE), 169 new Long (pos)); 170 } 171 if (length < 0) { 172 throw new SqlException(agent_.logWriter_, 173 new ClientMessageId(SQLState.BLOB_NONPOSITIVE_LENGTH), 174 new Integer (length)); 175 } 176 byte[] retVal = getBytesX(pos, length); 177 if (agent_.loggingEnabled()) { 178 agent_.logWriter_.traceExit(this, "getBytes", retVal); 179 } 180 return retVal; 181 } 182 } 183 catch ( SqlException se ) 184 { 185 throw se.getSQLException(); 186 } 187 } 188 189 private byte[] getBytesX(long pos, int length) throws SqlException { 190 checkForClosedConnection(); 191 192 long actualLength; 193 try { 194 actualLength = Math.min(this.length() - pos + 1, (long) length); 197 } catch ( SQLException se ) { 198 throw new SqlException(se); 199 } 200 byte[] retVal = new byte[(int) actualLength]; 201 System.arraycopy(binaryString_, (int) pos + dataOffset_ - 1, retVal, 0, (int) actualLength); 202 return retVal; 203 } 204 205 206 public java.io.InputStream getBinaryStream() throws SQLException { 207 checkValidity(); 210 try 211 { 212 synchronized (agent_.connection_) { 213 if (agent_.loggingEnabled()) { 214 agent_.logWriter_.traceEntry(this, "getBinaryStream"); 215 } 216 java.io.InputStream retVal = getBinaryStreamX(); 217 if (agent_.loggingEnabled()) { 218 agent_.logWriter_.traceExit(this, "getBinaryStream", retVal); 219 } 220 return retVal; 221 } 222 } 223 catch ( SqlException se ) 224 { 225 throw se.getSQLException(); 226 } 227 } 228 229 private java.io.InputStream getBinaryStreamX() throws SqlException { 230 checkForClosedConnection(); 231 232 if (isBinaryStream()) { 234 return binaryStream_; 235 } 236 237 return new java.io.ByteArrayInputStream (binaryString_, dataOffset_, binaryString_.length - dataOffset_); 238 } 239 240 public long position(byte[] pattern, long start) throws SQLException { 241 checkValidity(); 244 try 245 { 246 synchronized (agent_.connection_) { 247 if (agent_.loggingEnabled()) { 248 agent_.logWriter_.traceEntry(this, "position(byte[], long)", pattern, start); 249 } 250 if (pattern == null) { 251 throw new SqlException(agent_.logWriter_, 252 new ClientMessageId(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR)); 253 } 254 if (start < 1) { 255 throw new SqlException(agent_.logWriter_, 256 new ClientMessageId(SQLState.BLOB_BAD_POSITION), 257 new Long (start)); 258 } 259 long pos = positionX(pattern, start); 260 if (agent_.loggingEnabled()) { 261 agent_.logWriter_.traceExit(this, "position(byte[], long)", pos); 262 } 263 return pos; 264 } 265 } 266 catch ( SqlException se ) 267 { 268 throw se.getSQLException(); 269 } 270 } 271 272 private long positionX(byte[] pattern, long start) throws SqlException { 273 checkForClosedConnection(); 274 275 return binaryStringPosition(pattern, start); 276 } 277 278 public long position(java.sql.Blob pattern, long start) throws SQLException { 279 checkValidity(); 282 try 283 { 284 synchronized (agent_.connection_) { 285 if (agent_.loggingEnabled()) { 286 agent_.logWriter_.traceEntry(this, "position(Blob, long)", pattern, start); 287 } 288 if (pattern == null) { 289 throw new SqlException(agent_.logWriter_, 290 new ClientMessageId(SQLState.BLOB_NULL_PATTERN_OR_SEARCH_STR)); 291 } 292 if (start < 1) { 293 throw new SqlException(agent_.logWriter_, 294 new ClientMessageId(SQLState.BLOB_BAD_POSITION), 295 new Long (start)); 296 } 297 long pos = positionX(pattern, start); 298 if (agent_.loggingEnabled()) { 299 agent_.logWriter_.traceExit(this, "position(Blob, long)", pos); 300 } 301 return pos; 302 } 303 } 304 catch ( SqlException se ) 305 { 306 throw se.getSQLException(); 307 } 308 } 309 310 private long positionX(java.sql.Blob pattern, long start) throws SqlException { 311 checkForClosedConnection(); 312 313 try { 314 return binaryStringPosition(pattern.getBytes(1L, (int) pattern.length()), start); 315 } catch (java.sql.SQLException e) { 316 throw new SqlException(e); 317 } 318 } 319 320 322 323 public int setBytes(long pos, byte[] bytes) throws SQLException { 324 checkValidity(); 327 try 328 { 329 synchronized (agent_.connection_) { 330 if (agent_.loggingEnabled()) { 331 agent_.logWriter_.traceEntry(this, "setBytes", (int) pos, bytes); 332 } 333 int length = setBytesX(pos, bytes, 0, bytes.length); 334 if (agent_.loggingEnabled()) { 335 agent_.logWriter_.traceExit(this, "setBytes", length); 336 } 337 return length; 338 } 339 } 340 catch ( SqlException se ) 341 { 342 throw se.getSQLException(); 343 } 344 } 345 346 public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { 347 checkValidity(); 350 try 351 { 352 synchronized (agent_.connection_) { 353 if (agent_.loggingEnabled()) { 354 agent_.logWriter_.traceEntry(this, "setBytes", (int) pos, bytes, offset, len); 355 } 356 int length = setBytesX(pos, bytes, offset, len); 357 if (agent_.loggingEnabled()) { 358 agent_.logWriter_.traceExit(this, "setBytes", length); 359 } 360 return length; 361 } 362 } 363 catch ( SqlException se ) 364 { 365 throw se.getSQLException(); 366 } 367 } 368 369 public int setBytesX(long pos, byte[] bytes, int offset, int len) throws SqlException { 370 int length = 0; 371 372 376 377 if (pos <= 0L) { 378 throw new SqlException(agent_.logWriter_, 379 new ClientMessageId(SQLState.BLOB_BAD_POSITION), new Long (pos)); 380 } 381 382 387 388 if (pos >= Integer.MAX_VALUE) { 389 throw new SqlException(agent_.logWriter_, 390 new ClientMessageId(SQLState.BLOB_POSITION_TOO_LARGE), new Long (pos)); 391 } 392 393 if (pos - 1 > binaryString_.length - dataOffset_) { 394 throw new SqlException(agent_.logWriter_, 395 new ClientMessageId(SQLState.BLOB_POSITION_TOO_LARGE), new Long (pos)); 396 } 397 398 if ((offset < 0) || offset > bytes.length ) 399 { 400 throw new SqlException(agent_.logWriter_, 401 new ClientMessageId(SQLState.BLOB_INVALID_OFFSET), 402 new Integer (offset)); 403 } 404 if ( len < 0 ) { 405 throw new SqlException(agent_.logWriter_, 406 new ClientMessageId(SQLState.BLOB_NONPOSITIVE_LENGTH), 407 new Integer (length)); 408 } 409 if (len == 0) { 410 return 0; 411 } 412 length = Math.min((bytes.length - offset), len); 413 if ((binaryString_.length - dataOffset_ - (int) pos + 1) < length) { 414 byte newbuf[] = new byte[(int) pos + length + dataOffset_ - 1]; 415 System.arraycopy(binaryString_, 0, newbuf, 0, binaryString_.length); 416 binaryString_ = newbuf; 417 } 418 419 System.arraycopy(bytes, offset, binaryString_, (int) pos + dataOffset_ - 1, length); 420 binaryStream_ = new java.io.ByteArrayInputStream (binaryString_); 421 sqlLength_ = binaryString_.length - dataOffset_; 422 return length; 423 } 424 425 public java.io.OutputStream setBinaryStream(long pos) throws SQLException { 426 checkValidity(); 429 synchronized (agent_.connection_) { 430 if (agent_.loggingEnabled()) { 431 agent_.logWriter_.traceEntry(this, "setBinaryStream", (int) pos); 432 } 433 BlobOutputStream outStream = new BlobOutputStream(this, pos); 434 435 if (agent_.loggingEnabled()) { 436 agent_.logWriter_.traceExit(this, "setBinaryStream", outStream); 437 } 438 return outStream; 439 } 440 } 441 442 public void truncate(long len) throws SQLException { 443 checkValidity(); 446 try 447 { 448 synchronized (agent_.connection_) { 449 if (agent_.loggingEnabled()) { 450 agent_.logWriter_.traceEntry(this, " truncate", (int) len); 451 } 452 if (len < 0 || len > this.length()) { 453 throw new SqlException(agent_.logWriter_, 454 new ClientMessageId(SQLState.INVALID_API_PARAMETER), 455 new Long (len), "len", "Blob.truncate()"); 456 } 457 if (len == this.length()) { 458 return; 459 } 460 long newLength = (int) len + dataOffset_; 461 byte newbuf[] = new byte[(int) len + dataOffset_]; 462 System.arraycopy(binaryString_, 0, newbuf, 0, (int) newLength); 463 binaryString_ = newbuf; 464 binaryStream_ = new java.io.ByteArrayInputStream (binaryString_); 465 sqlLength_ = binaryString_.length - dataOffset_; 466 } 467 } 468 catch ( SqlException se ) 469 { 470 throw se.getSQLException(); 471 } 472 } 473 474 476 485 public void free() 486 throws SQLException { 487 488 if (!isValid) return; 490 491 isValid = false; 494 495 if(isBinaryStream()) { 496 try { 497 binaryStream_.close(); 498 } 499 catch(IOException ioe) { 500 throw new SqlException(null, new ClientMessageId(SQLState.IO_ERROR_UPON_LOB_FREE)).getSQLException(); 501 } 502 } 503 else { 504 binaryString_ = null; 505 } 506 } 507 508 public InputStream getBinaryStream(long pos, long length) 509 throws SQLException { 510 throw SQLExceptionFactory.notImplemented("getBinaryStream(long,long)"); 511 } 512 513 515 public boolean isBinaryString() { 517 return ((dataType_ & BINARY_STRING) == BINARY_STRING); 518 } 519 520 public boolean isBinaryStream() { 521 return ((dataType_ & BINARY_STREAM) == BINARY_STREAM); 522 } 523 524 public byte[] getBinaryString() { 525 return binaryString_; 526 } 527 528 protected long binaryStringPosition(byte[] pattern, long start) { 529 int index = (int) start + dataOffset_ - 1; 533 while (index + pattern.length <= binaryString_.length) { 534 if (isSubString(pattern, index)) { 535 return (long) (index - dataOffset_ + 1); } 537 index++; 538 } 539 return -1L; } 541 542 protected boolean isSubString(byte[] pattern, int index) { 544 for (int i = 0; i < pattern.length; i++, index++) { 545 if (pattern[i] != binaryString_[index]) { 546 return false; 547 } 548 } 549 550 return true; 551 } 552 553 560 private void checkValidity() throws SQLException { 561 if(!isValid) 562 throw new SqlException(null,new ClientMessageId(SQLState.LOB_OBJECT_INVALID)) 563 .getSQLException(); 564 } 565 } 566 | Popular Tags |