public void testTypeMix() throws IOException { byte[] buffer = new byte[1024]; String resPath = "/org/hsqldb/resources/odbcPacket.data"; InputStream is = OdbcPacketOutputStreamTest.class.getResourceAsStream(resPath); if (is == null) { throw new RuntimeException( "CLASSPATH not set properly. " + "Res file '" + resPath + "' not accessible"); } ByteArrayOutputStream baosA = new ByteArrayOutputStream(); ByteArrayOutputStream baosE = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baosA); int i; while ((i = is.read(buffer)) > -1) { baosE.write(buffer, 0, i); } byte[] expectedBa = baosE.toByteArray(); baosE.close(); targetPacket.writeShort((short) distinguishableLong); targetPacket.writeInt((int) distinguishableLong); targetPacket.writeLong(distinguishableLong); targetPacket.writeByte((byte) distinguishableLong); targetPacket.writeByteChar('k'); // the writeByteChar() method is explicitly not for ext. characters. int preLength = targetPacket.getSize(); targetPacket.write("Ein gro\u00df Baum\nwith blossom", false); if (targetPacket.getSize() - preLength != 27) { throw new RuntimeException("Assertion failed. Fix test because encoding size changed"); } targetPacket.write("Another string", true); targetPacket.writeSized("Ein gro\u00df Baum\nmit blossom"); targetPacket.xmit('a', dos); dos.flush(); dos.close(); byte[] actualBa = baosA.toByteArray(); /* Use this to regenerate the test data (which is also used to test * the reader). java.io.FileOutputStream fos = new java.io.FileOutputStream("/tmp/fix.bin"); fos.write(actualBa); fos.flush(); fos.close(); */ // JUnit 4.x has a built-in byte-array comparator. Until then... assertEquals("Byte stream size is wrong", expectedBa.length, actualBa.length); for (i = 0; i < expectedBa.length; i++) { assertEquals("Bye stream corruption at offset " + i, expectedBa[i], actualBa[i]); } }
public void write(SessionInterface session, DataOutputStream dataOut, RowOutputInterface rowOut) throws IOException, HsqlException { rowOut.reset(); rowOut.writeByte(mode); int startPos = rowOut.size(); rowOut.writeSize(0); switch (mode) { case ResultConstants.GETSESSIONATTR: rowOut.writeByte(statementReturnType); break; case ResultConstants.DISCONNECT: case ResultConstants.RESETSESSION: case ResultConstants.STARTTRAN: break; case ResultConstants.PREPARE: rowOut.writeByte(statementReturnType); rowOut.writeString(mainString); rowOut.writeByte(rsProperties); rowOut.writeByte(generateKeys); if (generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES || generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES) { generatedMetaData.write(rowOut); } break; case ResultConstants.FREESTMT: rowOut.writeLong(statementID); break; case ResultConstants.CLOSE_RESULT: rowOut.writeLong(id); break; case ResultConstants.EXECDIRECT: rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); rowOut.writeByte(statementReturnType); rowOut.writeString(mainString); rowOut.writeByte(rsProperties); rowOut.writeShort(queryTimeout); rowOut.writeByte(generateKeys); if (generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES || generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES) { generatedMetaData.write(rowOut); } break; case ResultConstants.CONNECT: rowOut.writeString(databaseName); rowOut.writeString(mainString); rowOut.writeString(subString); rowOut.writeString(zoneString); rowOut.writeInt(updateCount); break; case ResultConstants.ERROR: case ResultConstants.WARNING: rowOut.writeString(mainString); rowOut.writeString(subString); rowOut.writeInt(errorCode); break; case ResultConstants.CONNECTACKNOWLEDGE: rowOut.writeInt(databaseID); rowOut.writeLong(sessionID); rowOut.writeString(databaseName); rowOut.writeString(mainString); break; case ResultConstants.UPDATECOUNT: rowOut.writeInt(updateCount); break; case ResultConstants.ENDTRAN: { int type = getActionType(); rowOut.writeInt(type); // endtran type switch (type) { case ResultConstants.TX_SAVEPOINT_NAME_RELEASE: case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK: rowOut.writeString(mainString); // savepoint name break; case ResultConstants.TX_COMMIT: case ResultConstants.TX_ROLLBACK: case ResultConstants.TX_COMMIT_AND_CHAIN: case ResultConstants.TX_ROLLBACK_AND_CHAIN: case ResultConstants.PREPARECOMMIT: break; default: throw Error.runtimeError(ErrorCode.U_S0500, "Result"); } break; } case ResultConstants.PREPARE_ACK: rowOut.writeByte(statementReturnType); rowOut.writeLong(statementID); rowOut.writeByte(rsProperties); metaData.write(rowOut); parameterMetaData.write(rowOut); break; case ResultConstants.CALL_RESPONSE: rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); rowOut.writeLong(statementID); rowOut.writeByte(statementReturnType); rowOut.writeByte(rsProperties); metaData.write(rowOut); writeSimple(rowOut, metaData, (Object[]) valueData); break; case ResultConstants.EXECUTE: rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); rowOut.writeLong(statementID); rowOut.writeByte(rsProperties); rowOut.writeShort(queryTimeout); writeSimple(rowOut, metaData, (Object[]) valueData); break; case ResultConstants.UPDATE_RESULT: rowOut.writeLong(id); rowOut.writeInt(getActionType()); metaData.write(rowOut); writeSimple(rowOut, metaData, (Object[]) valueData); break; case ResultConstants.BATCHEXECRESPONSE: case ResultConstants.BATCHEXECUTE: case ResultConstants.BATCHEXECDIRECT: case ResultConstants.SETSESSIONATTR: { rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); rowOut.writeLong(statementID); rowOut.writeShort(queryTimeout); metaData.write(rowOut); navigator.writeSimple(rowOut, metaData); break; } case ResultConstants.PARAM_METADATA: { metaData.write(rowOut); navigator.write(rowOut, metaData); break; } case ResultConstants.SETCONNECTATTR: { int type = getConnectionAttrType(); rowOut.writeInt(type); // attr type / updateCount switch (type) { case ResultConstants.SQL_ATTR_SAVEPOINT_NAME: rowOut.writeString(mainString); // savepoint name break; // case ResultConstants.SQL_ATTR_AUTO_IPD // always true // default: // throw, but case never happens default: throw Error.runtimeError(ErrorCode.U_S0500, "Result"); } break; } case ResultConstants.REQUESTDATA: { rowOut.writeLong(id); rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); break; } case ResultConstants.DATAROWS: metaData.write(rowOut); navigator.write(rowOut, metaData); break; case ResultConstants.DATAHEAD: case ResultConstants.DATA: case ResultConstants.GENERATED: rowOut.writeLong(id); rowOut.writeInt(updateCount); rowOut.writeInt(fetchSize); rowOut.writeByte(rsProperties); metaData.write(rowOut); navigator.write(rowOut, metaData); break; default: throw Error.runtimeError(ErrorCode.U_S0500, "Result"); } rowOut.writeIntData(rowOut.size() - startPos, startPos); dataOut.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.size()); int count = getLobCount(); Result current = this; for (int i = 0; i < count; i++) { ResultLob lob = current.lobResults; lob.writeBody(session, dataOut); current = current.lobResults; } if (chainedResult == null) { dataOut.writeByte(ResultConstants.NONE); } else { chainedResult.write(session, dataOut, rowOut); } dataOut.flush(); }