Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 14973 invoked from network); 25 Feb 2009 18:15:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 25 Feb 2009 18:15:43 -0000 Received: (qmail 32788 invoked by uid 500); 25 Feb 2009 18:15:43 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 32773 invoked by uid 500); 25 Feb 2009 18:15:42 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 32764 invoked by uid 99); 25 Feb 2009 18:15:42 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Feb 2009 10:15:42 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Feb 2009 18:15:42 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C90102388962; Wed, 25 Feb 2009 18:15:21 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r747881 - in /db/derby/code/trunk/java/client/org/apache/derby/client/net: CcsidManager.java EbcdicCcsidManager.java NetConnectionRequest.java Request.java Date: Wed, 25 Feb 2009 18:15:20 -0000 To: derby-commits@db.apache.org From: kmarsden@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090225181521.C90102388962@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: kmarsden Date: Wed Feb 25 18:15:19 2009 New Revision: 747881 URL: http://svn.apache.org/viewvc?rev=747881&view=rev Log: DERBY-4009 (partial) Accommodate length delimited DRDA strings where character length does not equal byte length Change client RDBNAM, USERID, and PASSWORD to allow for CcsidManager where the byte length might not equal the string length. Right now we just have EbcdicCcsidManager which has a maximum bytes per char as 1. But, this lays the groundwork for UTF8 which will be added later as part of DERBY-728 Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/CcsidManager.java db/derby/code/trunk/java/client/org/apache/derby/client/net/EbcdicCcsidManager.java db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/CcsidManager.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/CcsidManager.java?rev=747881&r1=747880&r2=747881&view=diff ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/CcsidManager.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/CcsidManager.java Wed Feb 25 18:15:19 2009 @@ -89,5 +89,13 @@ // @return The converted Java char. abstract char convertToUCS2Char(byte sourceByte); + + + /** + * + * @return Maximum number of bytes per character + */ + abstract int maxBytesPerChar(); + } Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/EbcdicCcsidManager.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/EbcdicCcsidManager.java?rev=747881&r1=747880&r2=747881&view=diff ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/EbcdicCcsidManager.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/EbcdicCcsidManager.java Wed Feb 25 18:15:19 2009 @@ -182,5 +182,13 @@ return (char) conversionArrayToUCS2[(sourceByte < 0) ? (sourceByte + 256) : sourceByte]; } + + /* (non-Javadoc) + * @see org.apache.derby.client.net.CcsidManager#maxBytesPerChar() + */ + int maxBytesPerChar() { + return 1; + } + } Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java?rev=747881&r1=747880&r2=747881&view=diff ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java Wed Feb 25 18:15:19 2009 @@ -490,20 +490,12 @@ } } - 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_, - new ClientMessageId(SQLState.NET_DBNAME_TOO_LONG), rdbnam); - } - //"at SQLAM level " + netAgent_.targetSqlam_); - } + + writeScalarString(CodePoint.RDBNAM, rdbnam, + NetConfiguration.PKG_IDENTIFIER_FIXED_LEN, //minimum RDBNAM length in bytes + NetConfiguration.PKG_IDENTIFIER_MAX_LEN, //maximum RDBNAM length in bytes + SQLState.NET_DBNAME_TOO_LONG); + } private void buildSECTKN(byte[] sectkn) throws SqlException { @@ -515,18 +507,14 @@ } private void buildUSRID(String usrid) throws SqlException { - int usridLength = usrid.length(); - if ((usridLength == 0) || (usridLength > NetConfiguration.USRID_MAXSIZE)) { - throw new SqlException(netAgent_.logWriter_, - new ClientMessageId(SQLState.NET_USERID_TOO_LONG)); - } - - writeScalarString(CodePoint.USRID, usrid); + + writeScalarString(CodePoint.USRID, usrid,0,NetConfiguration.USRID_MAXSIZE, + SQLState.NET_USERID_TOO_LONG); } private void buildPASSWORD(String password) throws SqlException { int passwordLength = password.length(); - if ((passwordLength == 0) || (passwordLength > NetConfiguration.PASSWORD_MAXSIZE)) { + if ((passwordLength == 0) ) { throw new SqlException(netAgent_.logWriter_, new ClientMessageId(SQLState.NET_PASSWORD_TOO_LONG)); } @@ -535,9 +523,12 @@ // mask it out in trace (see Request.sendBytes()). passwordIncluded_ = true; passwordStart_ = offset_ + 4; - passwordLength_ = passwordLength; } - writeScalarString(CodePoint.PASSWORD, password); + writeScalarString(CodePoint.PASSWORD, password, 0, NetConfiguration.PASSWORD_MAXSIZE, + SQLState.NET_PASSWORD_TOO_LONG); + if (netAgent_.logWriter_ != null) { + passwordLength_ = offset_ - passwordStart_; + } } private void buildRDBACCCL() throws SqlException { Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java?rev=747881&r1=747880&r2=747881&view=diff ============================================================================== --- db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java (original) +++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java Wed Feb 25 18:15:19 2009 @@ -1246,51 +1246,73 @@ bytes_[offset_++] = (byte) (codePoint & 0xff); } - // insert a 4 byte length/codepoint pair plus ddm character data into - // the buffer. This method assumes that the String argument can be - // converted by the ccsid manager. This should be fine because usually - // there are restrictions on the characters which can be used for ddm - // character data. This method also assumes that the string.length() will - // be the number of bytes following the conversion. - // The two byte length field will contain the length of the character data - // and the length of the 4 byte llcp. This method does not handle - // scenarios which require extended length bytes. + /** + * Write string with no minimum or maximum limit. + * @param codePoint codepoint to write + * @param string value to write + * @throws SqlException + */ final void writeScalarString(int codePoint, String string) throws SqlException { - int stringLength = string.length(); - ensureLength(offset_ + stringLength + 4); - bytes_[offset_++] = (byte) (((stringLength + 4) >>> 8) & 0xff); - bytes_[offset_++] = (byte) ((stringLength + 4) & 0xff); - bytes_[offset_++] = (byte) ((codePoint >>> 8) & 0xff); - bytes_[offset_++] = (byte) (codePoint & 0xff); - offset_ = ccsidManager_.convertFromUCS2(string, bytes_, offset_, netAgent_); - } - - // insert a 4 byte length/codepoint pair plus ddm character data into the - // buffer. The ddm character data is padded if needed with the ccsid manager's - // space character if the length of the character data is less than paddedLength. - // Note: this method is not to be used for String truncation and the string length - // must be <= paddedLength. - // This method assumes that the String argument can be - // converted by the ccsid manager. This should be fine because usually - // there are restrictions on the characters which can be used for ddm - // character data. This method also assumes that the string.length() will - // be the number of bytes following the conversion. The two byte length field - // of the llcp will contain the length of the character data including the pad - // and the length of the llcp or 4. This method will not handle extended length - // scenarios. - final void writeScalarPaddedString(int codePoint, String string, int paddedLength) throws SqlException { - int stringLength = string.length(); - ensureLength(offset_ + paddedLength + 4); - bytes_[offset_++] = (byte) (((paddedLength + 4) >>> 8) & 0xff); - bytes_[offset_++] = (byte) ((paddedLength + 4) & 0xff); + writeScalarString(codePoint, string, 0,Integer.MAX_VALUE,null); + + } + + /** + * insert a 4 byte length/codepoint pair plus ddm character data into + * the buffer. This method assumes that the String argument can be + * converted by the ccsid manager. This should be fine because usually + * there are restrictions on the characters which can be used for ddm + * character data. + * The two byte length field will contain the length of the character data + * and the length of the 4 byte llcp. This method does not handle + * scenarios which require extended length bytes. + * + * @param codePoint codepoint to write + * @param string value + * @param byteMinLength minimum length. String will be padded with spaces + * if value is too short. Assumes space character is one byte. + * @param byteLengthLimit Limit to string length. SQLException will be + * thrown if we exceed this limit. + * @param sqlState SQLState to throw with string as param if byteLengthLimit + * is exceeded. + * @throws SqlException if string exceeds byteLengthLimit + */ + final void writeScalarString(int codePoint, String string, int byteMinLength, + int byteLengthLimit, String sqlState) throws SqlException { + int maxByteLength = ccsidManager_.maxBytesPerChar() * string.length(); + ensureLength(offset_ + maxByteLength + 4); + // Skip length for now until we know actual length + int lengthOffset = offset_; + offset_ += 2; + bytes_[offset_++] = (byte) ((codePoint >>> 8) & 0xff); bytes_[offset_++] = (byte) (codePoint & 0xff); + offset_ = ccsidManager_.convertFromUCS2(string, bytes_, offset_, netAgent_); - for (int i = 0; i < paddedLength - stringLength; i++) { - bytes_[offset_++] = ccsidManager_.space_; + + int stringByteLength = offset_ - lengthOffset - 4; + // reset the buffer and throw an SQLException if the length is too long + if (stringByteLength > byteLengthLimit) { + offset_ = lengthOffset; + throw new SqlException(netAgent_.logWriter_, + new ClientMessageId(sqlState), string); } + // pad if we don't reach the byteMinLength limit + if (stringByteLength < byteMinLength) { + for (int i = stringByteLength ; i < byteMinLength; i++) { + bytes_[offset_++] = ccsidManager_.space_; + } + stringByteLength = byteMinLength; + } + // now write the length. We have the string byte length plus + // 4 bytes, 2 for length and 2 for codepoint. + int totalLength = stringByteLength + 4; + bytes_[lengthOffset] = (byte) ((totalLength >>> 8) & 0xff); + bytes_[lengthOffset + 1] = (byte) ((totalLength) & 0xff); } + + // this method inserts ddm character data into the buffer and pad's the // data with the ccsid manager's space character if the character data length // is less than paddedLength.