db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From banda...@apache.org
Subject svn commit: r165178 [18/26] - in /incubator/derby/code/trunk: ./ java/client/ java/client/org/ java/client/org/apache/ java/client/org/apache/derby/ java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/client/net/ java/client/org/apache/derby/client/resources/ java/client/org/apache/derby/jdbc/ tools/ant/properties/
Date Thu, 28 Apr 2005 19:05:45 GMT
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,635 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.NetConnectionRequest
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   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 org.apache.derby.client.net;
+
+
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.Utils;
+import javax.transaction.xa.Xid;
+
+public class NetConnectionRequest extends Request implements ConnectionRequestInterface
+{
+  NetConnectionRequest (NetAgent netAgent, CcsidManager ccsidManager, int bufferSize)
+  {
+    super (netAgent, ccsidManager, bufferSize);
+  }
+  //----------------------------- entry points ---------------------------------
+
+  void writeExchangeServerAttributes (String externalName,
+                                      int targetAgent,
+                                      int targetSqlam,
+                                      int targetRdb,
+                                      int targetSecmgr,
+                                      int targetCmntcpip,
+                                      int targetCmnappc,
+                                      int targetXamgr,
+                                      int targetSyncptmgr,
+                                      int targetRsyncmgr) throws SqlException
+  {
+    // send the exchange server attributes command to the server.
+    // no other commands will be chained to the excsat because
+    // the manager levels are needed before anything else is attempted.
+    buildEXCSAT (externalName,
+                 targetAgent,
+                 targetSqlam,
+                 targetRdb,
+                 targetSecmgr,
+                 targetCmntcpip,
+                 targetCmnappc,
+                 targetXamgr,
+                 targetSyncptmgr,
+                 targetRsyncmgr);
+
+  }
+
+  void writeDummyExchangeServerAttributes () throws SqlException
+  {
+    // send the exchange server attributes command to the server,
+    // without any parameters
+    buildDummyEXCSAT ();
+  }
+
+  void writeAccessSecurity (int securityMechanism,
+                            String databaseName,
+                            byte[] publicKey) throws SqlException
+  {
+    buildACCSEC (securityMechanism, databaseName, publicKey);
+  }
+
+  void writeSecurityCheck (int securityMechanism,
+                           String databaseName,
+                           String userid,
+                           String password,
+                           byte[] encryptedUserid,
+                           byte[] encryptedPassword) throws SqlException
+
+
+  {
+    buildSECCHK (securityMechanism,
+                 databaseName,
+                 userid,
+                 password,
+                 encryptedUserid,
+                 encryptedPassword);
+  }
+
+  void writeAccessDatabase (String rdbnam,
+                            boolean readOnly,
+                            byte[] correlationToken,
+                            byte[] productData,
+                            Typdef typdef) throws SqlException
+  {
+    buildACCRDB (rdbnam,
+                 readOnly,
+                 correlationToken,
+                 productData,
+                 typdef);
+  }
+
+
+
+  public void writeCommitSubstitute (NetConnection connection) throws SqlException
+  {
+    buildDummyEXCSAT();
+  }
+
+  public void writeLocalCommit (NetConnection connection) throws SqlException
+  {
+    buildRDBCMM ();
+  }
+
+  public void writeLocalRollback (NetConnection connection) throws SqlException
+  {
+    buildRDBRLLBCK ();
+  }
+
+  public void writeLocalXAStart(NetConnection connection) throws SqlException
+  {
+  }
+
+
+  //Build the SYNNCTL commit command
+  public void writeLocalXACommit (NetConnection conn) throws SqlException
+  {
+  }
+
+  //Build the SYNNCTL rollback command
+  public void writeLocalXARollback (NetConnection conn) throws SqlException
+  {
+  }
+
+  public void writeXaStartUnitOfWork(NetConnection conn) throws SqlException
+      {
+  }
+
+  public void writeXaEndUnitOfWork(NetConnection conn) throws SqlException
+      {
+  }
+
+ protected void writeXaPrepare(NetConnection conn) throws SqlException
+  {
+  }
+
+ protected void writeXaCommit(NetConnection conn, Xid xid) throws SqlException
+  {
+ }
+
+ protected void writeXaRollback(NetConnection conn, Xid xid) throws SqlException
+ {
+ }
+
+ protected void writeXaRecover(NetConnection conn, int flag) throws SqlException
+ {
+ }
+
+ protected void writeXaForget(NetConnection conn, Xid xid) throws SqlException
+ {
+ }
+
+  public void writeSYNCType(int codepoint, int syncType)
+  {
+    writeScalar1Byte (codepoint, syncType);
+  }
+
+  public void writeForget(int codepoint, int value)
+  {
+  }
+
+  public void writeReleaseConversation(int codepoint, int value)
+  {
+  }
+
+  void writeNullXID(int codepoint)
+  {
+  }
+
+  void writeXID(int codepoint, Xid xid) throws SqlException
+  {
+  }
+
+
+  void writeXAFlags(int codepoint, int xaFlags)
+  {
+  }
+
+
+  //----------------------helper methods----------------------------------------
+  // These methods are "private protected", which is not a recognized java privilege,
+  // but means that these methods are private to this class and to subclasses,
+  // and should not be used as package-wide friendly methods.
+
+  // RDB Commit Unit of Work (RDBCMM) Command commits all work performed
+  // for the current unit of work.
+  //
+  // The Relational Database Name (RDBNAM) is an optional parameter
+  // which will not be sent by this command to reduce size, building,
+  // and parsing.
+  void buildRDBCMM () throws SqlException
+  {
+    createCommand ();
+    writeLengthCodePoint (0x04, CodePoint.RDBCMM);
+  }
+
+  // RDB Rollback Unit of Work(RDBRLLBCK) Command rolls back
+  // all work performed for the current unit of work.
+  //
+  // The Relational Database Name (RDBNAM) is an optional parameter
+  // which will not be sent by this command to reduce size, building,
+  // and parsing.
+  void buildRDBRLLBCK () throws SqlException
+  {
+    createCommand ();
+    writeLengthCodePoint (0x04, CodePoint.RDBRLLBCK);
+  }
+
+  // build the Exchange Server Attributes Command.
+  // This command sends the following information to the server.
+  // - this driver's server class name
+  // - this driver's level of each of the manager's it supports
+  // - this driver's product release level
+  // - this driver's external name
+  // - this driver's server name
+  void buildEXCSAT (String externalName,
+                    int targetAgent,
+                    int targetSqlam,
+                    int targetRdb,
+                    int targetSecmgr,
+                    int targetCmntcpip,
+                    int targetCmnappc,
+                    int targetXamgr,
+                    int targetSyncptmgr,
+                    int targetRsyncmgr) throws SqlException
+  {
+    createCommand ();
+
+    // begin excsat collection by placing the 4 byte llcp in the buffer.
+    // the length of this command will be computed later and "filled in"
+    // with the call to request.updateLengthBytes().
+    markLengthBytes (CodePoint.EXCSAT);
+
+    // place the external name for the client into the buffer.
+    // the external name was previously calculated before the call to this method.
+    buildEXTNAM (externalName); 
+
+    // place the server name for the client into the buffer.
+    buildSRVNAM ("Derby");
+
+    // place the server release level for the client into the buffer.
+    // this is a hard coded value for the driver.
+    buildSRVRLSLV();
+
+    // the managers supported by this driver and their levels will
+    // be sent to the server.  the variables which store these values
+    // were initialized during object constrcution to the highest values
+    // supported by the driver.
+
+    // for the case of the manager levels object, there is no
+    // need to have the length of the ddm object dynamically calculated
+    // because this method knows exactly how many will be sent and can set
+    // this now.
+    // each manager level class and level are 4 bytes long and
+    // right now 5 are being sent for a total of 20 bytes or 0x14 bytes.
+    // writeScalarHeader will be called to insert the llcp.
+    buildMGRLVLLS (targetAgent,
+                   targetSqlam,
+                   targetRdb,
+                   targetSecmgr,
+                   targetXamgr,
+                   targetSyncptmgr,
+                   targetRsyncmgr);
+
+
+    // place the server class name into the buffer.
+    // this value is hard coded for the driver.
+    buildSRVCLSNM();
+
+    // the excsat command is complete so the updateLengthBytes method
+    // is called to dynamically compute the length for this command and insert
+    // it into the buffer
+    updateLengthBytes();
+  }
+
+  void buildDummyEXCSAT () throws SqlException
+  {
+    createCommand ();
+
+    // begin excsat collection by placing the 4 byte llcp in the buffer.
+    // the length of this command will be computed later and "filled in"
+    // with the call to request.updateLengthBytes().
+    markLengthBytes (CodePoint.EXCSAT);
+
+    // the excsat command is complete so the updateLengthBytes method
+    // is called to dynamically compute the length for this command and insert
+    // it into the buffer
+    updateLengthBytes();
+  }
+
+  void buildACCSEC (int secmec,
+                    String rdbnam,
+                    byte[] sectkn) throws SqlException
+  {
+    createCommand ();
+
+    // place the llcp for the ACCSEC in the buffer.  save the length bytes for
+    // later update
+    markLengthBytes (CodePoint.ACCSEC);
+
+    // the security mechanism is a required instance variable.  it will
+    // always be sent.
+    buildSECMEC (secmec);
+
+    // the rdbnam will be built and sent.  different sqlam levels support
+    // different lengths.  at this point the length has been checked against
+    // the maximum allowable length.  so write the bytes and padd up to the
+    // minimum length if needed.
+    buildRDBNAM (rdbnam);
+
+    if (sectkn != null) buildSECTKN (sectkn);
+
+    // the accsec command is complete so notify the the request object to
+    // update the ddm length and the dss header length.
+    updateLengthBytes();
+  }
+
+  void buildSECCHK (int secmec,
+                    String rdbnam,
+                    String user,
+                    String password,
+                    byte[] sectkn,
+                    byte[] sectkn2) throws SqlException
+  {
+    createCommand ();
+    markLengthBytes (CodePoint.SECCHK);
+
+    // always send the negotiated security mechanism for the connection.
+    buildSECMEC (secmec);
+
+    // the rdbnam will be built and sent.  different sqlam levels support
+    // different lengths.  at this point the length has been checked against
+    // the maximum allowable length.  so write the bytes and padd up to the
+    // minimum length if needed.
+    buildRDBNAM (rdbnam);
+    if (user != null ) buildUSRID (user);
+    if (password != null ) buildPASSWORD (password);
+    if (sectkn != null) buildSECTKN (sectkn);
+    if (sectkn2 != null) buildSECTKN (sectkn2);
+    updateLengthBytes();
+
+  }
+
+  // The Access RDB (ACCRDB) command makes a named relational database (RDB)
+  // available to a requester by creating an instance of an SQL application
+  // manager.  The access RDB command then binds the created instance to the target
+  // agent and to the RDB. The RDB remains available (accessed) until
+  // the communications conversation is terminate.
+  void buildACCRDB (String rdbnam,
+                    boolean readOnly,
+                    byte[] crrtkn,
+                    byte[] prddta,
+                    Typdef typdef) throws SqlException
+  {
+    createCommand ();
+
+    markLengthBytes (CodePoint.ACCRDB);
+
+    // the relational database name specifies the name of the rdb to
+    // be accessed.  this can be different sizes depending on the level of
+    // support.  the size will have ben previously checked so at this point just
+    // write the data and pad with the correct number of bytes as needed.
+    // this instance variable is always required.
+    buildRDBNAM (rdbnam);
+
+    // the rdb access manager class specifies an instance of the SQLAM
+    // that accesses the RDB.  the sqlam manager class codepoint
+    // is always used/required for this.  this instance variable
+    // is always required.
+    buildRDBACCCL();
+
+    // product specific identifier specifies the product release level
+    // of this driver.  see the hard coded value in the NetConfiguration class.
+    // this instance variable is always required.
+    buildPRDID();
+
+    // product specific data.  this is an optional parameter which carries
+    // product specific information.  although it is optional, it will be
+    // sent to the server.  use the first byte to determine the number
+    // of the prddta bytes to write to the buffer. note: this length
+    // doesn't include itself so increment by it by 1 to get the actual
+    // length of this data.
+    buildPRDDTA (prddta);
+
+
+    // the typdefnam parameter specifies the name of the data type to data representation
+    // mappings used when this driver sends command data objects.
+    buildTYPDEFNAM (typdef.getTypdefnam());
+
+	if (crrtkn == null)
+        netAgent_.netConnection_.constructCrrtkn();
+	
+	buildCRRTKN(netAgent_.netConnection_.crrtkn_);
+
+    // This specifies the single-byte, double-byte
+    // and mixed-byte CCSIDs of the Scalar Data Arrays (SDAs) in the identified
+    // data type to the data representation mapping definitions.  This can
+    // contain 3 CCSIDs.  The driver will only send the ones which were set.
+    buildTYPDEFOVR (typdef.isCcsidSbcSet(),
+                    typdef.getCcsidSbc(),
+                    typdef.isCcsidDbcSet(),
+                    typdef.getCcsidDbc(),
+                    typdef.isCcsidMbcSet(),
+                    typdef.getCcsidMbc());
+
+    // RDB allow update is an optional parameter which indicates
+    // whether the RDB allows the requester to perform update operations
+    // in the RDB.  If update operations are not allowed, this connection
+    // is limited to read-only access of the RDB resources.
+    buildRDBALWUPD (readOnly);
+
+
+
+    // the Statement Decimal Delimiter (STTDECDEL),
+    // Statement String Delimiter (STTSTRDEL),
+    // and Target Default Value Return (TRGDFTRT) are all optional
+    // instance variables which will not be sent to the server.
+
+    // the command and the dss are complete so make the call to notify
+    // the request object.
+    updateLengthBytes();
+  }
+
+
+  void buildSYNCCTLMigrate() throws SqlException
+  {
+  }
+
+  void buildSYNCCTLCommit (int xaFlags, Xid xid) throws SqlException
+  {
+  }
+
+  void buildSYNCCTLRollback (int xaFlags) throws SqlException
+  {
+  }
+
+
+  // The External Name is the name of the job, task, or process on a
+  // system for which a DDM server is active.
+  private void buildEXTNAM (String extnam) throws SqlException
+  {
+    int extnamTruncateLength = Utils.min (extnam.length(),
+                                          NetConfiguration.EXTNAM_MAXSIZE);
+
+    writeScalarString (CodePoint.EXTNAM,
+                       extnam.substring (0, extnamTruncateLength));
+  }
+
+  // Server Name is the name of the DDM server.
+  private void buildSRVNAM (String srvnam) throws SqlException
+  {
+    int srvnamTruncateLength = Utils.min (srvnam.length(),
+                                          NetConfiguration.SRVNAM_MAXSIZE);
+    writeScalarString (CodePoint.SRVNAM,
+                       srvnam.substring (0,srvnamTruncateLength));
+  }
+
+  // Server Product Release Level String specifies the product
+  // release level of a DDM server.
+  private void buildSRVRLSLV () throws SqlException
+  {
+    // Hard-coded to ClientDNC 1.0 for dnc 1.0.
+    writeScalarString (CodePoint.SRVRLSLV, NetConfiguration.SRVRLSLV);
+  }
+
+  private void buildSRVCLSNM () throws SqlException
+  {
+    // Server class name is hard-coded to QDERBY/JVM for dnc.
+    writeScalarString (CodePoint.SRVCLSNM, NetConfiguration.SRVCLSNM_JVM);
+  }
+
+  // Precondition: valid secmec is assumed.
+  private void buildSECMEC (int secmec) throws SqlException
+  {
+    writeScalar2Bytes (CodePoint.SECMEC, secmec);
+  }
+
+  // Relational Database Name specifies the name of a relational database
+  // of the server.
+  // if length of RDB name <= 18 characters, there is not change to the format
+  // of the RDB name.  The length of the RDBNAM remains fixed at 18 which includes
+  // any right bland padding if necessary.
+  // if length of the RDB name is > 18 characters, the length of the RDB name is
+  // identical to the length of the RDB name.  No right blank padding is required.
+  private void buildRDBNAM (String rdbnam) throws SqlException
+  {
+    // since this gets built more than once on the connect flow,
+   // see if we can optimize
+
+    int rdbnamLength = rdbnam.length();
+    if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_FIXED_LEN ) {
+      writeScalarPaddedString (CodePoint.RDBNAM,
+                               rdbnam,
+                               NetConfiguration.PKG_IDENTIFIER_FIXED_LEN);  // minimum length of RDBNAM
+    }
+    else {
+      if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_MAX_LEN)
+        writeScalarString (CodePoint.RDBNAM, rdbnam);
+      else
+        throw new SqlException (netAgent_.logWriter_, "Length of the Relational Database Name, " +
+                               rdbnam +
+                             ", exceeds maximum size allowed for PROTOCOL Connection.");// +
+                             //"at SQLAM level " + netAgent_.targetSqlam_);
+    }
+  }
+
+  private void buildSECTKN (byte[] sectkn) throws SqlException
+  {
+    if (sectkn.length > NetConfiguration.SECTKN_MAXSIZE)
+      throw new SqlException (netAgent_.logWriter_, "bug check: sectkn too long");
+    writeScalarBytes (CodePoint.SECTKN, sectkn);
+  }
+
+  private void buildUSRID (String usrid) throws SqlException
+  {
+    int usridLength = usrid.length();
+    if ((usridLength == 0) || (usridLength > NetConfiguration.USRID_MAXSIZE))
+      throw new SqlException (netAgent_.logWriter_, "userid length, " + usridLength + ", is not allowed.");
+
+    writeScalarString (CodePoint.USRID, usrid);
+  }
+
+  private void buildPASSWORD (String password) throws SqlException
+  {
+    int passwordLength = password.length();
+    if ((passwordLength == 0) || (passwordLength > NetConfiguration.PASSWORD_MAXSIZE))
+      throw new SqlException (netAgent_.logWriter_, "password length, " + passwordLength + ", is not allowed.");
+    if (netAgent_.logWriter_ != null) {
+      // remember the position of password in order to
+      // mask it out in trace (see Request.sendBytes()).
+      passwordIncluded_ = true;
+      passwordStart_ = offset_ + 4;
+      passwordLength_ = passwordLength;
+    }
+    writeScalarString (CodePoint.PASSWORD, password);
+  }
+
+  private void buildRDBACCCL() throws SqlException
+  {
+    writeScalar2Bytes (CodePoint.RDBACCCL, CodePoint.SQLAM);
+  }
+
+
+  private void buildPRDID () throws SqlException
+  {
+    writeScalarString (CodePoint.PRDID, NetConfiguration.PRDID);  // product id is hard-coded to DNC01000 for dnc 1.0.
+  }
+
+  private void buildPRDDTA (byte[] prddta) throws SqlException
+  {
+    int prddtaLength = (prddta[NetConfiguration.PRDDTA_LEN_BYTE] & 0xff) + 1;
+    writeScalarBytes (CodePoint.PRDDTA, prddta, 0, prddtaLength);
+  }
+
+  private void buildTYPDEFNAM (String typdefnam) throws SqlException
+  {
+    writeScalarString (CodePoint.TYPDEFNAM, typdefnam);
+  }
+
+  void buildTYPDEFOVR (boolean sendCcsidSbc,
+                               int ccsidSbc,
+                               boolean sendCcsidDbc,
+                               int ccsidDbc,
+                               boolean sendCcsidMbc,
+                               int ccsidMbc
+                               ) throws SqlException
+  {
+    markLengthBytes (CodePoint.TYPDEFOVR);
+    // write the single-byte ccsid used by this driver.
+    if (sendCcsidSbc) writeScalar2Bytes (CodePoint.CCSIDSBC, ccsidSbc);
+
+    // write the double-byte ccsid used by this driver.
+    if (sendCcsidDbc) writeScalar2Bytes (CodePoint.CCSIDDBC, ccsidDbc);
+
+    // write the mixed-byte ccsid used by this driver
+    if (sendCcsidMbc) writeScalar2Bytes (CodePoint.CCSIDMBC, ccsidMbc);
+
+    updateLengthBytes();
+
+  }
+
+  private void buildMGRLVLLS (int agent,
+                              int sqlam,
+                              int rdb,
+                              int secmgr,
+                              int xamgr,
+                              int syncptmgr,
+                              int rsyncmgr) throws SqlException
+
+  {
+    markLengthBytes(CodePoint.MGRLVLLS);
+
+    // place the managers and their levels in the buffer
+    writeCodePoint4Bytes (CodePoint.AGENT, agent);
+    writeCodePoint4Bytes (CodePoint.SQLAM, sqlam);
+    writeCodePoint4Bytes (CodePoint.RDB, rdb);
+    writeCodePoint4Bytes (CodePoint.SECMGR, secmgr);
+
+    if (netAgent_.netConnection_.isXAConnection())
+    {
+      if (xamgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.XAMGR, xamgr);
+      if (syncptmgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.SYNCPTMGR, syncptmgr);
+      if (rsyncmgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.RSYNCMGR, rsyncmgr);
+    }
+    updateLengthBytes();
+  }
+
+  private void buildCRRTKN (byte[] crrtkn) throws SqlException
+  {
+    writeScalarBytes (CodePoint.CRRTKN, crrtkn);
+  }
+
+  private void buildRDBALWUPD (boolean readOnly) throws SqlException
+  {
+    if (readOnly) writeScalar1Byte (CodePoint.RDBALWUPD, CodePoint.FALSE);
+  }
+
+}
+
+
+

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,1066 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.NetCursor
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   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 org.apache.derby.client.net;
+
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.SqlWarning;
+import org.apache.derby.client.am.SignedBinary;
+import org.apache.derby.client.am.DisconnectException;
+import org.apache.derby.client.am.Blob;
+import org.apache.derby.client.am.Clob;
+import org.apache.derby.client.am.Agent;
+import org.apache.derby.client.am.Types;
+
+public class NetCursor extends org.apache.derby.client.am.Cursor
+{
+
+  NetResultSet netResultSet_;
+  NetAgent netAgent_;
+
+  Typdef qrydscTypdef_;
+
+  int targetSqlamForTypdef_;
+
+
+  // override column meta data
+  int numMddOverrides_;
+  int maximumRowSize_;
+  boolean blocking_;  // if true, multiple rows may be "blocked" in a single reply
+
+  // Raw fdoca column meta data.
+  int[] typeToUseForComputingDataLength_;
+  boolean[] isGraphic_;
+
+  // key = column position, value = index into extdtaData_
+  java.util.HashMap extdtaPositions_; 
+  java.util.ArrayList extdtaData_; // queue to hold EXTDTA data that hasn't been correlated to its column #
+
+
+  boolean rtnextrow_ = true;
+
+  //-----------------------------constants--------------------------------------
+
+  //---------------------constructors/finalizer---------------------------------
+
+  NetCursor (NetAgent netAgent)
+  {
+    super (netAgent);
+    netAgent_ = netAgent;
+    numMddOverrides_ = 0;
+    maximumRowSize_ = 0;
+    extdtaPositions_ = new java.util.HashMap();
+    extdtaData_ = new java.util.ArrayList ();
+  }
+
+  NetCursor (NetAgent netAgent,
+            int qryprctyp)  //protocolType, CodePoint.FIXROWPRC | CodePoint.LMTBLKPRC
+  {
+    this (netAgent);
+    if (qryprctyp == CodePoint.FIXROWPRC)
+      blocking_ = false;
+    else if (qryprctyp == CodePoint.LMTBLKPRC)
+      blocking_ = true;
+  }
+  //-----------------------------parsing the data buffer------------------------
+
+  // Pseudo-code:
+  //   parse thru the current row in dataBuffer computing column offsets
+  //   if (we hit the super.lastValidBytePosition, ie. encounter partial row) {
+  //     shift partial row bytes to beginning of dataBuffer (this.shiftPartialRowToBeginning())
+  //     reset current row position (also done by this.shiftPartialRowToBeginning())
+  //     send and recv continue-query into commBuffer (rs.flowContinueQuery())
+  //     parse commBuffer up to QRYDTA (rs.flowContinueQuery())
+  //     copy query data from reply's commBuffer to our dataBuffer (this.copyQrydta())
+  //   }
+  // Returns true if the current row position is a valid row position.
+  // rename this to parse*() 
+  protected boolean calculateColumnOffsetsForRow_ (int rowIndex) throws SqlException, org.apache.derby.client.am.DisconnectException
+  {
+    int daNullIndicator = CodePoint.NULLDATA;
+    int colNullIndicator = CodePoint.NULLDATA;
+    int length;
+
+    if (hasLobs_)
+    extdtaPositions_.clear();  // reset positions for this row
+
+    int[] columnDataPosition = null;
+    int[] columnDataComputedLength = null;
+    boolean[] columnDataIsNull = null;
+
+    if ((position_ == lastValidBytePosition_) &&
+      (netResultSet_ != null) && (netResultSet_.scrollable_))
+       return false;
+
+    NetSqlca netSqlca = this.parseSQLCARD (qrydscTypdef_);
+
+    if (netSqlca != null) {
+      int sqlcode = netSqlca.getSqlCode();
+     if (sqlcode < 0) {
+       throw new SqlException (netAgent_.logWriter_, netSqlca);
+     }
+     else {
+       if (sqlcode > 0) {
+         if (sqlcode == 100) {
+           allRowsReceivedFromServer_ = true;
+           if (netResultSet_ != null && netSqlca.containsSqlcax())
+             netResultSet_.setRowCountEvent (netSqlca.getRowCount(qrydscTypdef_));
+         }
+         else if (netResultSet_ != null)
+           netResultSet_.accumulateWarning (new SqlWarning (agent_.logWriter_, netSqlca));
+        }
+      }
+    }
+
+    // If we don't have at least one byte in the buffer for the DA null indicator,
+    // then we need to send a CNTQRY request to fetch the next block of data.
+    // Read the DA null indicator.
+    daNullIndicator = readFdocaOneByte ();
+
+    // In the case for held cursors, the +100 comes back as part of the QRYDTA, and as
+    // we are parsing through the row that contains the SQLCA with +100, we mark the
+    // nextRowPosition_ which is the lastValidBytePosition_, but we don't mark the
+    // currentRowPosition_ until the next time next() is called causing the check
+    // cursor_.currentRowPositionIsEqualToNextRowPosition () to fail in getRow() and thus
+    // not returning 0 when it should. So we need to mark the current row position immediately
+    // in order for getRow() to be able to pick it up.
+
+    // markNextRowPosition() is called again once this method returns, but it is ok
+    // since it's only resetting nextRowPosition_ to position_ and position_ will
+    // not change again from this point.
+
+    if (allRowsReceivedFromServer_ && (position_ == lastValidBytePosition_)) {
+      markNextRowPosition ();
+      makeNextRowPositionCurrent ();
+      return false;
+    }
+
+    // If data flows....
+    if (daNullIndicator == 0x0) {
+
+      incrementRowsReadEvent();
+
+      // netResultSet_ is null if this method is invoked from Lob.position()
+      // If row has exceeded the size of the ArrayList, new up a new int[] and add it to the
+      // ArrayList, otherwise just reuse the int[].
+      if (netResultSet_ != null && netResultSet_.scrollable_) {
+        columnDataPosition = allocateColumnDataPositionArray (rowIndex);
+        columnDataComputedLength = allocateColumnDataComputedLengthArray (rowIndex);
+        columnDataIsNull = allocateColumnDataIsNullArray (rowIndex);
+        // Since we are no longer setting the int[]'s to null for a delete/update hole, we need
+        // another way of keeping track of the delete/update holes.
+        setIsUpdataDeleteHole (rowIndex, false);
+      }
+      else {
+        // Use the arrays defined on the Cursor for forward-only cursors.
+        // can they ever be null
+        if (columnDataPosition_ == null || columnDataComputedLength_ == null || isNull_ == null)
+          allocateColumnOffsetAndLengthArrays ();
+        columnDataPosition = columnDataPosition_;
+        columnDataComputedLength = columnDataComputedLength_;
+        columnDataIsNull = isNull_;
+      }
+
+      // Loop through the columns
+      for (int index = 0; index < columns_; index++) {
+        // If column is nullable, read the 1-byte null indicator.
+        if (nullable_[index])
+          // Need to pass the column index so all previously calculated offsets can be
+          // readjusted if the query block splits on a column null indicator.
+
+          // null indicators from FD:OCA data
+          // 0 to 127: a data value will flow.
+          // -1 to -128: no data value will flow.
+          colNullIndicator = readFdocaOneByte (index);
+
+        // If non-null column data
+        if (!nullable_[index] || (colNullIndicator >= 0 && colNullIndicator <= 127)) {
+
+          // Set the isNull indicator to false
+          columnDataIsNull[index] = false;
+
+          switch (typeToUseForComputingDataLength_[index]) {
+          // for fixed length data
+          case Typdef.FIXEDLENGTH:
+            columnDataPosition[index] = position_;
+            if (isGraphic_[index])
+              columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index]*2, index);
+            else
+              columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index], index);
+            break;
+
+            // for variable character string and variable byte string,
+            // there are 2-byte of length in front of the data
+          case Typdef.TWOBYTELENGTH:
+            columnDataPosition[index] = position_;
+            length = readFdocaTwoByteLength (index);
+            // skip length + the 2-byte length field
+            if (isGraphic_[index])
+              columnDataComputedLength[index] = skipFdocaBytes (length*2, index) + 2;
+            else
+              columnDataComputedLength[index] = skipFdocaBytes (length, index) + 2;
+            break;
+
+            // For decimal columns, determine the precision, scale, and the representation
+          case Typdef.DECIMALLENGTH:
+            columnDataPosition[index] = position_;
+            columnDataComputedLength[index] = skipFdocaBytes (getDecimalLength(index), index);
+            break;
+
+          case Typdef.LOBLENGTH:
+            columnDataPosition[index] = position_;
+            columnDataComputedLength[index] = this.skipFdocaBytes (fdocaLength_[index] & 0x7fff, index);
+            break;
+
+          // for short variable character string and short variable byte string,
+          // there is a 1-byte length in front of the data
+          case Typdef.ONEBYTELENGTH:
+            columnDataPosition[index] = position_;
+            length = readFdocaOneByte (index);
+            // skip length + the 1-byte length field
+            if (isGraphic_[index])
+              columnDataComputedLength[index] = skipFdocaBytes (length*2, index) + 1;
+            else
+              columnDataComputedLength[index] = skipFdocaBytes (length, index) + 1;
+            break;
+
+          default:
+            columnDataPosition[index] = position_;
+            if (isGraphic_[index])
+              columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index]*2, index);
+            else
+              columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index], index);
+            break;
+          }
+        }
+        else if ((colNullIndicator & 0x80) == 0x80) {
+          // Null data. Set the isNull indicator to true.
+          columnDataIsNull[index] = true;
+        }
+      }
+
+      // set column offsets for the current row.
+      columnDataPosition_ = columnDataPosition;
+      columnDataComputedLength_ = columnDataComputedLength;
+      isNull_ = columnDataIsNull;
+
+      if (!allRowsReceivedFromServer_) {
+        calculateLobColumnPositionsForRow();
+        // Flow another CNTQRY if we are blocking, are using rtnextrow, and expect
+        // non-trivial EXTDTAs for forward only cursors.  Note we do not support
+        // EXTDTA retrieval for scrollable cursors.
+        // if qryrowset was sent on excsqlstt for a sp call, which is only the case
+        if (blocking_ && rtnextrow_ &&
+            extdtaPositions_.size () > 0 && !netResultSet_.scrollable_)
+          if (!extdtaPositions_.isEmpty())
+            netResultSet_.flowFetch ();
+      }
+    }
+
+    // Else if this row is null, only add to the isRowNullCache_ if the cursor is scrollable.
+    else {
+      if (netResultSet_ != null && netResultSet_.scrollable_) setIsUpdataDeleteHole (rowIndex, true);
+    }
+
+    // If blocking protocol is used, we could have already received an ENDQRYRM,
+    // which sets allRowsReceivedFromServer_ to true.  It's safe to assume that all of
+    // our QRYDTA's have been successfully copied to the dataBuffer.  And even though
+    // the flag for allRowsReceivedFromServer_ is set, we still want to continue to parse through
+    // the data in the dataBuffer.
+    // But in the case where fixed row protocol is used,
+    if (!blocking_ && allRowsReceivedFromServer_ && daNullIndicator == 0xFF)
+      return false;
+    else
+      return true; 
+  }
+
+  protected boolean isDataBufferNull ()
+  {
+    if (dataBuffer_ == null)
+      return true;
+    else
+      return false;
+  }
+
+  protected void allocateDataBuffer ()
+  {
+    int length;
+    if (maximumRowSize_ > DssConstants.MAX_DSS_LEN)
+      length = maximumRowSize_;
+    else
+      length = DssConstants.MAX_DSS_LEN;
+
+    dataBuffer_ = new byte[length];
+    position_ = 0;
+    lastValidBytePosition_ = 0;
+  }
+
+  protected void allocateDataBuffer (int length)
+  {
+    dataBuffer_ = new byte[length];
+  }
+
+
+  private int readFdocaInt () throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    if ((position_ + 4) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    int i = SignedBinary.getInt (dataBuffer_, position_);
+    position_ += 4;
+    return i;
+  }
+
+  // Reads 1-byte from the dataBuffer from the current position.
+  // If position is already at the end of the buffer, send CNTQRY to get more data.
+  private int readFdocaOneByte () throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if (position_ == lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+    return dataBuffer_[position_++] & 0xff;
+  }
+
+  // Reads 1-byte from the dataBuffer from the current position.
+  // If position is already at the end of the buffer, send CNTQRY to get more data.
+  private int readFdocaOneByte (int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if (position_ == lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow (index);
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+    return dataBuffer_[position_++] & 0xff;
+  }
+
+  // Reads <i>length</i> number of bytes from the dataBuffer starting from the
+  // current position.  Returns a new byte array which contains the bytes read.
+  // If current position plus length goes past the lastValidBytePosition, send
+  // CNTQRY to get more data.
+  private byte[] readFdocaBytes (int length) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    byte[] b = new byte[length];;
+
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + length) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    for (int i = 0; i < length; i++)
+      b[i] = dataBuffer_[position_++];
+
+    return b;
+  }
+
+  // Reads 2-bytes from the dataBuffer starting from the current position, and
+  // returns an integer constructed from the 2-bytes.  If current position plus
+  // 2 bytes goes past the lastValidBytePosition, send CNTQRY to get more data.
+  private int readFdocaTwoByteLength () throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + 2) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    return
+      ((dataBuffer_[position_++] & 0xff) << 8) +
+      ((dataBuffer_[position_++] & 0xff) << 0);
+  }
+
+  private int readFdocaTwoByteLength (int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + 2) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow (index);
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    return
+      ((dataBuffer_[position_++] & 0xff) << 8) +
+      ((dataBuffer_[position_++] & 0xff) << 0);
+  }
+
+  // Check if position plus length goes past the lastValidBytePosition.
+  // If so, send CNTQRY to get more data.
+  // length - number of bytes to skip
+  // returns the number of bytes skipped
+  private int skipFdocaBytes (int length) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + length) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+    position_ += length;
+    return length;
+  }
+
+  private int skipFdocaBytes (int length, int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + length) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow (index);
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    position_ += length;
+    return length;
+  }
+
+  // Shift partial row bytes to beginning of dataBuffer,
+  // and resets current row position, and lastValidBytePosition.
+  // When we shift partial row, we'll have to recalculate column offsets
+  // up to this column.
+  private void shiftPartialRowToBeginning ()
+  {
+    // Get the length to shift from the beginning of the partial row.
+    int length = lastValidBytePosition_ - currentRowPosition_;
+
+    // shift the data in the dataBufferStream
+    dataBufferStream_.reset ();
+    if (dataBuffer_ != null)
+      dataBufferStream_.write (dataBuffer_, currentRowPosition_, length);
+
+    for (int i = 0; i < length; i++)
+      dataBuffer_[i] = dataBuffer_[currentRowPosition_+i];
+
+    position_ = length - (lastValidBytePosition_ - position_);
+    lastValidBytePosition_ = length;
+  }
+
+  private void adjustColumnOffsetsForColumnsPreviouslyCalculated (int index)
+  {
+    for (int j = 0; j <= index; j++) {
+      columnDataPosition_[j] -= currentRowPosition_;
+    }
+  }
+
+  private void resetCurrentRowPosition ()
+  {
+    currentRowPosition_ = 0;
+  }
+
+  // Calculates the column index for Lob objects constructed from EXTDTA data.
+  // Describe information isn't sufficient because we have to check
+  // for trivial values (nulls or zero-length) and exclude them.
+  void calculateLobColumnPositionsForRow ()
+  {
+    int currentPosition = 0;
+
+    for (int i = 0; i < columns_; i++) {
+      if ( isNonTrivialDataLob (i) )
+        // key = column position, data = index to corresponding data in extdtaData_
+        // ASSERT: the server always returns the EXTDTA objects in ascending order
+        extdtaPositions_.put(new Integer(i + 1), new Integer (currentPosition++));
+    }
+  }
+
+  // prereq: the base data for the cursor has been processed for offsets and lengths
+  boolean isNonTrivialDataLob (int index)
+  {
+    long length = 0L;
+
+    if (isNull_[index] ||
+        (jdbcTypes_[index] != Types.BLOB &&
+         jdbcTypes_[index] != Types.CLOB) )
+      return false;
+
+    int position = columnDataPosition_[index];
+
+    // if the high-order bit is set, length is unknown -> set value to x'FF..FF'
+    if (((dataBuffer_[position])&0x80) == 0x80)
+      length = -1;
+    else {
+
+      byte[] lengthBytes = new byte[columnDataComputedLength_[index]];
+      byte[] longBytes = new byte[8];
+
+      System.arraycopy (dataBuffer_,
+                        position,
+                        lengthBytes,
+                        0,
+                        columnDataComputedLength_[index] );
+
+      // right-justify for BIG ENDIAN
+      int j = 0;
+      for (int i = 8 - columnDataComputedLength_[index]; i < 8; i++) {
+        longBytes[i] = lengthBytes[j];
+        j++;
+      }
+      length = SignedBinary.getLong (longBytes, 0);
+    }
+    return (length != 0L)?true:false;
+  }
+
+  protected void clearLobData_()
+  {
+    extdtaData_.clear ();
+    extdtaPositions_.clear ();
+  }
+
+  // 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 parseSQLCARD (Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    return parseSQLCAGRP (typdef);  
+  }
+
+  // SQLCAGRP : FDOCA EARLY GROUP
+  // SQL Communcations Area Group Description
+  //
+  // 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
+  private NetSqlca parseSQLCAGRP (Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException
+  {
+    if (readFdocaOneByte() == CodePoint.NULLDATA)
+      return null;
+    int sqlcode = readFdocaInt();
+    byte[] sqlstate = readFdocaBytes (5);
+    byte[] sqlerrproc = readFdocaBytes (8);
+    NetSqlca netSqlca = new NetSqlca (netAgent_.netConnection_, sqlcode, sqlstate, sqlerrproc, typdef.getCcsidSbc());
+
+    parseSQLCAXGRP (typdef, netSqlca);
+
+	parseSQLDIAGGRP ();
+
+    return netSqlca;
+  }
+
+  // SQLCAXGRP : EARLY FDOCA GROUP
+  // SQL Communications Area Exceptions Group Description
+  //
+  // 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 255
+  //   SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
+  //   SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
+  private void parseSQLCAXGRP (Typdef typdef, NetSqlca netSqlca) throws DisconnectException, SqlException
+  {
+    if (readFdocaOneByte() == CodePoint.NULLDATA) {
+      netSqlca.setContainsSqlcax (false);
+      return;
+    }
+
+
+    //   SQLERRD1 to SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    int[] sqlerrd = new int[6];
+    for (int i = 0; i < sqlerrd.length; i++)
+      sqlerrd[i] = readFdocaInt ();
+
+    //   SQLWARN0 to SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+    byte[] sqlwarn = readFdocaBytes (11);
+
+	// skip over the rdbnam for now
+	// SQLRDBNAME; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
+	parseVCS (typdef);
+
+    //   SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
+    //   SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
+    int varcharLength = readFdocaTwoByteLength();  // mixed length
+    byte[] sqlerrmc = null;
+    int sqlerrmcCcsid = 0;
+    if (varcharLength != 0) {                    // if mixed
+      sqlerrmc = readFdocaBytes(varcharLength);      // read mixed bytes
+      sqlerrmcCcsid = typdef.getCcsidMbc();
+      skipFdocaBytes(2);                          // skip single length
+    }
+    else {
+      varcharLength = readFdocaTwoByteLength();  // read single length
+      sqlerrmc = readFdocaBytes (varcharLength);     // read single bytes
+      sqlerrmcCcsid = typdef.getCcsidSbc();
+    }
+
+    netSqlca.setSqlerrd (sqlerrd);
+    netSqlca.setSqlwarnBytes (sqlwarn);
+    netSqlca.setSqlerrmcBytes (sqlerrmc, sqlerrmcCcsid);
+  }
+
+  // SQLDIAGGRP : FDOCA EARLY GROUP
+  private void parseSQLDIAGGRP () throws DisconnectException, SqlException
+  {
+    if (readFdocaOneByte() == CodePoint.NULLDATA)
+      return;
+
+    netAgent_.accumulateChainBreakingReadExceptionAndThrow (new DisconnectException (
+      netAgent_,
+      "parseSQLDIAGGRP not yet implemented"));
+  }
+
+  private String parseVCS (Typdef typdefInEffect) throws DisconnectException, SqlException
+  {
+    return readFdocaString(readFdocaTwoByteLength(),
+                           typdefInEffect.getCcsidSbcEncoding());
+  }
+
+  // This is not used for column data.
+  private String readFdocaString (int length, String encoding) throws DisconnectException, SqlException
+  {
+    if (length == 0)
+      return null;
+
+    // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+    // so there is no need to drive a flowFetch (continue query) request for singleton select.
+    if ((position_ + length) > lastValidBytePosition_) {
+      // Check for ENDQRYRM, throw SqlException if already received one.
+      checkAndThrowReceivedEndqryrm ();
+
+      // Send CNTQRY to complete the row/rowset.
+      int lastValidByteBeforeFetch = completeSplitRow ();
+
+      // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+      // throw a SqlException for the ENDQRYRM.
+      checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+    }
+
+    String s = null;
+
+    try {
+      s = new String (dataBuffer_, position_, length, encoding);
+    }
+    catch (java.io.UnsupportedEncodingException e) {
+      netAgent_.accumulateChainBreakingReadExceptionAndThrow (
+        new org.apache.derby.client.am.DisconnectException (
+          e,
+          netAgent_,
+          "encoding not supported!!"));
+    }
+
+    position_ += length;
+    return s;
+  }
+
+  void allocateColumnOffsetAndLengthArrays ()
+  {
+    columnDataPosition_ = new int[columns_];
+    columnDataComputedLength_ = new int[columns_];
+    isNull_ = new boolean[columns_];
+  }
+
+  void setBlocking (int queryProtocolType)
+  {
+    if (queryProtocolType == CodePoint.LMTBLKPRC) 
+      blocking_ = true;
+    else
+      blocking_ = false;
+  }
+
+  protected byte[] findExtdtaData (int column)
+  {
+    byte[] data = null;
+
+    // locate the EXTDTA bytes, if any
+    Integer key = new Integer(column);
+
+    if (extdtaPositions_.containsKey (key)) {
+      //  found, get the data
+      int extdtaQueuePosition = ((Integer) extdtaPositions_.get(key)).intValue();
+      data = (byte[]) (extdtaData_.get(extdtaQueuePosition));
+    }
+
+    return data;
+  }
+
+  public Blob getBlobColumn_ (int column, Agent agent) throws SqlException
+  {
+    int index = column - 1;
+    int dataOffset;
+    byte[] data;
+    Blob blob = null;
+
+    // locate the EXTDTA bytes, if any
+    data = findExtdtaData (column);
+
+    if (data != null) {
+      // data found
+      // set data offset based on the presence of a null indicator 
+		if (!nullable_[index])
+			dataOffset = 0;
+		else
+			dataOffset = 1;
+
+      blob = new Blob ( data, agent, dataOffset);
+    }
+    else {
+      blob = new Blob (new byte[0], agent, 0);
+    }
+
+    return blob;
+  }
+
+
+  public Clob getClobColumn_ (int column, Agent agent) throws SqlException
+  {
+    int index = column - 1;
+    int dataOffset;
+    byte[] data;
+    Clob clob = null;
+
+    // locate the EXTDTA bytes, if any
+    data = findExtdtaData (column);
+
+    if (data != null) {
+      // data found
+      // set data offset based on the presence of a null indicator
+      if (! nullable_[index])
+        dataOffset = 0;
+      else
+        dataOffset = 1;
+      clob = new Clob (agent, data, charsetName_[index], dataOffset);
+    }
+    else {
+      // the locator is not valid, it is a zero-length LOB
+      clob = new Clob (agent, "");
+    }
+
+    return clob;
+  }
+
+  public byte[] getClobBytes_ (int column, int[] dataOffset /*output*/) throws SqlException
+  {
+    int index = column - 1;
+    byte[] data = null;
+
+    // locate the EXTDTA bytes, if any
+    data = findExtdtaData (column);
+
+    if (data != null) {
+      // data found
+      // set data offset based on the presence of a null indicator 
+      if (! nullable_[index])
+       dataOffset[0] = 0;
+      else
+       dataOffset[0] = 1;
+    }
+
+    return data;
+  }
+
+  // this is really an event-callback from NetStatementReply.parseSQLDTARDarray()
+  void initializeColumnInfoArrays (Typdef typdef,
+                           int columnCount, int targetSqlamForTypdef) throws DisconnectException
+  {
+    qrydscTypdef_ = typdef;
+
+    // Allocate  arrays to hold the descriptor information.
+    setNumberOfColumns (columnCount);
+    fdocaLength_ = new int[columnCount];
+    isGraphic_ = new boolean[columnCount];
+    typeToUseForComputingDataLength_ = new int[columnCount];
+    targetSqlamForTypdef_ = targetSqlamForTypdef;
+  }
+
+
+  int ensureSpaceForDataBuffer (int ddmLength) 
+  {
+    if (dataBuffer_ == null) {
+      allocateDataBuffer();
+    }
+    //super.resultSet.cursor.clearColumnDataOffsetsCache();
+    // Need to know how many bytes to ask from the Reply object,
+    // and handle the case where buffer is not big enough for all the bytes.
+    // Get the length in front of the code point first.
+
+    int bytesAvailableInDataBuffer = dataBuffer_.length - lastValidBytePosition_;
+
+    // Make sure the buffer has at least ddmLength amount of room left.
+    // If not, expand the buffer before calling the getQrydtaData() method.
+    if (bytesAvailableInDataBuffer < ddmLength) {
+
+      // Get a new buffer that is twice the size of the current buffer.
+      // Copy the contents from the old buffer to the new buffer.
+      int newBufferSize = 2 * dataBuffer_.length;
+
+      while (newBufferSize < ddmLength) {
+        newBufferSize = 2 * newBufferSize;
+      }
+
+      byte[] tempBuffer = new byte[newBufferSize];
+
+      System.arraycopy (dataBuffer_,
+                        0,
+                        tempBuffer,
+                        0,
+                        lastValidBytePosition_);
+
+      // Make the new buffer the dataBuffer.
+      dataBuffer_ = tempBuffer;
+
+      // Recalculate bytesAvailableInDataBuffer
+      bytesAvailableInDataBuffer = dataBuffer_.length - lastValidBytePosition_;
+    }
+    return bytesAvailableInDataBuffer;
+  }
+
+  protected void getMoreData_ () throws SqlException
+  {
+    // reset the dataBuffer_ before getting more data if cursor is foward-only.
+    // getMoreData() is only called in Cursor.next() when current position is
+    // equal to lastValidBytePosition_.
+    if (netResultSet_.resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
+      resetDataBuffer();
+    netResultSet_.flowFetch ();
+  }
+
+  public void nullDataForGC ()       // memory leak fix 
+  {
+    super.nullDataForGC();
+    qrydscTypdef_ = null;
+    typeToUseForComputingDataLength_ = null;
+    isGraphic_ = null;
+
+    if (extdtaPositions_ != null) extdtaPositions_.clear();
+    extdtaPositions_ = null;
+
+    if (extdtaData_ != null) extdtaData_.clear();
+    extdtaData_ = null;
+  }
+
+  // It is possible for the driver to have received an QRYDTA(with incomplete row)+ENDQRYRM+SQLCARD.
+  // This means some error has occurred on the server and the server is terminating the query.
+  // Before sending a CNTQRY to retrieve the rest of the split row, check if an ENDQRYRM has already
+  // been received.  If so, do not send CNTQRY because the cursor is already closed on the server.
+  // Instead, throw a SqlException.  Since we did not receive a complete row, it is not safe to
+  // allow the application to continue to access the ResultSet, so we close it.
+  private void checkAndThrowReceivedEndqryrm () throws SqlException
+  {
+    // If we are in a split row, and before sending CNTQRY, check whether an ENDQRYRM
+    // has been received.
+    if (!netResultSet_.openOnServer_) {
+      SqlException sqlException = null;
+      int sqlcode = org.apache.derby.client.am.Utils.getSqlcodeFromSqlca (netResultSet_.queryTerminatingSqlca_);
+      if (sqlcode < 0)
+        sqlException = new SqlException (agent_.logWriter_, netResultSet_.queryTerminatingSqlca_);
+      else
+        sqlException = new SqlException (agent_.logWriter_, "Query processing has been terminated due to error on the server.");
+      try {
+        netResultSet_.closeX(); // the auto commit logic is in closeX()
+      }
+      catch (SqlException e) {
+        sqlException.setNextException (e);
+      }
+      throw sqlException;
+    }
+  }
+
+  private void checkAndThrowReceivedEndqryrm (int lastValidBytePositionBeforeFetch) throws SqlException
+  {
+    // if we have received more data in the dataBuffer_, just return.
+    if (lastValidBytePosition_ > lastValidBytePositionBeforeFetch)
+      return;
+    checkAndThrowReceivedEndqryrm ();
+  }
+
+  private int completeSplitRow () throws DisconnectException, SqlException
+  {
+    int lastValidBytePositionBeforeFetch = 0;
+    if (netResultSet_ != null && netResultSet_.scrollable_) {
+      lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+      netResultSet_.flowFetchToCompleteRowset ();
+    }
+    else {
+      // Shift partial row to the beginning of the dataBuffer
+      shiftPartialRowToBeginning ();
+      resetCurrentRowPosition ();
+      lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+      netResultSet_.flowFetch ();
+    }
+    return lastValidBytePositionBeforeFetch;
+  }
+
+  private int completeSplitRow (int index) throws DisconnectException, SqlException
+  {
+    int lastValidBytePositionBeforeFetch = 0;
+    if (netResultSet_ != null && netResultSet_.scrollable_) {
+      lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+      netResultSet_.flowFetchToCompleteRowset ();
+    }
+    else {
+      // Shift partial row to the beginning of the dataBuffer
+      shiftPartialRowToBeginning ();
+      adjustColumnOffsetsForColumnsPreviouslyCalculated (index);
+      resetCurrentRowPosition ();
+      lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+      netResultSet_.flowFetch ();
+    }
+    return lastValidBytePositionBeforeFetch;
+  }
+
+  private int[] allocateColumnDataPositionArray (int row)
+  {
+    int[] columnDataPosition;
+    if (columnDataPositionCache_.size() == row) {
+      columnDataPosition = new int[columns_];
+      columnDataPositionCache_.add (columnDataPosition);
+    }
+    else
+      columnDataPosition = (int[])columnDataPositionCache_.get(row);
+    return columnDataPosition;
+  }
+
+  private int[] allocateColumnDataComputedLengthArray (int row)
+  {
+    int[] columnDataComputedLength;
+    if (columnDataLengthCache_.size() == row) {
+      columnDataComputedLength = new int[columns_];
+      columnDataLengthCache_.add (columnDataComputedLength);
+    }
+    else
+      columnDataComputedLength = (int[])columnDataLengthCache_.get(row);
+    return columnDataComputedLength;
+  }
+
+  private boolean[] allocateColumnDataIsNullArray (int row)
+  {
+    boolean[] columnDataIsNull;
+    if (columnDataIsNullCache_.size() <= row) {
+      columnDataIsNull = new boolean[columns_];
+      columnDataIsNullCache_.add(columnDataIsNull);
+    }
+    else
+      columnDataIsNull = (boolean[])columnDataIsNullCache_.get(row);
+    return columnDataIsNull;
+  }
+
+  protected int getDecimalLength (int index)
+  {
+    return (((fdocaLength_[index] >> 8) & 0xff) + 2) / 2;
+  }
+
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,80 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.NetDatabaseMetaData
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   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 org.apache.derby.client.net;
+
+import org.apache.derby.client.am.Configuration;
+import org.apache.derby.client.am.ProductLevel;
+import org.apache.derby.client.am.SqlException;
+
+
+public class NetDatabaseMetaData extends org.apache.derby.client.am.DatabaseMetaData
+{
+
+  private final NetAgent netAgent_;
+
+
+  public NetDatabaseMetaData (NetAgent netAgent, NetConnection netConnection)
+  {
+    // Consider setting product level during parse
+    super (netAgent, netConnection, new ProductLevel (netConnection.productID_,
+                          netConnection.targetSrvclsnm_,
+                          netConnection.targetSrvrlslv_));
+    // Set up cheat-links
+    netAgent_ = netAgent;
+  }
+
+  //---------------------------call-down methods--------------------------------
+
+  public String getURL_ () throws SqlException
+  {
+    String urlProtocol;
+
+      urlProtocol = Configuration.jdbcDerbyNETProtocol;
+
+    return
+      urlProtocol +
+      connection_.serverNameIP_+
+      ":" +
+      connection_.portNumber_ +
+      "/" +
+      connection_.databaseName_;
+  }
+
+  //-----------------------------helper methods---------------------------------
+
+  // Set flags describing the level of support for this connection.
+  // Flags will be set based on manager level and/or specific product identifiers.
+  // Support for a specific server version can be set as follows. For example
+  // if (productLevel_.greaterThanOrEqualTo(11,1,0))
+  //  supportsTheBestThingEver = true
+  protected void computeFeatureSet_ ()
+  {
+    if (connection_.resultSetHoldability_ == 0)  // property not set
+      setDefaultResultSetHoldability ();
+
+  }
+
+
+  public void setDefaultResultSetHoldability ()
+  {
+	  connection_.resultSetHoldability_ = org.apache.derby.jdbc.ClientDataSource.HOLD_CURSORS_OVER_COMMIT;
+  }
+
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,84 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.NetXACallInfo
+
+   Copyright (c) 2002, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   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 org.apache.derby.client.net;
+
+import javax.transaction.xa.*;
+
+/**
+ * <p>Title: dnc Project</p>
+ * <p>Description: </p>
+ * @version 1.0
+ */
+
+public class NetIndoubtTransaction
+{
+
+    Xid xid_;
+    byte[] uowid_;
+    byte[] cSyncLog_;
+    byte[] pSyncLog_;
+    String ipaddr_;
+    int port_;
+
+    protected NetIndoubtTransaction(Xid xid,
+                                   byte[] uowid,
+                                   byte[] cSyncLog,
+                                   byte[] pSyncLog,
+                                   String ipaddr,
+                                   int port)
+    {
+      xid_ = xid;
+      uowid_ = uowid;
+      cSyncLog_ = cSyncLog;
+      pSyncLog_ = pSyncLog;
+      ipaddr_ = ipaddr;
+      port_ = port;
+    }
+
+    protected Xid getXid()
+    {
+      return xid_;
+    }
+
+    protected byte[] getUOWID()
+    {
+      return uowid_;
+    }
+
+    protected byte[] getCSyncLog()
+    {
+      return cSyncLog_;
+    }
+
+    protected byte[] getPSyncLog()
+    {
+      return pSyncLog_;
+    }
+
+    protected String getIpAddr()
+    {
+      return ipaddr_;
+    }
+
+    protected int getPort()
+    {
+      return port_;
+    }
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,416 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.NetLogWriter
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   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 org.apache.derby.client.net;
+
+// network traffic tracer.
+// This class traces communication buffers for both sends and receives.
+// The value of the hex bytes are traced along with the ascii and ebcdic translations.
+public class NetLogWriter extends org.apache.derby.client.am.LogWriter
+{
+
+  // The recevie constant is used to indicate that the bytes were read to a Stream.
+  // It indicates to this class that a receive header should be used.
+  public static final int TYPE_TRACE_RECEIVE = 2;
+
+  // The send constant is used to indicate that the bytes were written to
+  // a Stream.  It indicates to this class that a send header should be used.
+  public static final int TYPE_TRACE_SEND = 1;
+
+  //------------------------------ internal constants --------------------------
+
+  // This class was implemented using character arrays to translate bytes
+  // into ascii and ebcdic.  The goal was to be able to quickly index into the
+  // arrays to find the characters.  Char arrays instead of strings were used as
+  // much as possible in an attempt to help speed up performance.
+
+  // An array of characters used to translate bytes to ascii.
+  // The position in the array corresponds to the hex value of the character.
+  private static final char asciiChar__ [] = {
+    // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //0
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //1
+    ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', //2
+    '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',  //3
+    '@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',  //4
+    'P','Q','R','S','T','U','V','W','X','Y','Z','[','\\',']','^','_', //5
+    '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',  //6
+    'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~','.',  //7
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //8
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //9
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //A
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //B
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //C
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //D
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //E
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.'   //F
+  };
+
+  // This column position header is used to mark offsets into the trace.
+  private static final String colPosHeader__ =
+    "       0 1 2 3 4 5 6 7   8 9 A B C D E F   0123456789ABCDEF  0123456789ABCDEF";
+
+  // An array of characters used to translate bytes to ebcdic.
+  // The position in the array corresponds to the hex value of the
+  // character.
+  private static final char ebcdicChar__[] = {
+    // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //0
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //1
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //2
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //3
+    ' ','.','.','.','.','.','.','.','.','.','.','.','<','(','+','|',  //4
+    '&','.','.','.','.','.','.','.','.','.','!','$','*',')',';','.',  //5
+    '-','/','.','.','.','.','.','.','.','.','|',',','%','_','>','?',  //6
+    '.','.','.','.','.','.','.','.','.','`',':','#','@','\'','=','"', //7
+    '.','a','b','c','d','e','f','g','h','i','.','.','.','.','.','.',  //8
+    '.','j','k','l','m','n','o','p','q','r','.','.','.','.','.','.',  //9
+    '.','~','s','t','u','v','w','x','y','z','.','.','.','.','.','.',  //A
+    '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',  //B
+    '{','A','B','C','D','E','F','G','H','I','.','.','.','.','.','.',  //C
+    '}','J','K','L','M','N','O','P','Q','R','.','.','.','.','.','.',  //D
+    '\\','.','S','T','U','V','W','X','Y','Z','.','.','.','.','.','.', //E
+    '0','1','2','3','4','5','6','7','8','9','.','.','.','.','.','.'   //F
+  };
+
+  // An array of characters representing hex numbers.
+  private static final char hexDigit__ [] = {
+    '0','1','2','3','4','5','6','7',
+    '8','9','A','B','C','D','E','F'
+  };
+
+  // The receive header comes befor bytes which would be read from a stream.
+  private static final String receiveHeader__ =
+    "       RECEIVE BUFFER:                     (ASCII)           (EBCDIC)";
+
+  // The send header comes before bytes which would be written to a stream.
+  private static final String sendHeader__ =
+    "       SEND BUFFER:                        (ASCII)           (EBCDIC)";
+
+  private static final char spaceChar__ = ' ';
+
+  private static final char zeroChar__ = '0';
+
+  // This mapping table associates a codepoint to a String describing the codepoint.
+  // This is needed because the trace prints the first codepoint in send and receive buffers.
+  // This is created lazily because there is no need to create the mapping if tracing isn't used.
+  // So this array will only be created when the com buffer trace is started.
+  private static CodePointNameTable codePointNameTable__ = null;
+
+  //-----------------------------internal state---------------------------------
+
+  //-----------------------------constructors/finalizer-------------------------
+
+  // One NetLogWriter object is created per data source, iff tracing is enabled.
+  public NetLogWriter (java.io.PrintWriter printWriter, int traceLevel)
+  {
+    super (printWriter, traceLevel);
+
+    // Initialize the codepoint name table if not previously initialized.
+    // This is done lazily so that it is not created if the trace isn't used (save some init time).
+    if (codePointNameTable__ == null) {
+      codePointNameTable__ = new CodePointNameTable();
+    }
+  }
+
+  //------------------------------entry points----------------------------------
+
+  // Specialization of LogWriter.traceConnectsExit()
+  public void traceConnectsExit (org.apache.derby.client.am.Connection connection)
+  {
+    if (traceSuspended()) return;
+    NetConnection c = (NetConnection) connection;
+    synchronized (printWriter_) {
+      super.traceConnectsExit (c);
+      dncnetprint  ("  PROTOCOL manager levels: { ");
+      printWriter_.print ("SQLAM=" + c.getSQLAM() + ", ");
+      printWriter_.print ("AGENT=" + c.getAGENT() + ", ");
+      printWriter_.print ("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
+      printWriter_.print ("RDB=" + c.getRDB() + ", ");
+      printWriter_.print ("SECMGR=" + c.getSECMGR() + ", ");
+      printWriter_.print ("XAMGR=" + c.getXAMGR() + ", ");
+      printWriter_.print ("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
+      printWriter_.print ("RSYNCMGR=" + c.getRSYNCMGR());
+      printWriter_.println  (" }");
+      printWriter_.flush();
+    }
+  }
+
+  public void traceConnectsResetExit (org.apache.derby.client.am.Connection connection)
+  {
+    if (traceSuspended()) return;
+    NetConnection c = (NetConnection) connection;
+    synchronized (printWriter_) {
+      super.traceConnectsResetExit (c);
+      dncnetprint  ("  PROTOCOL manager levels: { ");
+      printWriter_.print ("SQLAM=" + c.getSQLAM() + ", ");
+      printWriter_.print ("AGENT=" + c.getAGENT() + ", ");
+      printWriter_.print ("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
+      printWriter_.print ("RDB=" + c.getRDB() + ", ");
+      printWriter_.print ("SECMGR=" + c.getSECMGR() + ", ");
+      printWriter_.print ("XAMGR=" + c.getXAMGR() + ", ");
+      printWriter_.print ("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
+      printWriter_.print ("RSYNCMGR=" + c.getRSYNCMGR());
+      printWriter_.println  (" }");
+      printWriter_.flush();
+    }
+  }
+
+  // Pass the connection handle and print it in the header 
+  // What exactly is supposed to be passed,  assume one complete DSS packet
+  // Write the communication buffer data to the trace.
+  // The data is passed in via a byte array.  The start and length of the data is given.
+  // The type is needed to indicate if the data is part of the send or receive buffer.
+  // The class name, method name, and trcPt number are also written to the trace.
+  // Not much checking is performed on the parameters.  This is done to help performance.
+  synchronized public void traceProtocolFlow (byte[] buff,
+					       int offset,
+					       int len,
+					       int type,
+					       String className,
+					       String methodName,
+					       int tracepoint)
+  {
+    if (traceSuspended()) return;
+    if (!loggingEnabled (org.apache.derby.jdbc.ClientDataSource.TRACE_PROTOCOL_FLOWS)) return;
+    synchronized (printWriter_) {
+      super.tracepoint ("[net]", tracepoint, className, methodName);
+
+      int fullLen = len;
+      boolean printColPos = true;
+      while( fullLen >= 2 )
+      { // format each DssHdr seperately
+        // get the length of this DssHdr
+        len = ((buff[offset] & 0xff) << 8) + ((buff[offset+1] & 0xff) << 0);
+
+        // check for valid dss header or not all of dss block
+        if ((len < 10) || (len > fullLen))
+          len = fullLen;
+
+        // subtract that length from the full length
+        fullLen -= len;
+      // The data will only be written if there is a non-zero positive length.
+      if (len != 0) {
+	String codePointName = null;
+	// If the length <= 10, lookup the first codepoint so it's name can be printed
+	if (len >= 10) {
+	  // Get the int value of the two byte unsigned codepoint.
+	  int codePoint = getCodePoint (buff, offset+8);
+	  codePointName = codePointNameTable__.lookup (codePoint);
+
+    // if this is not a valid codepoint then format the entire buffer
+    // as one block.
+    if (codePointName == null)
+    {
+      len += fullLen;
+      fullLen = 0;
+    }
+	}
+
+          if( !printColPos )
+          { // not 1st Dss header of this buffer, write seperator
+            dncnetprintln( "" );
+          }
+
+	if (codePointName == null) {
+	  // codePointName was still null so either < 10 bytes were given or
+	  // the codepoint wasn't found in the table.  Just print the plain send header.
+	  dncnetprintln (getHeader (type));
+	}
+	else {
+	  // codePointName isn't null so the name of the codepoint will be printed.
+	  printHeaderWithCodePointName (codePointName, type);
+	}
+
+	// Print the col position header in the trace.
+          if( printColPos )
+          { // first Dss header of buffer, need column position header
+	dncnetprintln (colPosHeader__);
+            printColPos = false;
+          }
+
+	// A char array will be used to translate the bytes to their character
+	// representations along with ascii and ebcdic representations.
+	char trcDump[] = new char[77];
+
+	// bCounter, aCounter, eCounter are offsets used to help position the characters
+	short bCounter = 7;
+	short aCounter = 43;
+	short eCounter = 61;
+
+	// The lines will be counted starting at zero.
+        // This is hard coded since we are at the beginning.
+	trcDump[0] = zeroChar__;
+	trcDump[1] = zeroChar__;
+	trcDump[2] = zeroChar__;
+	trcDump[3] = zeroChar__;
+
+	// The 0's are already in the trace so bump the line counter up a row.
+	int lineCounter = 0x10;
+
+	// Make sure the character array has all blanks in it.
+	// Some of these blanks will be replaced later with values.
+	// The 0's were not wrote over.
+	for (int j = 4; j < 77; j++) {
+	  trcDump[j] = spaceChar__;
+	}
+
+	// i will maintain the position in the byte array to be traced.
+	int i = 0;
+
+	do {
+	  // Get the unsigned value of the byte.
+	  //                  int num = b[off++] & 0xff;
+	  int num = (buff[offset] < 0)? buff[offset] + 256 : buff[offset];
+	  offset++;
+	  i++;
+	  // Place the characters representing the bytes in the array.
+	  trcDump[bCounter++] = hexDigit__[((num >>> 4) & 0xf)];
+	  trcDump[bCounter++] = hexDigit__[(num & 0xf)];
+
+	  // Place the ascii and ebcdc representations in the array.
+	  trcDump[aCounter++] = asciiChar__[num];
+	  trcDump[eCounter++] = ebcdicChar__[num];
+
+	  if (((i%8) == 0)) {
+	    if (((i%16) == 0)) {
+	      // Print the array each time 16 bytes are processed.
+              dncnetprintln (trcDump);
+	      if (i != len) {
+		// Not yet at the end of the byte array.
+		if ((len - i) < 16) {
+		  // This is the last line so blank it all out.
+		  // This keeps the last line looking pretty in case
+		  // < 16 bytes remain.
+		  for (int j = 0; j < trcDump.length; j++) {
+		    trcDump[j] = spaceChar__;
+		  }
+		}
+		// Reset the counters.
+		bCounter = 0;
+		aCounter = 43;
+		eCounter = 61;
+		// Reset the lineCounter if it starts to get too large.
+		if (lineCounter == 0x100000) {
+		  lineCounter = 0;
+		}
+		// Place the characters representing the line counter in the array.
+		trcDump[bCounter++] = hexDigit__[((lineCounter >>> 12) & 0xf)];
+		trcDump[bCounter++] = hexDigit__[((lineCounter >>> 8) & 0xf)];
+		trcDump[bCounter++] = hexDigit__[((lineCounter >>> 4) & 0xf)];
+		trcDump[bCounter++] = hexDigit__[(lineCounter & 0xf)];
+		bCounter += 3;
+		// Bump up the line counter.
+		lineCounter += 0x10;
+	      }
+	    }
+	    else {
+	      // 8 bytes were processed so move the counter to adjust for
+	      // spaces between the columns of bytes.
+	      bCounter += 2;
+	    }
+	  }
+	  // do this until we all the data has been traced.
+	}
+        while (i < len);
+
+	// print the last line and add some blank lines to make it easier to read.
+	if (len % 16 != 0) {
+          dncnetprintln (trcDump);
+	}
+      }
+      }
+      dncnetprintln ("");
+    }
+  }
+
+  // Gets the int value of the two byte unsigned codepoint.
+  private static int getCodePoint (byte[] buff, int offset)
+  {
+    return ((buff[offset++] & 0xff) << 8) +
+      ((buff[offset] & 0xff) << 0);
+  }
+
+  private static String getHeader (int type)
+  {
+    switch (type) {
+    case TYPE_TRACE_SEND:
+      return sendHeader__;
+    case TYPE_TRACE_RECEIVE:
+      return receiveHeader__;
+    default:
+      return null;
+    }
+  }
+
+  private static int getStartPosition (int type)
+  {
+    switch (type) {
+    case TYPE_TRACE_SEND:
+      return 20; // This is right after 'SEND BUFFER: '.
+    case TYPE_TRACE_RECEIVE:
+      return 23; // This is right after 'RECEIVE BUFFER: '.
+    default:
+      return 0;
+    }
+  }
+
+  private void printHeaderWithCodePointName (String codePointName, int type)
+  {
+    // Create a char array so some of the characters
+    // can be replaced with the name of the codepoint.
+    char headerArray[] = getHeader(type).toCharArray();
+
+    // At most, 16 character name will be used.  This is so
+    // the headers on top of the ascii and ebcdic rows aren't shifted.
+    int replaceLen = (codePointName.length() < 17) ? codePointName.length() : 16;
+
+    int offset = getStartPosition (type);
+    for (int i = 0; i < replaceLen; i++) {
+      headerArray[offset++] = codePointName.charAt (i); 
+    }
+    dncnetprintln (headerArray);
+  }
+
+  private void dncnetprint (String s)
+  {
+    synchronized (printWriter_) {
+      printWriter_.print ("[derby] " + s);
+      printWriter_.flush();
+    }
+  }
+
+  private void dncnetprintln (String s)
+  {
+    synchronized (printWriter_) {
+      printWriter_.println ("[derby] " + s);
+      printWriter_.flush();
+    }
+  }
+
+  private void dncnetprintln (char[] s)
+  {
+    synchronized (printWriter_) {
+      printWriter_.print ("[derby] ");
+      printWriter_.println (s);
+      printWriter_.flush();
+    }
+  }
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message