org.hsqldb.server.OdbcPacketOutputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hsqldb Show documentation
Show all versions of hsqldb Show documentation
HSQLDB - Lightweight 100% Java SQL Database Engine
/* Copyright (c) 2001-2011, 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.server;
import java.io.IOException;
import org.hsqldb.lib.DataOutputStream;
import org.hsqldb.lib.HsqlByteArrayOutputStream;
/**
* Atomic transmission packet from HyperSQL server to ODBC client.
*
* Sample usage
*
* outPacket = OdbcPacketOutputStream.newOdbcPacketOutputStream();
* ...
* // For each packet you need to transmit:
* outPacket.reset();
* outPacket.write(this);
* outPacket.write(that);
* outPacket.xmit('X', hsqlDataOutputStream);
*
*/
class OdbcPacketOutputStream extends DataOutputStream {
private HsqlByteArrayOutputStream byteArrayOutputStream;
private HsqlByteArrayOutputStream stringWriterOS =
new HsqlByteArrayOutputStream();
private DataOutputStream stringWriterDos =
new DataOutputStream(stringWriterOS);
private int packetStart = 0; // Stream's "written" at start of packet.
public int getSize() {
return super.count - packetStart;
}
/**
* Wrapper method to write a null-terminated String.
*/
synchronized void write(String s) throws IOException {
write(s, true);
}
synchronized void write(String s, boolean nullTerm) throws IOException {
stringWriterDos.writeUTF(s);
write(stringWriterOS.toByteArray(), 2, stringWriterOS.size() - 2);
stringWriterOS.reset();
if (nullTerm) {
writeByte(0);
}
}
synchronized void writeSized(String s) throws IOException {
stringWriterDos.writeUTF(s);
byte[] ba = stringWriterOS.toByteArray();
stringWriterOS.reset();
writeInt(ba.length - 2);
write(ba, 2, ba.length - 2);
}
synchronized void reset() throws IOException {
byteArrayOutputStream.reset();
packetStart = count;
writeInt(-1); // length placeholder
}
static OdbcPacketOutputStream newOdbcPacketOutputStream()
throws IOException {
return new OdbcPacketOutputStream(new HsqlByteArrayOutputStream());
}
protected OdbcPacketOutputStream(
HsqlByteArrayOutputStream byteArrayOutputStream)
throws IOException {
super(byteArrayOutputStream);
this.byteArrayOutputStream = byteArrayOutputStream;
reset();
}
/**
* @return packet size (which does not count the type byte).
*/
synchronized int xmit(char packetType,
DataOutputStream destinationStream)
throws IOException {
byte[] ba = byteArrayOutputStream.toByteArray();
ba[0] = (byte) (ba.length >> 24);
ba[1] = (byte) (ba.length >> 16);
ba[2] = (byte) (ba.length >> 8);
ba[3] = (byte) ba.length;
reset();
destinationStream.writeByte(packetType);
destinationStream.write(ba);
destinationStream.flush();
return ba.length;
}
synchronized public void close() throws IOException {
super.close();
stringWriterDos.close();
}
/**
* The behavior here is purposefully different from
* java.io.DataOutputStream.writeChar(int), which writes 2 bytes.
*
* We are supporting only 1-byte characters, or don't care about the
* high bits.
*/
synchronized public void writeByteChar(char c) throws IOException {
writeByte(c);
}
}