Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2019,2020 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.vertx.db2client.impl.drda;
import java.nio.charset.Charset;
import java.util.ArrayDeque;
import java.util.Deque;
import io.netty.buffer.ByteBuf;
public abstract class DRDAResponse {
final ByteBuf buffer;
final ConnectionMetaData metadata;
Deque ddmCollectionLenStack = new ArrayDeque<>(4);
int ddmScalarLen_ = 0; // a value of -1 -> streamed ddm -> length unknown
protected int dssLength_;
boolean dssIsContinued_;
private boolean dssIsChainedWithSameID_;
private int dssCorrelationID_ = 1;
protected int peekedLength_ = 0;
int peekedCodePoint_ = END_OF_COLLECTION; // saves the peeked codept
int peekedNumOfExtendedLenBytes_ = 0;
final static int END_OF_COLLECTION = -1;
final static int END_OF_SAME_ID_CHAIN = -2;
final static int END_OF_BUFFER = -3;
public DRDAResponse(ByteBuf buffer, ConnectionMetaData metadata) {
this.buffer = buffer;
this.metadata = metadata;
}
protected final void startSameIdChainParse() {
// TODO: remove this method once everything is ported
readDssHeader();
}
protected final void endOfSameIdChainData() {
if (!ddmCollectionLenStack.isEmpty()) {
throw new IllegalStateException("SQLState.NET_COLLECTION_STACK_NOT_EMPTY");
// agent_.accumulateChainBreakingReadExceptionAndThrow(
// new DisconnectException(agent_,
// new ClientMessageId(SQLState.NET_COLLECTION_STACK_NOT_EMPTY)));
}
if (this.dssLength_ != 0) {
throw new IllegalStateException("SQLState.NET_DSS_NOT_ZERO " + dssLength_);
// agent_.accumulateChainBreakingReadExceptionAndThrow(
// new DisconnectException(agent_,
// new ClientMessageId(SQLState.NET_DSS_NOT_ZERO)));
}
if (dssIsChainedWithSameID_ == true) {
throw new IllegalStateException("SQLState.NET_DSS_CHAINED_WITH_SAME_ID");
// agent_.accumulateChainBreakingReadExceptionAndThrow(
// new DisconnectException(agent_,
// new ClientMessageId(SQLState.NET_DSS_CHAINED_WITH_SAME_ID)));
}
}
// The End Unit of Work Condition (ENDUOWRM) Reply Mesage specifies
// that the unit of work has ended as a result of the last command.
//
// Returned from Server:
// SVRCOD - required (4 WARNING)
// UOWDSP - required
// RDBNAM - optional
void parseENDUOWRM() {
boolean svrcodReceived = false;
int svrcod = CodePoint.SVRCOD_INFO;
boolean uowdspReceived = false;
int uowdsp = 0;
boolean rdbnamReceived = false;
String rdbnam = null;
parseLengthAndMatchCodePoint(CodePoint.ENDUOWRM);
pushLengthOnCollectionStack();
int peekCP = peekCodePoint();
while (peekCP != END_OF_COLLECTION) {
boolean foundInPass = false;
if (peekCP == CodePoint.SVRCOD) {
foundInPass = true;
svrcodReceived = checkAndGetReceivedFlag(svrcodReceived);
svrcod = parseSVRCOD(CodePoint.SVRCOD_WARNING, CodePoint.SVRCOD_WARNING);
peekCP = peekCodePoint();
}
if (peekCP == CodePoint.UOWDSP) {
foundInPass = true;
uowdspReceived = checkAndGetReceivedFlag(uowdspReceived);
uowdsp = parseUOWDSP();
peekCP = peekCodePoint();
}
if (peekCP == CodePoint.RDBNAM) {
foundInPass = true;
rdbnamReceived = checkAndGetReceivedFlag(rdbnamReceived);
rdbnam = parseRDBNAM(true);
peekCP = peekCodePoint();
}
if (peekCP == CodePoint.RLSCONV) {
foundInPass = true;
parseRLSCONV();
peekCP = peekCodePoint();
}
if (!foundInPass) {
throwUnknownCodepoint(peekCP);
}
}
popCollectionStack();
if (!svrcodReceived)
throwMissingRequiredCodepoint("SVRCOD", CodePoint.SVRCOD);
if (!uowdspReceived)
throwMissingRequiredCodepoint("UOWDSP", CodePoint.UOWDSP);
// netAgent_.setSvrcod(svrcod);
// if (uowdsp == CodePoint.UOWDSP_COMMIT) {
// connection.completeLocalCommit();
// } else {
// connection.completeLocalRollback();
// }
if (uowdsp == CodePoint.UOWDSP_COMMIT) {
//System.out.println("@AGG commit completed normally");
}
}
private int parseRLSCONV() {
parseLengthAndMatchCodePoint(CodePoint.RLSCONV);
int i = readUnsignedByte();
if (i != 0xF0 && // NO_TERM
i != 0xF1 && // TERM
i != 0xF2) { // REUSE
throw new IllegalStateException("Unknown value for RLSCONV: " + Integer.toHexString(i));
}
return i;
}
// Relational Database Name specifies the name of a relational
// database of the server. A server can have more than one RDB.
String parseRDBNAM(boolean skip) {
parseLengthAndMatchCodePoint(CodePoint.RDBNAM);
if (skip) {
skipBytes();
return null;
}
return readString();
}
// Unit of Work Disposition Scalar Object specifies the disposition of the
// last unit of work.
private int parseUOWDSP() {
parseLengthAndMatchCodePoint(CodePoint.UOWDSP);
int uowdsp = readUnsignedByte();
if ((uowdsp != CodePoint.UOWDSP_COMMIT) && (uowdsp != CodePoint.UOWDSP_ROLLBACK)) {
doValnsprmSemantics(CodePoint.UOWDSP, uowdsp);
}
return uowdsp;
}
NetSqlca parseSQLCARD(NetSqlca[] rowsetSqlca) {
parseLengthAndMatchCodePoint(CodePoint.SQLCARD);
int ddmLength = getDdmLength();
ensureBLayerDataInBuffer(ddmLength);
NetSqlca netSqlca = parseSQLCARDrow(rowsetSqlca);
adjustLengths(getDdmLength());
return netSqlca;
}
// SQLCAGRP : FDOCA EARLY GROUP
// SQL Communcations Area Group Description
// See DRDA V3 Vol 1 pg. 280
//
// FORMAT FOR SQLAM <= 6
// SQLCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLSTATE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
// SQLERRPROC; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
// SQLCAXGRP; PROTOCOL TYPE N-GDA; ENVLID 0x52; Length Override 0
//
// FORMAT FOR SQLAM >= 7
// SQLCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLSTATE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
// SQLERRPROC; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
// SQLCAXGRP; PROTOCOL TYPE N-GDA; ENVLID 0x52; Length Override 0
// SQLDIAGGRP; PROTOCOL TYPE N-GDA; ENVLID 0x56; Length Override 0
NetSqlca parseSQLCAGRP(NetSqlca[] rowsetSqlca) {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return null;
}
int sqlcode = readFastInt();
byte[] sqlstate = readFastBytes(5);
byte[] sqlerrproc = readFastBytes(8);
NetSqlca netSqlca = null;
netSqlca = new NetSqlca(sqlcode, sqlstate, sqlerrproc);
parseSQLCAXGRP(netSqlca);
if (DRDAConstants.TARGET_SQL_AM >= DRDAConstants.MGRLVL_7) {
netSqlca.setRowsetRowCount(parseSQLDIAGGRP(rowsetSqlca));
}
return netSqlca;
}
// SQLDIAGGRP : FDOCA EARLY GROUP
// See DRDA V3 Vol 1 pg. 283
// SQL Diagnostics Group Description - Identity 0xD1
// Nullable Group
// SQLDIAGSTT; PROTOCOL TYPE N-GDA; ENVLID 0xD3; Length Override 0
// SQLDIAGCN; DRFA TYPE N-RLO; ENVLID 0xF6; Length Override 0
// SQLDIAGCI; PROTOCOL TYPE N-RLO; ENVLID 0xF5; Length Override 0
private long parseSQLDIAGGRP(NetSqlca[] rowsetSqlca) {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return 0;
}
long row_count = parseSQLDIAGSTT(rowsetSqlca);
parseSQLDIAGCI(rowsetSqlca);
parseSQLDIAGCN();
return row_count;
}
// SQL Diagnostics Connection Array - Identity 0xF6
// SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1
// SQLCNROW; ROW LID 0xE6; ELEMENT TAKEN 0(all); REP FACTOR 0(all)
private void parseSQLDIAGCN() {
if (readUnsignedByte() == CodePoint.NULLDATA) {
return;
}
int num = parseFastSQLNUMROW();
for (int i = 0; i < num; i++) {
parseSQLCNROW();
}
}
// SQL Diagnostics Connection Row - Identity 0xE6
// SQLCNGRP; GROUP LID 0xD6; ELEMENT TAKEN 0(all); REP FACTOR 1
private void parseSQLCNROW() {
parseSQLCNGRP();
}
// SQL Diagnostics Connection Group Description - Identity 0xD6
// Nullable
//
// SQLCNSTATE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLCNSTATUS; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLCNATYPE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLCNETYPE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLCNPRDID; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
// SQLCNRDB; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 1024
// SQLCNCLASS; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
// SQLCNAUTHID; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
private void parseSQLCNGRP() {
skipBytes(18);
String sqlcnRDB = parseFastVCS(); // RDBNAM
String sqlcnClass = parseFastVCS(); // CLASS_NAME
String sqlcnAuthid = parseFastVCS(); // AUTHID
}
// SQLNUMROW : FDOCA EARLY ROW
// SQL Number of Elements Row Description
//
// FORMAT FOR SQLAM LEVELS
// SQLNUMGRP; GROUP LID 0x58; ELEMENT TAKEN 0(all); REP FACTOR 1
int parseSQLNUMROW() {
return parseSQLNUMGRP();
}
int parseFastSQLNUMROW() {
return parseFastSQLNUMGRP();
}
// SQLNUMGRP : FDOCA EARLY GROUP
// SQL Number of Elements Group Description
//
// FORMAT FOR ALL SQLAM LEVELS
// SQLNUM; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2
private int parseSQLNUMGRP() {
return readShort();
}
private int parseFastSQLNUMGRP() {
return readFastShort();
}
// SQL Diagnostics Statement Group Description - Identity 0xD3
// Nullable Group
// SQLDSFCOD; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSCOST; PROTOCOL TYPE I4; ENVLID 0X02; Length Override 4
// SQLDSLROW; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSNPM; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSNRS; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSRNS; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSDCOD; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDSROWC; PROTOCOL TYPE FD; ENVLID 0x0E; Length Override 31
// SQLDSNROW; PROTOCOL TYPE FD; ENVLID 0x0E; Length Override 31
// SQLDSROWCS; PROTOCOL TYPE FD; ENVLID 0x0E; Length Override 31
// SQLDSACON; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSACRH; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSACRS; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSACSL; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSACSE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSACTY; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSCERR; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLDSMORE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
private long parseSQLDIAGSTT(NetSqlca[] rowsetSqlca) {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return 0;
}
int sqldsFcod = readFastInt(); // FUNCTION_CODE
int sqldsCost = readFastInt(); // COST_ESTIMATE
int sqldsLrow = readFastInt(); // LAST_ROW
skipFastBytes(16);
long sqldsRowc = readFastLong(); // ROW_COUNT
//System.out.println("@AGG row count: " + sqldsRowc);
skipFastBytes(24);
return sqldsRowc;
}
// SQL Diagnostics Condition Information Array - Identity 0xF5
// SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1
// SQLDCIROW; ROW LID 0xE5; ELEMENT TAKEN 0(all); REP FACTOR 0(all)
private void parseSQLDIAGCI(NetSqlca[] rowsetSqlca) {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return;
}
int num = parseFastSQLNUMROW();
if (num == 0) {
resetRowsetSqlca(rowsetSqlca, 0);
}
// lastRow is the row number for the last row that had a non-null SQLCA.
int lastRow = 1;
for (int i = 0; i < num; i++) {
lastRow = parseSQLDCROW(rowsetSqlca, lastRow);
}
resetRowsetSqlca(rowsetSqlca, lastRow + 1);
}
private void resetRowsetSqlca(NetSqlca[] rowsetSqlca, int row) {
// rowsetSqlca can be null.
int count = ((rowsetSqlca == null) ? 0 : rowsetSqlca.length);
for (int i = row; i < count; i++) {
rowsetSqlca[i] = null;
}
}
// SQL Diagnostics Condition Row - Identity 0xE5
// SQLDCGRP; GROUP LID 0xD5; ELEMENT TAKEN 0(all); REP FACTOR 1
private int parseSQLDCROW(NetSqlca[] rowsetSqlca, int lastRow) {
return parseSQLDCGRP(rowsetSqlca, lastRow);
}
// SQL Diagnostics Condition Group Description
//
// SQLDCCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCSTATE; PROTOCOL TYPE FCS; ENVLID Ox30; Lengeh Override 5
// SQLDCREASON; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCLINEN; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCROWN; PROTOCOL TYPE FD; ENVLID 0x0E; Lengeh Override 31
// SQLDCER01; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCER02; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCER03; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCER04; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCPART; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCPPOP; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLDCMSGID; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 10
// SQLDCMDE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
// SQLDCPMOD; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
// SQLDCRDB; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
// SQLDCTOKS; PROTOCOL TYPE N-RLO; ENVLID 0xF7; Length Override 0
// SQLDCMSG_m; PROTOCOL TYPE NVMC; ENVLID 0x3F; Length Override 32672
// SQLDCMSG_S; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 32672
// SQLDCCOLN_m; PROTOCOL TYPE NVCM ; ENVLID 0x3F; Length Override 255
// SQLDCCOLN_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCCURN_m; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCCURN_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCPNAM_m; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCPNAM_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXGRP; PROTOCOL TYPE N-GDA; ENVLID 0xD3; Length Override 1
private int parseSQLDCGRP(NetSqlca[] rowsetSqlca, int lastRow) {
int sqldcCode = readFastInt(); // SQLCODE
String sqldcState = readFastString(5, CCSIDConstants.UTF8); // SQLSTATE
int sqldcReason = readFastInt(); // REASON_CODE
int sqldcLinen = readFastInt(); // LINE_NUMBER
int sqldcRown = (int) readFastLong(); // ROW_NUMBER
// save +20237 in the 0th entry of the rowsetSqlca's.
// this info is going to be used when a subsequent fetch prior is issued, and if already
// received a +20237 then we've gone beyond the first row and there is no need to
// flow another fetch to the server.
if (sqldcCode == 20237) {
rowsetSqlca[0] = new NetSqlca(sqldcCode,
sqldcState,
null);
} else {
if (rowsetSqlca[sqldcRown] != null) {
rowsetSqlca[sqldcRown].resetRowsetSqlca(sqldcCode,
sqldcState);
} else {
rowsetSqlca[sqldcRown] = new NetSqlca(sqldcCode,
sqldcState,
null);
}
}
// reset all entries between lastRow and sqldcRown to null
for (int i = lastRow + 1; i < sqldcRown; i++) {
rowsetSqlca[i] = null;
}
skipFastBytes(47);
String sqldcRdb = parseFastVCS(); // RDBNAM
// skip the tokens for now, since we already have the complete message.
parseSQLDCTOKS(); // MESSAGE_TOKENS
String sqldcMsg = parseFastNVCMorNVCS(); // MESSAGE_TEXT
// skip the following for now.
skipFastNVCMorNVCS(); // COLUMN_NAME
skipFastNVCMorNVCS(); // PARAMETER_NAME
skipFastNVCMorNVCS(); // EXTENDED_NAMES
parseSQLDCXGRP(); // SQLDCXGRP
return sqldcRown;
}
// Severity Code is an indicator of the severity of a condition
// detected during the execution of a command.
int parseSVRCOD(int minSvrcod, int maxSvrcod) {
parseLengthAndMatchCodePoint(CodePoint.SVRCOD);
int svrcod = readUnsignedShort();
if ((svrcod != CodePoint.SVRCOD_INFO) &&
(svrcod != CodePoint.SVRCOD_WARNING) &&
(svrcod != CodePoint.SVRCOD_ERROR) &&
(svrcod != CodePoint.SVRCOD_SEVERE) &&
(svrcod != CodePoint.SVRCOD_ACCDMG) &&
(svrcod != CodePoint.SVRCOD_PRMDMG) &&
(svrcod != CodePoint.SVRCOD_SESDMG)) {
doValnsprmSemantics(CodePoint.SVRCOD, svrcod);
}
if (svrcod < minSvrcod || svrcod > maxSvrcod) {
doValnsprmSemantics(CodePoint.SVRCOD, svrcod);
}
return svrcod;
}
// Also called by NetStatementReply
void doValnsprmSemantics(int codePoint, int value) {
doValnsprmSemantics(codePoint, Integer.toString(value));
}
void doValnsprmSemantics(int codePoint, String value) {
// special case the FDODTA codepoint not to disconnect.
if (codePoint == CodePoint.FDODTA) {
throw new IllegalStateException("SQLState.DRDA_DDM_PARAMVAL_NOT_SUPPORTED codePoint=" + Integer.toHexString(codePoint));
// agent_.accumulateReadException(new SqlException(agent_.logWriter_,
// new ClientMessageId(SQLState.DRDA_DDM_PARAMVAL_NOT_SUPPORTED),
// Integer.toHexString(codePoint)));
}
if (codePoint == CodePoint.CCSIDSBC ||
codePoint == CodePoint.CCSIDDBC ||
codePoint == CodePoint.CCSIDMBC) {
// the server didn't like one of the ccsids.
// the message should reflect the error in question. right now these values
// will be hard coded but this won't be correct if our driver starts sending
// other values to the server. In order to pick up the correct values,
// a little reorganization may need to take place so that this code (or
// whatever code sets the message) has access to the correct values.
int cpValue = 0;
switch (codePoint) {
case CodePoint.CCSIDSBC:
cpValue = Typdef.typdef.getCcsidSbc();
break;
case CodePoint.CCSIDDBC:
cpValue = Typdef.typdef.getCcsidDbc();
break;
case CodePoint.CCSIDMBC:
cpValue = Typdef.typdef.getCcsidSbc();
break;
default:
// should never be in this default case...
break;
}
throw new IllegalStateException("SQLState.DRDA_NO_AVAIL_CODEPAGE_CONVERSION");
// agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_,
// new ClientMessageId(SQLState.DRDA_NO_AVAIL_CODEPAGE_CONVERSION),
// cpValue, value));
// return;
}
// the problem isn't with one of the ccsid values so...
throw new IllegalStateException("SQLState.DRDA_DDM_PARAMVAL_NOT_SUPPORTED");
// Returning more information would
// require rearranging this code a little.
// agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_,
// new ClientMessageId(SQLState.DRDA_DDM_PARAMVAL_NOT_SUPPORTED),
// Integer.toHexString(codePoint)));
}
// SQL Diagnostics Extended Names Group Description - Identity 0xD5
// Nullable
//
// SQLDCXRDB_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 1024
// SQLDCXSCH_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXNAM_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXTBLN_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXRDB_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 1024
// SQLDCXSCH_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXNAM_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXTBLN_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
//
// SQLDCXCRDB_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 1024
// SQLDCXCSCH_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXCNAM_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXCRDB_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 1024
// SQLDCXCSCH_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXCNAM_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
//
// SQLDCXRRDB_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 1024
// SQLDCXRSCH_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXRNAM_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXRRDB_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 1024
// SQLDCXRSCH_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXRNAM_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
//
// SQLDCXTRDB_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 1024
// SQLDCXTSCH_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXTNAM_m ; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
// SQLDCXTRDB_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 1024
// SQLDCXTSCH_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
// SQLDCXTNAM_s ; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
private void parseSQLDCXGRP() {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return;
}
skipFastNVCMorNVCS(); // OBJECT_RDBNAM
skipFastNVCMorNVCS(); // OBJECT_SCHEMA
skipFastNVCMorNVCS(); // SPECIFIC_NAME
skipFastNVCMorNVCS(); // TABLE_NAME
String sqldcxCrdb = parseFastVCS(); // CONSTRAINT_RDBNAM
skipFastNVCMorNVCS(); // CONSTRAINT_SCHEMA
skipFastNVCMorNVCS(); // CONSTRAINT_NAME
parseFastVCS(); // ROUTINE_RDBNAM
skipFastNVCMorNVCS(); // ROUTINE_SCHEMA
skipFastNVCMorNVCS(); // ROUTINE_NAME
parseFastVCS(); // TRIGGER_RDBNAM
skipFastNVCMorNVCS(); // TRIGGER_SCHEMA
skipFastNVCMorNVCS(); // TRIGGER_NAME
}
private String parseFastNVCMorNVCS() {
String stringToBeSet = null;
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
int vcm_length = readFastUnsignedShort();
if (vcm_length > 0) {
stringToBeSet = readFastString(vcm_length, Typdef.targetTypdef.getCcsidMbcEncoding());
}
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
throw new IllegalStateException("SQLState.NET_NVCM_NVCS_BOTH_NON_NULL");
// agent_.accumulateChainBreakingReadExceptionAndThrow(
// new DisconnectException(agent_,
// new ClientMessageId(
// SQLState.NET_NVCM_NVCS_BOTH_NON_NULL)));
}
} else {
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
int vcs_length = readFastUnsignedShort();
if (vcs_length > 0) {
stringToBeSet = readFastString(vcs_length, Typdef.targetTypdef.getCcsidSbcEncoding());
}
}
}
return stringToBeSet;
}
// SQL Diagnostics Condition Token Array - Identity 0xF7
// SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1
// SQLTOKROW; ROW LID 0xE7; ELEMENT TAKEN 0(all); REP FACTOR 0(all)
private void parseSQLDCTOKS() {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
return;
}
int num = parseFastSQLNUMROW();
for (int i = 0; i < num; i++) {
parseSQLTOKROW();
}
}
// SQL Diagnostics Token Row - Identity 0xE7
// SQLTOKGRP; GROUP LID 0xD7; ELEMENT TAKEN 0(all); REP FACTOR 1
private void parseSQLTOKROW() {
parseSQLTOKGRP();
}
// check on SQLTOKGRP format
private void parseSQLTOKGRP() {
skipFastNVCMorNVCS();
}
private void skipFastNVCMorNVCS() {
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
int vcm_length = readFastUnsignedShort();
if (vcm_length > 0)
{
skipFastBytes(vcm_length);
}
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
throw new IllegalStateException("SQLState.NET_NVCM_NVCS_BOTH_NON_NULL");
// agent_.accumulateChainBreakingReadExceptionAndThrow(
// new DisconnectException(agent_,
// new ClientMessageId(
// SQLState.NET_NVCM_NVCS_BOTH_NON_NULL)));
}
} else {
if (readFastUnsignedByte() != CodePoint.NULLDATA) {
int vcs_length = readFastUnsignedShort();
if (vcs_length > 0)
{
skipFastBytes(vcs_length);
}
}
}
}
// SQLCAXGRP : EARLY FDOCA GROUP
// SQL Communications Area Exceptions Group Description
// See DRDA V3 Vol 1 pg. 281
//
// FORMAT FOR SQLAM <= 6
// SQLRDBNME; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 18
// SQLERRD1; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD2; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD3; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD4; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD5; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLWARN0; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN1; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN2; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN3; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN4; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN5; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN6; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN7; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN8; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN9; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
// SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
//
// FORMAT FOR SQLAM >= 7
// SQLERRD1; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD2; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD3; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD4; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD5; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
// SQLWARN0; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN1; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN2; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN3; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN4; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN5; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN6; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN7; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN8; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARN9; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
// SQLRDBNAME; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 1024
// SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
// SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
private void parseSQLCAXGRP(NetSqlca netSqlca) {
if (readFastUnsignedByte() == CodePoint.NULLDATA) {
netSqlca.setContainsSqlcax(false);
return;
}
// if (DRDAConstants.TARGET_SQL_AM < DRDAConstants.MGRLVL_7) {
// // skip over the rdbnam for now
// // SQLRDBNME; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 18
// skipFastBytes(18);
// }
// SQLERRD1 to SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
int[] sqlerrd = new int[ NetSqlca.SQL_ERR_LENGTH ];
readFastIntArray(sqlerrd);
// SQLWARN0 to SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
byte[] sqlwarn = readFastBytes(11);
if (DRDAConstants.TARGET_SQL_AM >= DRDAConstants.MGRLVL_7) {
// skip over the rdbnam for now
// SQLRDBNAME; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 1024
String rdbname = parseFastVCS();
}
int sqlerrmcCcsid;
byte[] sqlerrmc = readFastLDBytes();
if (sqlerrmc != null) {
sqlerrmcCcsid = Typdef.targetTypdef.getCcsidMbc();
skipFastBytes(2);
} else {
sqlerrmc = readFastLDBytes();
sqlerrmcCcsid = Typdef.targetTypdef.getCcsidSbc();
}
netSqlca.setSqlerrd(sqlerrd);
netSqlca.setSqlwarnBytes(sqlwarn);
netSqlca.setSqlerrmcBytes(sqlerrmc); // sqlerrmc may be null
}
// this is duplicated in parseColumnMetaData, but different
// DAGroup under NETColumnMetaData requires a lot more stuffs including
// precsion, scale and other stuffs
String parseFastVCMorVCS() {
String stringToBeSet = null;
int vcm_length = readFastUnsignedShort();
if (vcm_length > 0) {
stringToBeSet = readFastString(vcm_length, Typdef.targetTypdef.getCcsidMbcEncoding());
}
int vcs_length = readFastUnsignedShort();
if (vcm_length > 0 && vcs_length > 0) {
throw new IllegalStateException("SQLState.NET_VCM_VCS_LENGTHS_INVALID: VCM and VCS lengths are mutually exclusive " +
"but both were set: vcsLen=" + vcs_length + " vcmLen=" + vcm_length);
// agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_,
// new ClientMessageId(SQLState.NET_VCM_VCS_LENGTHS_INVALID)));
} else if (vcs_length > 0) {
stringToBeSet = readFastString(vcs_length, Typdef.targetTypdef.getCcsidSbcEncoding());
}
return stringToBeSet;
}
// SQLCARD : FDOCA EARLY ROW
// SQL Communications Area Row Description
//
// FORMAT FOR ALL SQLAM LEVELS
// SQLCAGRP; GROUP LID 0x54; ELEMENT TAKEN 0(all); REP FACTOR 1
NetSqlca parseSQLCARDrow(NetSqlca[] rowsetSqlca) {
return parseSQLCAGRP(rowsetSqlca);
}
int parseTypdefsOrMgrlvlovrs() {
boolean targetTypedefCloned = false;
while (true) {
int peekCP = peekCodePoint();
if (peekCP == CodePoint.TYPDEFNAM) {
if (!targetTypedefCloned) {
//netAgent_.targetTypdef_ = (Typdef) netAgent_.targetTypdef_.clone(); @AGG not sure if used?
targetTypedefCloned = true;
}
parseTYPDEFNAM();
} else if (peekCP == CodePoint.TYPDEFOVR) {
if (!targetTypedefCloned) {
//netAgent_.targetTypdef_ = (Typdef) netAgent_.targetTypdef_.clone(); @AGG not sure if used?
targetTypedefCloned = true;
}
parseTYPDEFOVR();
} else {
return peekCP;
}
}
}
void parseTYPDEFNAM() {
parseLengthAndMatchCodePoint(CodePoint.TYPDEFNAM);
String typedef = readString();
Typdef.targetTypdef.setTypdefnam(typedef);
}
void parseTYPDEFOVR() {
parseLengthAndMatchCodePoint(CodePoint.TYPDEFOVR);
pushLengthOnCollectionStack();
int peekCP = peekCodePoint();
while (peekCP != END_OF_COLLECTION) {
boolean foundInPass = false;
if (peekCP == CodePoint.CCSIDSBC) {
foundInPass = true;
Typdef.targetTypdef.setCcsidSbc(parseCCSIDSBC());
peekCP = peekCodePoint();
}
if (peekCP == CodePoint.CCSIDDBC) {
foundInPass = true;
Typdef.targetTypdef.setCcsidDbc(parseCCSIDDBC());
peekCP = peekCodePoint();
}
if (peekCP == CodePoint.CCSIDMBC) {
foundInPass = true;
Typdef.targetTypdef.setCcsidMbc(parseCCSIDMBC());
peekCP = peekCodePoint();
}
// @AGG added this block
if (peekCP == CodePoint.CCSIDXML) {
parseLengthAndMatchCodePoint(CodePoint.CCSIDXML);
readUnsignedShort();
peekCP = peekCodePoint();
}
if (!foundInPass) {
throwUnknownCodepoint(peekCP);
//doPrmnsprmSemantics(peekCP);
}
}
popCollectionStack();
}
static void throwUnknownCodepoint(int codepoint) {
throw new IllegalStateException("Found unknown codepoint: 0x" + Integer.toHexString(codepoint) + " / " + codepoint);
}
static void throwMissingRequiredCodepoint(String codepointStr, int expectedCodepoint) {
throw new IllegalStateException("Did not find required " + codepointStr + " (" + Integer.toHexString(expectedCodepoint) + ") codepoint");
}
// CCSID for Single-Byte Characters specifies a coded character
// set identifier for single-byte characters.
private int parseCCSIDSBC() {
parseLengthAndMatchCodePoint(CodePoint.CCSIDSBC);
return readUnsignedShort();
}
// CCSID for Mixed-Byte Characters specifies a coded character
// set identifier for mixed-byte characters.
private int parseCCSIDMBC() {
parseLengthAndMatchCodePoint(CodePoint.CCSIDMBC);
return readUnsignedShort();
}
// CCSID for Double-Byte Characters specifies a coded character
// set identifier for double-byte characters.
private int parseCCSIDDBC() {
parseLengthAndMatchCodePoint(CodePoint.CCSIDDBC);
return readUnsignedShort();
}
private void readDssHeader() {
int correlationID;
int nextCorrelationID;
ensureALayerDataInBuffer(6);
// read out the dss length
dssLength_ = buffer.readUnsignedShort();
// Remember the old dss length for decryption only.
int oldDssLength = dssLength_;
// check for the continuation bit and update length as needed.
if ((dssLength_ & 0x8000) == 0x8000) {
dssLength_ = 32767;
dssIsContinued_ = true;
} else {
dssIsContinued_ = false;
}
if (dssLength_ < 6) {
throw new IllegalStateException("DSS header length must be at least 6 bytes but was: " + dssLength_);
// doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_LESS_THAN_6);
}
// If the GDS id is not valid, or
// if the reply is not an RPYDSS nor
// a OBJDSS, then throw an exception.
byte magic = buffer.readByte();
if (magic != (byte) 0xd0) {
throw new IllegalStateException(String.format("Magic bit needs to be 0xD0 but was %02x", magic));
// doSyntaxrmSemantics(CodePoint.SYNERRCD_CBYTE_NOT_D0);
}
int gdsFormatter = buffer.readByte() & 0xFF;
if (((gdsFormatter & 0x02) != 0x02) && ((gdsFormatter & 0x03) != 0x03) && ((gdsFormatter & 0x04) != 0x04)) {
throw new IllegalStateException("CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED");
// doSyntaxrmSemantics(CodePoint.SYNERRCD_FBYTE_NOT_SUPPORTED);
}
// Determine if the current DSS is chained with the
// next DSS, with the same or different request ID.
if ((gdsFormatter & 0x40) == 0x40) { // on indicates structure chained to next structure
if ((gdsFormatter & 0x10) == 0x10) {
dssIsChainedWithSameID_ = true;
nextCorrelationID = dssCorrelationID_;
} else {
dssIsChainedWithSameID_ = false;
nextCorrelationID = dssCorrelationID_ + 1;
}
} else {
// chaining bit not b'1', make sure DSSFMT bit3 not b'1'
if ((gdsFormatter & 0x10) == 0x10) { // Next DSS can not have same correlator
throw new IllegalStateException("CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR");
// doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_SAME_NEXT_CORRELATOR);
}
// chaining bit not b'1', make sure no error continuation
if ((gdsFormatter & 0x20) == 0x20) { // must be 'do not continue on error'
throw new IllegalStateException("CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE");
// doSyntaxrmSemantics(CodePoint.SYNERRCD_CHAIN_OFF_ERROR_CONTINUE);
}
dssIsChainedWithSameID_ = false;
nextCorrelationID = 1;
}
correlationID = buffer.readShort();
// corrid must be the one expected or a -1 which gets returned in some error cases.
if ((correlationID != dssCorrelationID_) && (correlationID != -1)) {
// doSyntaxrmSemantics(CodePoint.SYNERRCD_INVALID_CORRELATOR);
throw new IllegalStateException(
"Invalid correlator ID. Got " + correlationID + " expected " + dssCorrelationID_);
} else {
dssCorrelationID_ = nextCorrelationID;
}
dssLength_ -= 6;
// if ((gdsFormatter & 0x04) == 0x04) {
// decryptData(gdsFormatter, oldDssLength); //we have to decrypt data here
// because
// }
// we need the decrypted codepoint. If
// Data is very long > 32767, we have to
// get all the data first because decrypt
// piece by piece doesn't work.
}
// reads a DSS continuation header
// prereq: pos_ is positioned on the first byte of the two-byte header
// post: dssIsContinued_ is set to true if the continuation bit is on, false otherwise
// dssLength_ is set to DssConstants.MAX_DSS_LEN - 2 (don't count the header for the next read)
// helper method for getEXTDTAData
void readDSSContinuationHeader() {
ensureALayerDataInBuffer(2);
dssLength_ = buffer.readUnsignedShort();
// ((buffer_[pos_++] & 0xFF) << 8) +
// ((buffer_[pos_++] & 0xFF) << 0);
if ((dssLength_ & 0x8000) == 0x8000) {
dssLength_ = DssConstants.MAX_DSS_LENGTH;
dssIsContinued_ = true;
} else {
dssIsContinued_ = false;
}
// it is a syntax error if the dss continuation header length
// is less than or equal to two
if (dssLength_ <= 2) {
doSyntaxrmSemantics(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2);
}
dssLength_ -= 2; // avoid consuming the DSS cont header
}
final String readString() {
return readString(metadata.getCCSID());
// String result = currentCCSID.decode(buffer);
// netAgent_.getCurrentCcsidManager()
// .convertToJavaString(buffer_, pos_, len);
// pos_ += len;
// return result;
}
final String readString(Charset encoding) {
return readString(ddmScalarLen_, encoding);
}
final String readString(int length, Charset encoding) {
ensureBLayerDataInBuffer(length);
adjustLengths(length);
String s = buffer.readCharSequence(length, encoding).toString();
//String s = new String(buffer.array(), pos_, length, encoding);
//pos_ += length;
return s;
}
final short readShort() {
// should we be checking dss lengths and ddmScalarLengths here
ensureBLayerDataInBuffer(2);
adjustLengths(2);
// short s = SignedBinary.getShort(buffer_, pos_);
//pos_ += 2;
if (metadata.isZos())
return buffer.readShort();
else
return buffer.readShortLE();
}
boolean checkAndGetReceivedFlag(boolean receivedFlag){
if (receivedFlag) {
// this method will throw a disconnect exception if
// the received flag is already true;
doSyntaxrmSemantics(CodePoint.SYNERRCD_DUP_OBJ_PRESENT);
}
return true;
}
final void doSyntaxrmSemantics(int syntaxErrorCode) {
throw new IllegalStateException("SQLState.DRDA_CONNECTION_TERMINATED CONN_DRDA_DATASTREAM_SYNTAX_ERROR " + syntaxErrorCode);
// DisconnectException e = new DisconnectException(agent_,
// new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED),
// SqlException.getMessageUtil().getTextMessage(
// MessageId.CONN_DRDA_DATASTREAM_SYNTAX_ERROR,
// syntaxErrorCode));
// if we are communicating to an older server, we may get a SYNTAXRM on
// ACCSEC (missing codepoint RDBNAM) if we were unable to convert to
// EBCDIC. In that case we should chain
// the original conversion exception, so it is clear to the user what
// the problem was.
// if (netAgent_.exceptionConvertingRdbnam != null) {
// e.setNextException(netAgent_.exceptionConvertingRdbnam);
// netAgent_.exceptionConvertingRdbnam = null;
// }
// agent_.accumulateChainBreakingReadExceptionAndThrow(e);
}
// Read "length" number of bytes from the buffer into the byte array b starting from offset
// "offset". The current offset in the buffer does not change.
protected final int peekFastBytes(byte[] b, int offset, int length) {
for (int i = 0; i < length; i++) {
b[offset + i] = buffer.getByte(buffer.readerIndex() + i);
// b[offset + i] = buffer_[pos_ + i];
}
return offset + length;
}
protected final int peekFastLength() {
return buffer.getUnsignedShort(buffer.readerIndex());
// return (((buffer_[pos_] & 0xff) << 8) +
// ((buffer_[pos_ + 1] & 0xff) << 0));
}
protected final int peekCodePoint() {
if (!ddmCollectionLenStack.isEmpty()) {
if (ddmCollectionLenStack.peek() == 0) {
return END_OF_COLLECTION;
} else if (ddmCollectionLenStack.peek() < 4) {
// error
throw new IllegalStateException("Invalid ddm collection length: " + ddmCollectionLenStack.peek());
}
}
// if there is no more data in the current dss, and the dss is not
// continued, indicate the end of the same Id chain or read the next dss header.
if ((dssLength_ == 0) && (!dssIsContinued_)) {
if (!dssIsChainedWithSameID_) {
return END_OF_SAME_ID_CHAIN;
}
if (!buffer.isReadable()) {
return END_OF_BUFFER;
}
readDssHeader();
}
// if (longBufferForDecryption_ == null) //we don't need to do this if it's data
// stream encryption
// {
// ensureBLayerDataInBuffer(4);
// }
peekedLength_ = buffer.getUnsignedShort(buffer.readerIndex()); //buffer.readShort();// ((buffer_[pos_] & 0xff) << 8) + ((buffer_[pos_ + 1] & 0xff) << 0);
peekedCodePoint_ = buffer.getUnsignedShort(buffer.readerIndex() + 2); //buffer.readShort(); // ((buffer_[pos_ + 2] & 0xff) << 8) + ((buffer_[pos_ + 3] & 0xff) << 0);
// check for extended length
if ((peekedLength_ & 0x8000) == 0x8000) {
peekExtendedLength();
} else {
peekedNumOfExtendedLenBytes_ = 0;
}
return peekedCodePoint_;
}
protected final void pushLengthOnCollectionStack() {
ddmCollectionLenStack.push(ddmScalarLen_);
ddmScalarLen_ = 0;
// System.out.println("@AGG pushed length: " + ddmCollectionLenStack);
}
protected final void parseLengthAndMatchCodePoint(int expectedCodePoint) {
int actualCodePoint = 0;
if (peekedCodePoint_ == END_OF_COLLECTION) {
actualCodePoint = readLengthAndCodePoint();
} else {
actualCodePoint = peekedCodePoint_;
//pos_ += (4 + peekedNumOfExtendedLenBytes_);
buffer.readerIndex(buffer.readerIndex() + (4 + peekedNumOfExtendedLenBytes_));
ddmScalarLen_ = peekedLength_;
if (peekedNumOfExtendedLenBytes_ == 0 && ddmScalarLen_ != -1) {
adjustLengths(4);
} else {
adjustCollectionAndDssLengths(4 + peekedNumOfExtendedLenBytes_);
}
peekedLength_ = 0;
peekedCodePoint_ = END_OF_COLLECTION;
peekedNumOfExtendedLenBytes_ = 0;
}
if (actualCodePoint != expectedCodePoint) {
throw new IllegalStateException("Expected code point " + Integer.toHexString(expectedCodePoint)
+ " but was " + Integer.toHexString(actualCodePoint));
}
}
private int readLengthAndCodePoint() {
if (!ddmCollectionLenStack.isEmpty()) {
if (ddmCollectionLenStack.peek() == 0) {
return END_OF_COLLECTION;
} else if (ddmCollectionLenStack.peek() < 4) {
// error
throw new IllegalStateException("Invalid ddm collection length: " + ddmCollectionLenStack.peek());
}
}
// if there is no more data in the current dss, and the dss is not
// continued, indicate the end of the same Id chain or read the next dss header.
if ((dssLength_ == 0) && (!dssIsContinued_)) {
if (!dssIsChainedWithSameID_) {
return END_OF_SAME_ID_CHAIN;
}
readDssHeader();
}
ensureBLayerDataInBuffer(4);
ddmScalarLen_ = buffer.readUnsignedShort();
// ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
int codePoint = buffer.readUnsignedShort();
// ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
adjustLengths(4);
// check for extended length
if ((ddmScalarLen_ & 0x8000) == 0x8000) {
readExtendedLength();
}
return codePoint;
}
private void readExtendedLength() {
int numberOfExtendedLenBytes = (ddmScalarLen_ - 0x8000); // fix scroll problem was - 4
int adjustSize = 0;
switch (numberOfExtendedLenBytes) {
case 4:
ensureBLayerDataInBuffer(4);
ddmScalarLen_ = (int) buffer.readUnsignedInt();
// ((buffer_[pos_++] & 0xff) << 24) +
// ((buffer_[pos_++] & 0xff) << 16) +
// ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
adjustSize = 4;
break;
case 0:
ddmScalarLen_ = -1;
adjustSize = 0;
break;
default:
throw new IllegalStateException("CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN");
//doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
}
adjustCollectionAndDssLengths(adjustSize);
}
private void adjustCollectionAndDssLengths(int length) {
// adjust the lengths here. this is a special case since the
// extended length bytes do not include their own length.
Deque original = ddmCollectionLenStack;
ddmCollectionLenStack = new ArrayDeque<>(original.size());
while (!original.isEmpty()) {
ddmCollectionLenStack.add(original.pop() - length);
}
dssLength_ -= length;
if (dssLength_ < 0)
throw new IllegalStateException("DSS length has gone negative: " + dssLength_);
// System.out.println("@AGG reduced len by " + length + " stack is now: " + ddmCollectionLenStack);
}
protected final void adjustLengths(int length) {
ddmScalarLen_ -= length;
if (ddmScalarLen_ < 0)
throw new IllegalStateException("DDM scalar length has gone negative: " + ddmScalarLen_);
adjustCollectionAndDssLengths(length);
}
protected int adjustDdmLength(int ddmLength, int length) {
ddmLength -= length;
if (ddmLength == 0) {
adjustLengths(getDdmLength());
}
return ddmLength;
}
final int getDdmLength() {
return ddmScalarLen_;
}
private void peekExtendedLength() {
peekedNumOfExtendedLenBytes_ = (peekedLength_ - 0x8004);
switch (peekedNumOfExtendedLenBytes_) {
case 4:
// L L C P Extended Length
// -->2-bytes<-- --->4-bytes<---
// We are only peeking the length here, the actual pos_ is still before LLCP. We ensured
// 4-bytes in peedCodePoint() for the LLCP, and we need to ensure 4-bytes(of LLCP) + the
// extended length bytes here.
// if (longBufferForDecryption_ == null) //we ddon't need to do this if it's
// data stream encryption
// {
// ensureBLayerDataInBuffer(4 + 4);
// }
// The ddmScalarLen_ we peek here does not include the LLCP and the extended
// length bytes
// themselves. So we will add those back to the ddmScalarLen_ so it can be
// adjusted
// correctly in parseLengthAndMatchCodePoint(). (since the adjustLengths()
// method will
// subtract the length from ddmScalarLen_)
peekedLength_ = (int) buffer.getUnsignedInt(buffer.readerIndex() + 4);
// ((buffer_[pos_ + 4] & 0xff) << 24) +
// ((buffer_[pos_ + 5] & 0xff) << 16) +
// ((buffer_[pos_ + 6] & 0xff) << 8) +
// ((buffer_[pos_ + 7] & 0xff) << 0);
break;
case 0:
peekedLength_ = -1; // this ddm is streamed, so set -1 -> length unknown
break;
default:
throw new IllegalStateException("CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN");
// doSyntaxrmSemantics(CodePoint.SYNERRCD_INCORRECT_EXTENDED_LEN);
}
}
final int[] readUnsignedShortList() {
int len = ddmScalarLen_;
ensureBLayerDataInBuffer(len);
adjustLengths(len);
int count = len / 2;
int[] list = new int[count];
for (int i = 0; i < count; i++) {
list[i] = buffer.readUnsignedShort();
// list[i] = ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
}
return list;
}
final int readUnsignedByte() {
ensureBLayerDataInBuffer(1);
adjustLengths(1);
return buffer.readUnsignedByte();
// return (buffer_[pos_++] & 0xff);
}
final byte readByte() {
ensureBLayerDataInBuffer(1);
adjustLengths(1);
return buffer.readByte();
// return (byte) (buffer_[pos_++] & 0xff);
}
final byte[] readBytes(int length) {
ensureBLayerDataInBuffer(length);
adjustLengths(length);
byte[] b = new byte[length];
//System.arraycopy(buffer, pos_, b, 0, length);
buffer.readBytes(b, 0, length);
//pos_ += length;
return b;
}
final byte[] readBytes() {
int len = ddmScalarLen_;
ensureBLayerDataInBuffer(len);
adjustLengths(len);
byte[] b = new byte[len];
buffer.readBytes(b, 0, len);
// System.arraycopy(buffer, pos_, b, 0, len);
//pos_ += len;
return b;
}
final int readUnsignedShort() {
// should we be checking dss lengths and ddmScalarLengths here
// if yes, i am not sure this is the correct place if we should be checking
ensureBLayerDataInBuffer(2);
adjustLengths(2);
return buffer.readUnsignedShort();
// return ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
}
// this is duplicated in parseColumnMetaData, but different
// DAGroup under NETColumnMetaData requires a lot more stuffs including
// precsion, scale and other stuffs
String parseFastVCS() {
// doublecheck what readString() does if the length is 0
return readFastString(readFastUnsignedShort(), Typdef.targetTypdef.getCcsidSbcEncoding());
}
final void skipBytes(int length) {
ensureBLayerDataInBuffer(length);
adjustLengths(length);
buffer.skipBytes(length);
//pos_ += length;
}
final void skipBytes() {
int len = ddmScalarLen_;
ensureBLayerDataInBuffer(len);
adjustLengths(len);
buffer.skipBytes(len);
//pos_ += len;
}
final void skipFastBytes(int length) {
buffer.skipBytes(length);
//pos_ += length;
}
protected final void popCollectionStack() {
// TODO: remove this after done porting
ddmCollectionLenStack.pop();
}
final String readFastString(int length, Charset encoding) {
// String s = new String(buffer_, pos_, length, encoding);
//pos_ += length;
return buffer.readCharSequence(length, encoding).toString();
}
final void readFastIntArray(int[] array) {
for (int i = 0; i < array.length; i++) {
if (metadata.isZos())
array[i] = buffer.readInt();
else
array[i] = buffer.readIntLE(); //SignedBinary.getInt(buffer_, pos_);
//pos_ += 4;
}
}
final int readFastUnsignedByte() {
//pos_++;
return buffer.readUnsignedByte();
// return (buffer_[pos_++] & 0xff);
}
final short readFastShort() {
//pos_ += 2;
if (metadata.isZos())
return buffer.readShort();
else
return buffer.readShortLE();
// short s = SignedBinary.getShort(buffer_, pos_);
// return s;
}
final long readFastLong() {
// long l = SignedBinary.getLong(buffer_, pos_);
//pos_ += 8;
if (metadata.isZos())
return buffer.readLong();
else
return buffer.readLongLE();
}
final int readFastUnsignedShort() {
//pos_ += 2;
return buffer.readUnsignedShort();
// return ((buffer_[pos_++] & 0xff) << 8) +
// ((buffer_[pos_++] & 0xff) << 0);
}
final int readFastInt() {
// int i = SignedBinary.getInt(buffer_, pos_);
//pos_ += 4;
if (metadata.isZos())
return buffer.readInt();
else
return buffer.readIntLE();
}
final String readFastString(int length) {
String result = buffer.readCharSequence(length, metadata.getCCSID()).toString();
// .convertToJavaString(buffer_, pos_, length);
//pos_ += length;
return result;
}
final byte[] readFastBytes(int length) {
byte[] b = new byte[length];
//System.arraycopy(buffer, pos_, b, 0, length);
buffer.readBytes(b, 0, length);
//pos_ += length;
return b;
}
final byte[] readFastLDBytes() {
int len = buffer.readShort();
// int len = ((buffer_[pos_++] & 0xff) << 8) + ((buffer_[pos_++] & 0xff) << 0);
if (len == 0) {
return null;
}
byte[] b = new byte[len];
//System.arraycopy(buffer, pos_, b, 0, len);
buffer.readBytes(b, 0, len);
//pos_ += len;
return b;
}
void ensureBLayerDataInBuffer(int desiredDataSize) {
// TODO: remove this after done porting
ensureALayerDataInBuffer(desiredDataSize);
}
// Make sure a certain amount of Layer A data is in the buffer.
// The data will be in the buffer after this method is called.
void ensureALayerDataInBuffer(int desiredDataSize) {
if (buffer.readableBytes() < desiredDataSize) {
throw new IllegalStateException(
"Needed to have " + desiredDataSize + " in buffer but only had " + buffer.readableBytes() +
". In JDBC we would normally block here but need to find a non-blocking solution");
}
}
}