org.hsqldb.result.ResultLob Maven / Gradle / Ivy
/* Copyright (c) 2001-2014, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.result;
import java.io.DataInput;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.hsqldb.SessionInterface;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.DataOutputStream;
import org.hsqldb.lib.HsqlByteArrayOutputStream;
import org.hsqldb.rowio.RowOutputInterface;
/**
* Sub-class of Result for communicating Blob and Clob operations.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.0.1
* @since 1.9.0
*/
public final class ResultLob extends Result {
public interface LobResultTypes {
int REQUEST_GET_BYTES = 1;
int REQUEST_SET_BYTES = 2;
int REQUEST_GET_CHARS = 3;
int REQUEST_SET_CHARS = 4;
int REQUEST_GET_BYTE_PATTERN_POSITION = 5;
int REQUEST_GET_CHAR_PATTERN_POSITION = 6;
int REQUEST_CREATE_BYTES = 7;
int REQUEST_CREATE_CHARS = 8;
int REQUEST_TRUNCATE = 9;
int REQUEST_GET_LENGTH = 10;
int REQUEST_GET_LOB = 11;
int REQUEST_DUPLICATE_LOB = 12;
// non-network
int REQUEST_GET_TRUNCATE_LENGTH = 13;
//
int RESPONSE_GET_BYTES = 21;
int RESPONSE_SET = 22;
int RESPONSE_GET_CHARS = 23;
int RESPONSE_GET_BYTE_PATTERN_POSITION = 25;
int RESPONSE_GET_CHAR_PATTERN_POSITION = 26;
int RESPONSE_CREATE_BYTES = 27;
int RESPONSE_CREATE_CHARS = 28;
int RESPONSE_TRUNCATE = 29;
}
long lobID;
int subType;
long blockOffset;
long blockLength;
byte[] byteBlock;
char[] charBlock;
Reader reader;
InputStream stream;
private ResultLob() {
super(ResultConstants.LARGE_OBJECT_OP);
}
public static ResultLob newLobGetLengthRequest(long id) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_LENGTH;
result.lobID = id;
return result;
}
public static ResultLob newLobGetBytesRequest(long id, long offset,
int length) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_BYTES;
result.lobID = id;
result.blockOffset = offset;
result.blockLength = length;
return result;
}
public static ResultLob newLobGetCharsRequest(long id, long offset,
int length) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_CHARS;
result.lobID = id;
result.blockOffset = offset;
result.blockLength = length;
return result;
}
public static ResultLob newLobSetBytesRequest(long id, long offset,
byte block[]) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_SET_BYTES;
result.lobID = id;
result.blockOffset = offset;
result.byteBlock = block;
result.blockLength = block.length;
return result;
}
public static ResultLob newLobSetCharsRequest(long id, long offset,
char[] chars) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_SET_CHARS;
result.lobID = id;
result.blockOffset = offset;
result.charBlock = chars;
result.blockLength = chars.length;
return result;
}
public static ResultLob newLobTruncateRequest(long id, long offset) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_TRUNCATE;
result.lobID = id;
result.blockOffset = offset;
return result;
}
public static ResultLob newLobGetBytesResponse(long id, long offset,
byte block[]) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_GET_BYTES;
result.lobID = id;
result.blockOffset = offset;
result.byteBlock = block;
result.blockLength = block.length;
return result;
}
public static ResultLob newLobGetCharsResponse(long id, long offset,
char[] chars) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_GET_CHARS;
result.lobID = id;
result.blockOffset = offset;
result.charBlock = chars;
result.blockLength = chars.length;
return result;
}
public static ResultLob newLobSetResponse(long id, long length) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_SET;
result.lobID = id;
result.blockLength = length;
return result;
}
public static ResultLob newLobGetBytePatternPositionRequest(long id,
byte[] pattern, long offset) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION;
result.lobID = id;
result.blockOffset = offset;
result.byteBlock = pattern;
result.blockLength = pattern.length;
return result;
}
public static ResultLob newLobGetBytePatternPositionRequest(long id,
long otherId, long offset) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION;
result.lobID = id;
result.blockOffset = offset;
return result;
}
public static ResultLob newLobGetCharPatternPositionRequest(long id,
char[] pattern, long offset) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION;
result.lobID = id;
result.blockOffset = offset;
result.charBlock = pattern;
result.blockLength = pattern.length;
return result;
}
public static ResultLob newLobGetCharPatternPositionRequest(long id,
long otherId, long offset) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION;
result.lobID = id;
result.blockOffset = offset;
result.blockLength = otherId;
return result;
}
public static ResultLob newLobCreateBlobRequest(long sessionID,
long lobID, InputStream stream, long length) {
ResultLob result = new ResultLob();
result.lobID = lobID;
result.subType = LobResultTypes.REQUEST_CREATE_BYTES;
result.blockLength = length;
result.stream = stream;
return result;
}
public static ResultLob newLobCreateClobRequest(long sessionID,
long lobID, Reader reader, long length) {
ResultLob result = new ResultLob();
result.lobID = lobID;
result.subType = LobResultTypes.REQUEST_CREATE_CHARS;
result.blockLength = length;
result.reader = reader;
return result;
}
public static ResultLob newLobGetTruncateLength(long id) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_TRUNCATE_LENGTH;
result.lobID = id;
return result;
}
public static ResultLob newLobCreateBlobResponse(long id) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_CREATE_BYTES;
result.lobID = id;
return result;
}
public static ResultLob newLobCreateClobResponse(long id) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_CREATE_CHARS;
result.lobID = id;
return result;
}
public static ResultLob newLobTruncateResponse(long id, long length) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.RESPONSE_TRUNCATE;
result.lobID = id;
result.blockLength = length;
return result;
}
public static ResultLob newLobGetRequest(long id, long offset,
long length) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_GET_LOB;
result.lobID = id;
result.blockOffset = offset;
result.blockLength = length;
return result;
}
public static ResultLob newLobDuplicateRequest(long id) {
ResultLob result = new ResultLob();
result.subType = LobResultTypes.REQUEST_DUPLICATE_LOB;
result.lobID = id;
return result;
}
public static ResultLob newLob(DataInput dataInput,
boolean readTerminate) throws IOException {
ResultLob result = new ResultLob();
result.databaseID = dataInput.readInt();
result.sessionID = dataInput.readLong();
result.lobID = dataInput.readLong();
result.subType = dataInput.readInt();
switch (result.subType) {
case LobResultTypes.REQUEST_CREATE_BYTES :
case LobResultTypes.REQUEST_CREATE_CHARS :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
break;
case LobResultTypes.REQUEST_GET_LOB :
case LobResultTypes.REQUEST_DUPLICATE_LOB :
//
case LobResultTypes.REQUEST_GET_BYTES :
case LobResultTypes.REQUEST_GET_CHARS :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
break;
case LobResultTypes.REQUEST_SET_BYTES :
case LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
result.byteBlock = new byte[(int) result.blockLength];
dataInput.readFully(result.byteBlock);
break;
case LobResultTypes.REQUEST_SET_CHARS :
case LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
result.charBlock = new char[(int) result.blockLength];
for (int i = 0; i < result.charBlock.length; i++) {
result.charBlock[i] = dataInput.readChar();
}
break;
case LobResultTypes.REQUEST_GET_LENGTH :
case LobResultTypes.REQUEST_TRUNCATE :
result.blockOffset = dataInput.readLong();
break;
case LobResultTypes.RESPONSE_GET_BYTES :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
result.byteBlock = new byte[(int) result.blockLength];
dataInput.readFully(result.byteBlock);
break;
case LobResultTypes.RESPONSE_GET_CHARS :
result.blockOffset = dataInput.readLong();
result.blockLength = dataInput.readLong();
result.charBlock = new char[(int) result.blockLength];
for (int i = 0; i < result.charBlock.length; i++) {
result.charBlock[i] = dataInput.readChar();
}
break;
case LobResultTypes.RESPONSE_SET :
case LobResultTypes.RESPONSE_CREATE_BYTES :
case LobResultTypes.RESPONSE_CREATE_CHARS :
case LobResultTypes.RESPONSE_TRUNCATE :
result.blockLength = dataInput.readLong();
break;
case LobResultTypes.RESPONSE_GET_BYTE_PATTERN_POSITION :
case LobResultTypes.RESPONSE_GET_CHAR_PATTERN_POSITION :
result.blockOffset = dataInput.readLong();
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "ResultLob");
}
if (readTerminate) {
dataInput.readByte();
}
return result;
}
public void write(SessionInterface session, DataOutputStream dataOut,
RowOutputInterface rowOut) throws IOException {
writeBody(session, dataOut);
dataOut.writeByte(ResultConstants.NONE);
dataOut.flush();
}
public void writeBody(SessionInterface session,
DataOutputStream dataOut) throws IOException {
switch (subType) {
case LobResultTypes.REQUEST_CREATE_BYTES :
if (blockLength >= 0) {
writeCreate(session, dataOut);
return;
}
writeCreateByteSegments(session, dataOut);
return;
case LobResultTypes.REQUEST_CREATE_CHARS : {
if (blockLength >= 0) {
writeCreate(session, dataOut);
return;
}
writeCreateCharSegments(session, dataOut);
return;
}
}
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(subType);
switch (subType) {
case LobResultTypes.REQUEST_SET_BYTES :
case LobResultTypes.REQUEST_GET_BYTE_PATTERN_POSITION :
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
dataOut.write(byteBlock);
break;
case LobResultTypes.REQUEST_SET_CHARS :
case LobResultTypes.REQUEST_GET_CHAR_PATTERN_POSITION :
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
dataOut.writeChars(charBlock);
break;
case LobResultTypes.REQUEST_GET_LOB :
case LobResultTypes.REQUEST_DUPLICATE_LOB :
//
case LobResultTypes.REQUEST_GET_BYTES :
case LobResultTypes.REQUEST_GET_CHARS :
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
break;
case LobResultTypes.REQUEST_GET_LENGTH :
case LobResultTypes.REQUEST_TRUNCATE :
dataOut.writeLong(blockOffset);
break;
case LobResultTypes.RESPONSE_GET_BYTES :
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
dataOut.write(byteBlock);
break;
case LobResultTypes.RESPONSE_GET_CHARS :
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
dataOut.writeChars(charBlock);
break;
case LobResultTypes.RESPONSE_SET :
case LobResultTypes.RESPONSE_CREATE_BYTES :
case LobResultTypes.RESPONSE_CREATE_CHARS :
case LobResultTypes.RESPONSE_TRUNCATE :
dataOut.writeLong(blockLength);
break;
case LobResultTypes.RESPONSE_GET_BYTE_PATTERN_POSITION :
case LobResultTypes.RESPONSE_GET_CHAR_PATTERN_POSITION :
dataOut.writeLong(blockOffset);
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "ResultLob");
}
}
private void writeCreate(SessionInterface session,
DataOutputStream dataOut) throws IOException {
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(subType);
dataOut.writeLong(blockOffset);
dataOut.writeLong(blockLength);
switch (subType) {
case LobResultTypes.REQUEST_CREATE_BYTES :
dataOut.write(stream, blockLength);
break;
case LobResultTypes.REQUEST_CREATE_CHARS :
dataOut.write(reader, blockLength);
break;
}
}
private void writeCreateByteSegments(SessionInterface session,
DataOutputStream dataOut)
throws IOException {
//
int bufferLength = session.getStreamBlockSize();
long currentOffset = blockOffset;
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(subType);
HsqlByteArrayOutputStream byteArrayOS =
new HsqlByteArrayOutputStream(bufferLength);
byteArrayOS.reset();
byteArrayOS.write(stream, bufferLength);
dataOut.writeLong(currentOffset);
dataOut.writeLong(byteArrayOS.size());
dataOut.write(byteArrayOS.getBuffer(), 0, byteArrayOS.size());
currentOffset += byteArrayOS.size();
if (byteArrayOS.size() < bufferLength) {
return;
}
//
while (true) {
byteArrayOS.reset();
byteArrayOS.write(stream, bufferLength);
if (byteArrayOS.size() == 0) {
break;
}
//
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(LobResultTypes.REQUEST_SET_BYTES);
dataOut.writeLong(currentOffset);
dataOut.writeLong(byteArrayOS.size());
dataOut.write(byteArrayOS.getBuffer(), 0, byteArrayOS.size());
currentOffset += byteArrayOS.size();
if (byteArrayOS.size() < bufferLength) {
break;
}
}
}
private void writeCreateCharSegments(SessionInterface session,
DataOutputStream dataOut)
throws IOException {
//
int bufferLength = session.getStreamBlockSize();
long currentOffset = blockOffset;
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(subType);
HsqlByteArrayOutputStream byteArrayOS =
new HsqlByteArrayOutputStream(bufferLength);
byteArrayOS.reset();
byteArrayOS.write(reader, bufferLength / 2);
//
dataOut.writeLong(currentOffset);
dataOut.writeLong(byteArrayOS.size() / 2);
dataOut.write(byteArrayOS.getBuffer(), 0, byteArrayOS.size());
currentOffset += byteArrayOS.size() / 2;
if (byteArrayOS.size() < bufferLength) {
return;
}
//
while (true) {
byteArrayOS.reset();
byteArrayOS.write(reader, bufferLength / 2);
if (byteArrayOS.size() == 0) {
break;
}
//
dataOut.writeByte(mode);
dataOut.writeInt(databaseID);
dataOut.writeLong(sessionID);
dataOut.writeLong(lobID);
dataOut.writeInt(LobResultTypes.REQUEST_SET_CHARS);
dataOut.writeLong(currentOffset);
dataOut.writeLong(byteArrayOS.size() / 2);
dataOut.write(byteArrayOS.getBuffer(), 0, byteArrayOS.size());
currentOffset += byteArrayOS.size() / 2;
if (byteArrayOS.size() < bufferLength) {
break;
}
}
}
public long getLobID() {
return lobID;
}
public int getSubType() {
return subType;
}
public long getOffset() {
return blockOffset;
}
public long getBlockLength() {
return blockLength;
}
public byte[] getByteArray() {
return byteBlock;
}
public char[] getCharArray() {
return charBlock;
}
public InputStream getInputStream() {
return stream;
}
public Reader getReader() {
return reader;
}
}