You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by bp...@apache.org on 2010/08/06 04:37:13 UTC

svn commit: r982852 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functionTests/tests/derbynet/

Author: bpendleton
Date: Fri Aug  6 02:37:12 2010
New Revision: 982852

URL: http://svn.apache.org/viewvc?rev=982852&view=rev
Log:
DERBY-4757: Implement UTF8 support in DRDA (Client changes)

This patch was contributed by Tiago R. Espinha (tiago dot derby at yahoo dot co dot uk)

This patch lays the foundation for the UTF-8 support in the client:
- Changes the method names for the CcsidManager abstract class so that
they are clearer in terms of what they do (convertToJavaString,
convertFromJavaString) similar to what's been done for the server. 
- Introduces a new name to the CcsidManager that returns, for the given
CcsidManager, the length of a String in bytes (which differs for the
different managers). 
- Creates the Utf8CcsidManager.java for the client and the respective
Utf8CcsidManagerClientTest.java.
- Changes NetAgent.java so that it no longer has a source and target
CCSID managers. Also, similarly to the server, it now has an instance
of each type of CCSID (EBCDIC and UTF-8) and a current CCSID which is
the one currently in use. 

This patch does not yet enable UTF-8 support but puts everything in
place so that the switch mechanism can be implemented. 


Added:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Utf8CcsidManager.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/Utf8CcsidManagerClientTest.java
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/NetAgent.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.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/Reply.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.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=982852&r1=982851&r2=982852&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 Fri Aug  6 02:37:12 2010
@@ -52,7 +52,7 @@ public abstract class CcsidManager {
     //
     // @param sourceString A Java String to convert.
     // @return A new byte array representing the String in a particular ccsid.
-    public abstract byte[] convertFromUCS2(String sourceString, org.apache.derby.client.am.Agent agent) throws org.apache.derby.client.am.SqlException;
+    public abstract byte[] convertFromJavaString(String sourceString, org.apache.derby.client.am.Agent agent) throws org.apache.derby.client.am.SqlException;
 
 
     // Convert a Java String into bytes for a particular ccsid.
@@ -62,16 +62,16 @@ public abstract class CcsidManager {
     // @param buffer        The buffer to convert the String into.
     // @param offset        Offset in buffer to start putting output.
     // @return An int containing the buffer offset after conversion.
-    public abstract int convertFromUCS2(String sourceString,
-                                        byte[] buffer,
-                                        int offset,
-                                        org.apache.derby.client.am.Agent agent) throws org.apache.derby.client.am.SqlException;
+    public abstract int convertFromJavaString(String sourceString,
+                                              byte[] buffer,
+                                              int offset,
+                                              org.apache.derby.client.am.Agent agent) throws org.apache.derby.client.am.SqlException;
 
     // Convert a byte array representing characters in a particular ccsid into a Java String.
     //
     // @param sourceBytes An array of bytes to be converted.
     // @return String A new Java String Object created after conversion.
-    abstract String convertToUCS2(byte[] sourceBytes);
+    abstract String convertToJavaString(byte[] sourceBytes);
 
 
     // Convert a byte array representing characters in a particular ccsid into a Java String.
@@ -80,14 +80,14 @@ public abstract class CcsidManager {
     // @param offset  An offset indicating first byte to convert.
     // @param numToConvert The number of bytes to be converted.
     // @return A new Java String Object created after conversion.
-    abstract String convertToUCS2(byte[] sourceBytes, int offset, int numToConvert);
+    abstract String convertToJavaString(byte[] sourceBytes, int offset, int numToConvert);
 
 
     // Convert a byte representing a char in a particular ccsid into a Java char.
     //
     // @param sourceByte The byte to be converted
     // @return The converted Java char.
-    abstract char convertToUCS2Char(byte sourceByte);
+    abstract char convertToJavaChar(byte sourceByte);
 
 
     
@@ -97,5 +97,11 @@ public abstract class CcsidManager {
      */
     abstract int maxBytesPerChar();
 
+    /**
+     * Get length in bytes for string s
+     * @param s The string from which to obtain the length
+     * @return The length of s in bytes
+     */
+    abstract int getByteLength(String s);
 }
 

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=982852&r1=982851&r2=982852&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 Fri Aug  6 02:37:12 2010
@@ -126,16 +126,16 @@ public class EbcdicCcsidManager extends 
         );
     }
 
-    public byte[] convertFromUCS2(String sourceString, org.apache.derby.client.am.Agent agent) throws SqlException {
+    public byte[] convertFromJavaString(String sourceString, org.apache.derby.client.am.Agent agent) throws SqlException {
         byte[] bytes = new byte[sourceString.length()];
-        convertFromUCS2(sourceString, bytes, 0, agent);
+        convertFromJavaString(sourceString, bytes, 0, agent);
         return bytes;
     }
 
-    public int convertFromUCS2(String sourceString,
-                               byte[] buffer,
-                               int offset,
-                               org.apache.derby.client.am.Agent agent) throws SqlException {
+    public int convertFromJavaString(String sourceString,
+                                     byte[] buffer,
+                                     int offset,
+                                     org.apache.derby.client.am.Agent agent) throws SqlException {
         for (int i = 0; i < sourceString.length(); i++) {
             char c = sourceString.charAt(i);
             if (c > 0xff)
@@ -151,7 +151,7 @@ public class EbcdicCcsidManager extends 
         return offset;
     }
 
-    String convertToUCS2(byte[] sourceBytes) {
+    String convertToJavaString(byte[] sourceBytes) {
         int i = 0;
         char[] theChars = new char[sourceBytes.length];
         int num = 0;
@@ -164,7 +164,7 @@ public class EbcdicCcsidManager extends 
         return new String(theChars);
     }
 
-    String convertToUCS2(byte[] sourceBytes, int offset, int numToConvert) {
+    String convertToJavaString(byte[] sourceBytes, int offset, int numToConvert) {
         int i = 0, j = 0;
         char[] theChars = new char[numToConvert];
         int num = 0;
@@ -178,7 +178,7 @@ public class EbcdicCcsidManager extends 
     }
 
 
-    char convertToUCS2Char(byte sourceByte) {
+    char convertToJavaChar(byte sourceByte) {
         return (char) conversionArrayToUCS2[(sourceByte < 0) ? (sourceByte + 256) : sourceByte];
     }
 
@@ -190,5 +190,9 @@ public class EbcdicCcsidManager extends 
         return 1;
     }
 
+    public int getByteLength(String s) {
+        return s.length();
+    }
+
 }
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java Fri Aug  6 02:37:12 2010
@@ -84,8 +84,12 @@ public class NetAgent extends Agent {
     int port_;
     int clientSSLMode_;
 
-    public CcsidManager sourceCcsidManager_;
-    public CcsidManager targetCcsidManager_;
+    private EbcdicCcsidManager ebcdicCcsidManager_;
+    private Utf8CcsidManager utf8CcsidManager_;
+    private CcsidManager currentCcsidManager_;
+    
+    // TODO: Remove target? Keep just one CcsidManager?
+    //public CcsidManager targetCcsidManager_;
     public Typdef typdef_;
     public Typdef targetTypdef_;
     public Typdef originalTargetTypdef_; // added to support typdef overrides
@@ -166,8 +170,12 @@ public class NetAgent extends Agent {
                 e.getMessage(), e);
         }
 
-        sourceCcsidManager_ = new EbcdicCcsidManager(); // delete these
-        targetCcsidManager_ = sourceCcsidManager_; // delete these
+        ebcdicCcsidManager_ = new EbcdicCcsidManager();
+        utf8CcsidManager_ = new Utf8CcsidManager();
+        currentCcsidManager_ = ebcdicCcsidManager_;
+        
+        // TODO: Remove target? Keep just one ccsidManager?
+        //targetCcsidManager_ = sourceCcsidManager_; // delete these
 
         if (netConnection_.isXAConnection()) {
             NetXAConnectionReply netXAConnectionReply_ = new NetXAConnectionReply(this, netConnection_.commBufferSize_);
@@ -184,7 +192,7 @@ public class NetAgent extends Agent {
             statementReply_ = (StatementReply) resultSetReply_;
             packageReply_ = (ConnectionReply) statementReply_;
             connectionReply_ = (ConnectionReply) packageReply_;
-            NetXAConnectionRequest netXAConnectionRequest_ = new NetXAConnectionRequest(this, sourceCcsidManager_, netConnection_.commBufferSize_);
+            NetXAConnectionRequest netXAConnectionRequest_ = new NetXAConnectionRequest(this, currentCcsidManager_, netConnection_.commBufferSize_);
             netResultSetRequest_ = (NetResultSetRequest) netXAConnectionRequest_;
             netStatementRequest_ = (NetStatementRequest) netResultSetRequest_;
             netPackageRequest_ = (NetPackageRequest) netStatementRequest_;
@@ -209,7 +217,7 @@ public class NetAgent extends Agent {
             statementReply_ = (StatementReply) resultSetReply_;
             packageReply_ = (ConnectionReply) statementReply_;
             connectionReply_ = (ConnectionReply) packageReply_;
-            netResultSetRequest_ = new NetResultSetRequest(this, sourceCcsidManager_, netConnection_.commBufferSize_);
+            netResultSetRequest_ = new NetResultSetRequest(this, currentCcsidManager_, netConnection_.commBufferSize_);
             netStatementRequest_ = (NetStatementRequest) netResultSetRequest_;
             netPackageRequest_ = (NetPackageRequest) netStatementRequest_;
             netConnectionRequest_ = (NetConnectionRequest) netPackageRequest_;
@@ -394,6 +402,10 @@ public class NetAgent extends Agent {
         return rawSocketInputStream_;
     }
 
+    public CcsidManager getCurrentCcsidManager() {
+        return currentCcsidManager_;
+    }
+    
     public java.io.OutputStream getOutputStream() {
         return rawSocketOutputStream_;
     }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java Fri Aug  6 02:37:12 2010
@@ -1257,17 +1257,17 @@ public class NetConnection extends org.a
             // the characters 'G' thro 'P'(in order to use the crrtkn as the LUWID when using
             // SNA in a hop site). For example, 0 is mapped to G, 1 is mapped H,etc.
             if (i == 0) {
-                crrtkn_[j] = netAgent_.sourceCcsidManager_.numToSnaRequiredCrrtknChar_[halfByte];
+                crrtkn_[j] = netAgent_.getCurrentCcsidManager().numToSnaRequiredCrrtknChar_[halfByte];
             } else {
-                crrtkn_[j] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
+                crrtkn_[j] = netAgent_.getCurrentCcsidManager().numToCharRepresentation_[halfByte];
             }
 
             halfByte = (num) & 0x0f;
-            crrtkn_[j + 1] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
+            crrtkn_[j + 1] = netAgent_.getCurrentCcsidManager().numToCharRepresentation_[halfByte];
         }
 
         // fill the '.' in between the IP address and the port number
-        crrtkn_[8] = netAgent_.sourceCcsidManager_.dot_;
+        crrtkn_[8] = netAgent_.getCurrentCcsidManager().dot_;
 
         // Port numbers have values which fit in 2 unsigned bytes.
         // Java returns port numbers in an int so the value is not negative.
@@ -1276,13 +1276,13 @@ public class NetConnection extends org.a
         num = netAgent_.socket_.getLocalPort();
 
         halfByte = (num >> 12) & 0x0f;
-        crrtkn_[9] = netAgent_.sourceCcsidManager_.numToSnaRequiredCrrtknChar_[halfByte];
+        crrtkn_[9] = netAgent_.getCurrentCcsidManager().numToSnaRequiredCrrtknChar_[halfByte];
         halfByte = (num >> 8) & 0x0f;
-        crrtkn_[10] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
+        crrtkn_[10] = netAgent_.getCurrentCcsidManager().numToCharRepresentation_[halfByte];
         halfByte = (num >> 4) & 0x0f;
-        crrtkn_[11] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
+        crrtkn_[11] = netAgent_.getCurrentCcsidManager().numToCharRepresentation_[halfByte];
         halfByte = (num) & 0x0f;
-        crrtkn_[12] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
+        crrtkn_[12] = netAgent_.getCurrentCcsidManager().numToCharRepresentation_[halfByte];
 
         // The final part of CRRTKN is a 6 byte binary number that makes the
         // crrtkn unique, which is usually the time stamp/process id.
@@ -1318,21 +1318,21 @@ public class NetConnection extends org.a
         }
 
         for (int i = 0; i < NetConfiguration.PRDDTA_ACCT_SUFFIX_LEN_BYTE; i++) {
-            prddta_[i] = netAgent_.sourceCcsidManager_.space_;
+            prddta_[i] = netAgent_.getCurrentCcsidManager().space_;
         }
 
-        prddtaLen = netAgent_.sourceCcsidManager_.convertFromUCS2(NetConfiguration.PRDID,
+        prddtaLen = netAgent_.getCurrentCcsidManager().convertFromJavaString(NetConfiguration.PRDID,
                 prddta_,
                 prddtaLen,
                 netAgent_);
 
-        prddtaLen = netAgent_.sourceCcsidManager_.convertFromUCS2(NetConfiguration.PRDDTA_PLATFORM_ID,
+        prddtaLen = netAgent_.getCurrentCcsidManager().convertFromJavaString(NetConfiguration.PRDDTA_PLATFORM_ID,
                 prddta_,
                 prddtaLen,
                 netAgent_);
 
         int extnamTruncateLength = Math.min(extnam_.length(), NetConfiguration.PRDDTA_APPL_ID_FIXED_LEN);
-        netAgent_.sourceCcsidManager_.convertFromUCS2(extnam_.substring(0, extnamTruncateLength),
+        netAgent_.getCurrentCcsidManager().convertFromJavaString(extnam_.substring(0, extnamTruncateLength),
                 prddta_,
                 prddtaLen,
                 netAgent_);
@@ -1340,7 +1340,7 @@ public class NetConnection extends org.a
 
         if (user_ != null) {
             int userTruncateLength = Math.min(user_.length(), NetConfiguration.PRDDTA_USER_ID_FIXED_LEN);
-            netAgent_.sourceCcsidManager_.convertFromUCS2(user_.substring(0, userTruncateLength),
+            netAgent_.getCurrentCcsidManager().convertFromJavaString(user_.substring(0, userTruncateLength),
                     prddta_,
                     prddtaLen,
                     netAgent_);
@@ -1373,21 +1373,21 @@ public class NetConnection extends org.a
     }
 
     private byte[] encryptedPasswordForUSRENCPWD(String password) throws SqlException {
-        return encryptionManager_.encryptData(netAgent_.sourceCcsidManager_.convertFromUCS2(password, netAgent_),
+        return encryptionManager_.encryptData(netAgent_.getCurrentCcsidManager().convertFromJavaString(password, netAgent_),
                 NetConfiguration.SECMEC_USRENCPWD,
-                netAgent_.sourceCcsidManager_.convertFromUCS2(user_, netAgent_),
+                netAgent_.getCurrentCcsidManager().convertFromJavaString(user_, netAgent_),
                 targetPublicKey_);
     }
 
     private byte[] encryptedUseridForEUSRIDPWD() throws SqlException {
-        return encryptionManager_.encryptData(netAgent_.sourceCcsidManager_.convertFromUCS2(user_, netAgent_),
+        return encryptionManager_.encryptData(netAgent_.getCurrentCcsidManager().convertFromJavaString(user_, netAgent_),
                 NetConfiguration.SECMEC_EUSRIDPWD,
                 targetPublicKey_,
                 targetPublicKey_);
     }
 
     private byte[] encryptedPasswordForEUSRIDPWD(String password) throws SqlException {
-        return encryptionManager_.encryptData(netAgent_.sourceCcsidManager_.convertFromUCS2(password, netAgent_),
+        return encryptionManager_.encryptData(netAgent_.getCurrentCcsidManager().convertFromJavaString(password, netAgent_),
                 NetConfiguration.SECMEC_EUSRIDPWD,
                 targetPublicKey_,
                 targetPublicKey_);

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=982852&r1=982851&r2=982852&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 Fri Aug  6 02:37:12 2010
@@ -485,7 +485,7 @@ public class NetConnectionRequest extend
         // see if we can optimize
         if (dontSendOnConversionError) {
             try {
-                ccsidManager_.convertFromUCS2(rdbnam, netAgent_);
+                ccsidManager_.convertFromJavaString(rdbnam, netAgent_);
             } catch (SqlException se)  {
                 netAgent_.exceptionConvertingRdbnam = se;
                 return;

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Reply.java Fri Aug  6 02:37:12 2010
@@ -73,7 +73,7 @@ public class Reply {
     Reply(NetAgent netAgent, int bufferSize) {
         buffer_ = new byte[bufferSize];
         agent_ = netAgent_ = netAgent;
-        ccsidManager_ = netAgent.targetCcsidManager_;
+        ccsidManager_ = netAgent.getCurrentCcsidManager();
         ddmCollectionLenStack_ = new int[Reply.MAX_MARKS_NESTING];
         initialize();
     }
@@ -668,7 +668,7 @@ public class Reply {
         ensureBLayerDataInBuffer(length);
         adjustLengths(length);
 
-        String result = ccsidManager_.convertToUCS2(buffer_, pos_, length);
+        String result = ccsidManager_.convertToJavaString(buffer_, pos_, length);
         pos_ += length;
         return result;
     }
@@ -695,7 +695,7 @@ public class Reply {
         int len = ddmScalarLen_;
         ensureBLayerDataInBuffer(len);
         adjustLengths(len);
-        String result = ccsidManager_.convertToUCS2(buffer_, pos_, len);
+        String result = ccsidManager_.convertToJavaString(buffer_, pos_, len);
         pos_ += len;
         return result;
     }
@@ -1253,7 +1253,7 @@ public class Reply {
     }
 
     final String readFastString(int length) throws DisconnectException {
-        String result = ccsidManager_.convertToUCS2(buffer_, pos_, length);
+        String result = ccsidManager_.convertToJavaString(buffer_, pos_, length);
         pos_ += length;
         return result;
     }

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=982852&r1=982851&r2=982852&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 Fri Aug  6 02:37:12 2010
@@ -1171,7 +1171,7 @@ public class Request {
         bytes_[offset_++] = (byte) ((codePoint >>> 8) & 0xff);
         bytes_[offset_++] = (byte) (codePoint & 0xff);
         
-        offset_ = ccsidManager_.convertFromUCS2(string, bytes_, offset_, netAgent_);
+        offset_ = ccsidManager_.convertFromJavaString(string, bytes_, offset_, netAgent_);
        
         int stringByteLength = offset_ - lengthOffset - 4;
         // reset the buffer and throw an SQLException if the length is too long
@@ -1209,7 +1209,7 @@ public class Request {
     final void writeScalarPaddedString(String string, int paddedLength) throws SqlException {
         int stringLength = string.length();
         ensureLength(offset_ + paddedLength);
-        offset_ = ccsidManager_.convertFromUCS2(string, bytes_, offset_, netAgent_);
+        offset_ = ccsidManager_.convertFromJavaString(string, bytes_, offset_, netAgent_);
         for (int i = 0; i < paddedLength - stringLength; i++) {
             bytes_[offset_++] = ccsidManager_.space_;
         }
@@ -1327,7 +1327,7 @@ public class Request {
                 mask.append(maskChar);
             }
             // try to write mask over password.
-            ccsidManager_.convertFromUCS2(mask.toString(), bytes_, passwordStart_, netAgent_);
+            ccsidManager_.convertFromJavaString(mask.toString(), bytes_, passwordStart_, netAgent_);
         } catch (SqlException sqle) {
             // failed to convert mask,
             // them simply replace with 0xFF.
@@ -1565,7 +1565,7 @@ public class Request {
     // data or fodca data right now it is coded for ddm char data only
     final void writeDDMString(String s) throws SqlException {
         ensureLength(offset_ + s.length());
-        offset_ = ccsidManager_.convertFromUCS2(s, bytes_, offset_, netAgent_);
+        offset_ = ccsidManager_.convertFromJavaString(s, bytes_, offset_, netAgent_);
     }
 
     private void buildLengthAndCodePointForLob(int codePoint,

Added: db/derby/code/trunk/java/client/org/apache/derby/client/net/Utf8CcsidManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Utf8CcsidManager.java?rev=982852&view=auto
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Utf8CcsidManager.java (added)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Utf8CcsidManager.java Fri Aug  6 02:37:12 2010
@@ -0,0 +1,134 @@
+/*
+
+   Derby - Class org.apache.derby.client.net.Utf8CcsidManager
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 java.io.UnsupportedEncodingException;
+
+import org.apache.derby.client.am.Agent;
+import org.apache.derby.client.am.ClientMessageId;
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.shared.common.reference.SQLState;
+
+public class Utf8CcsidManager extends CcsidManager {
+
+    public Utf8CcsidManager() {
+        super((byte) ' ', // 0x40 is the ebcdic space character
+                (byte) '.',
+                new byte[]{//02132002jev begin
+                    //     '0',       '1',       '2',       '3',      '4',
+                    (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4,
+                    //     '5',       '6',       '7',       '8',      '9',
+                    (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9,
+                    //     'A',       'B',       'C',       'D',      'E',
+                    (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5,
+                    //      'F'
+                    (byte) 0xc6},
+                new byte[]{
+                    //     'G',       'H',       'I',       'J',      'K',
+                    (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xd1, (byte) 0xd2,
+                    //     'L',       'M',       'N',       '0',      'P',
+                    (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7,
+                    //     'A',       'B',       'C',       'D',      'E',
+                    (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5,
+                    //      'F'
+                    (byte) 0xc6}                     //02132002jev end
+        );
+    }
+    
+    public byte[] convertFromJavaString(String sourceString, Agent agent)
+    throws SqlException {
+        byte[] bytes = new byte[getByteLength(sourceString)];
+        convertFromJavaString(sourceString, bytes, 0, agent);
+        return bytes;
+    }
+    
+    public String convertToJavaString(byte[] sourceBytes) {
+        return convertToJavaString(sourceBytes, 0, sourceBytes.length);
+    }
+
+    /**
+     * Offset and numToConvert are given in terms of bytes! Not characters!
+     */
+    public String convertToJavaString(byte[] sourceBytes, int offset, int numToConvert) {
+        try {
+            return new String(sourceBytes, offset, numToConvert, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            // We don't have an agent in this method
+            if (SanityManager.DEBUG) {
+                SanityManager.THROWASSERT("Could not convert byte[] to Java String using UTF-8 encoding with offset",e);
+            }
+        }
+        return null;
+    }
+
+//    //Will this be needed in client?
+//    int getByteLength(String str) {
+//        try {
+//            return str.getBytes("UTF-8").length;
+//        } catch (UnsupportedEncodingException e) {
+//            if (SanityManager.DEBUG) {
+//                SanityManager.THROWASSERT("Could not obtain byte length of Java String in Utf8CcsidManager",e);
+//            }
+//        }
+//        return -1;
+//    }
+
+    public int convertFromJavaString(String sourceString, byte[] buffer,
+            int offset, Agent agent) throws SqlException {
+        try {
+            byte[] strBytes = sourceString.getBytes("UTF-8"); 
+            
+            for(int i=0; i<strBytes.length; i++) {
+                buffer[offset++] = strBytes[i];
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new SqlException(agent.logWriter_, 
+                    new ClientMessageId(SQLState.CANT_CONVERT_UNICODE_TO_UTF8));
+        }
+        return offset;
+    }
+
+    public char convertToJavaChar(byte sourceByte) {
+        /* 1 byte = 0 to 255 which is the same in UTF-8 and ASCII */ 
+        return (char)sourceByte;
+    }
+
+    int maxBytesPerChar() {
+        return 4;
+    }
+
+    public int getByteLength(String s) {
+        try {
+            return s.getBytes("UTF-8").length;
+        } catch (UnsupportedEncodingException e) {
+            // We don't have an agent in this method
+            if (SanityManager.DEBUG) {
+                SanityManager.THROWASSERT("Could not obtain byte length of Java String",e);
+            }
+        }
+        return -1;
+    }
+    
+    
+
+}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Fri Aug  6 02:37:12 2010
@@ -642,6 +642,11 @@ Guide.
                 <text>Unrecognized Java SQL type {0}.</text>
                 <arg>datatypeName</arg>
             </msg>
+            
+            <msg>
+                <name>22005.S.7</name>
+                <text>Unicode string cannot convert to UTF-8 string</text>
+            </msg>
 
             <msg>
                 <name>22005</name>

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Aug  6 02:37:12 2010
@@ -697,6 +697,7 @@ public interface SQLState {
     String NET_UNRECOGNIZED_JDBC_TYPE                                  = "22005.S.4";
     String NET_INVALID_JDBC_TYPE_FOR_PARAM                             = "22005.S.5";
     String UNRECOGNIZED_JAVA_SQL_TYPE                                  = "22005.S.6";
+    String CANT_CONVERT_UNICODE_TO_UTF8                                = "22005.S.7";
 
 	String LANG_DATE_RANGE_EXCEPTION                                   = "22007.S.180";
 	String LANG_DATE_SYNTAX_EXCEPTION                                  = "22007.S.181";

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/Utf8CcsidManagerClientTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/Utf8CcsidManagerClientTest.java?rev=982852&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/Utf8CcsidManagerClientTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/Utf8CcsidManagerClientTest.java Fri Aug  6 02:37:12 2010
@@ -0,0 +1,120 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.derbynet.Utf8CcsidManagerClientTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.derbyTesting.functionTests.tests.derbynet;
+
+import java.util.Arrays;
+
+import junit.framework.Test;
+
+import org.apache.derby.client.net.Utf8CcsidManager;
+import org.apache.derbyTesting.junit.BaseTestCase;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+public class Utf8CcsidManagerClientTest extends BaseTestCase {
+    private Utf8CcsidManager ccsidManager;
+    
+    public Utf8CcsidManagerClientTest(String name) {
+        super(name);
+        
+        ccsidManager = new Utf8CcsidManager();
+    }
+
+    /**
+     * Use the Utf8CcsidManager to convert strings from UCS2/UTF-16 into UTF-8
+     */
+    public void testConvertFromJavaString() throws Exception {
+        // Get the UTF-16 representation of "Hello World" in Chinese
+        String ucs2String = new String(new String("\u4f60\u597d\u4e16\u754c").getBytes("UTF-16"),"UTF-16");
+        
+        // Get the same as above but in UTF-8
+        byte[] utf8Bytes = new String("\u4f60\u597d\u4e16\u754c").getBytes("UTF-8");
+
+        // Use the CcsidManager to convert the UTF-16 string to UTF-8 bytes
+        byte[] utf8Converted = ccsidManager.convertFromJavaString(ucs2String, null);
+        
+        // Compare the bytes
+        assertTrue("UTF-8 conversion isn't equal to bytes",
+                Arrays.equals(utf8Bytes, utf8Converted));
+        
+    }
+    
+    /**
+     * Use the Utf8CcsidManager to convert strings from UCS2/UTF-16 into UTF-8
+     * while offsetting the first character (3 bytes)
+     */
+    public void testConvertFromJavaStringWithOffset() throws Exception {
+        // String with 1 more chinese char (3 bytes) in the beginning
+        String ucs2String = new String(new String("\u4f60\u597d\u4e16\u754c").getBytes("UTF-16"),"UTF-16");
+        
+        // Create a new byte array with one additional chinese char (3 bytes) in the beginning
+        byte[] additionalBytes = new String("\u53f0\u4f60\u597d\u4e16\u754c").getBytes("UTF-8");
+        
+        // Create a buffer to accommodate additionalBytes.length bytes
+        byte[] buffer = new byte[additionalBytes.length];
+        
+        // Copy the first character manually
+        buffer[0] = additionalBytes[0];
+        buffer[1] = additionalBytes[1];
+        buffer[2] = additionalBytes[2];
+        
+        // Offset 3 bytes and convert the 4 chars in ucs2String
+        ccsidManager.convertFromJavaString(ucs2String, buffer, 3, null);
+            
+        assertTrue("UTF-8 conversion isn't equal to bytes (with buffer)",
+                Arrays.equals(additionalBytes, buffer));
+    }
+    
+    /**
+     * Use the Utf8CcsidManager to convert strings from UTF-8 into UCS2/UTF-16
+     */
+    public void testConvertToJavaString() throws Exception {
+        // Get the UTF-8 bytes for "Hello World" in Chinese
+        byte[] utf8Bytes = new String("\u4f60\u597d\u4e16\u754c").getBytes("UTF-8");
+        
+        // Get the UTF-16 string for "Hello World" in Chinese
+        String ucs2String = new String(new String("\u4f60\u597d\u4e16\u754c").getBytes("UTF-16"),"UTF-16");
+        
+        // Get the 2nd and 3rd Chinese characters in UTF-16
+        String offsetUcs2String = new String(new String("\u597d\u4e16").getBytes("UTF-16"),"UTF-16");
+        
+        // Convert our UTF-8 bytes to UTF-16 using the CcsidManager and compare
+        String convertedString = ccsidManager.convertToJavaString(utf8Bytes);
+        assertEquals(ucs2String, convertedString);
+        
+        // Convert just the two characters as offset above and compare
+        String convertedOffset = ccsidManager.convertToJavaString(utf8Bytes, 3, 6);
+        assertEquals(offsetUcs2String, convertedOffset);
+    }
+    
+    /**
+     * Use the Utf8CcsidManager to convert a byte to a character
+     */
+    public void testConvertToJavaChar() throws Exception {
+        byte b = 0x2a; // '*'
+        
+        assertEquals('*', ccsidManager.convertToJavaChar(b));
+    }
+    
+    public static Test suite() {
+        return TestConfiguration.clientServerSuite(Utf8CcsidManagerClientTest.class);
+    }
+}

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java?rev=982852&r1=982851&r2=982852&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/_Suite.java Fri Aug  6 02:37:12 2010
@@ -64,6 +64,7 @@ public class _Suite extends BaseTestCase
         suite.addTest(OutBufferedStreamTest.suite());
         suite.addTest(GetCurrentPropertiesTest.suite());
         suite.addTest(Utf8CcsidManagerTest.suite());
+        suite.addTest(Utf8CcsidManagerClientTest.suite());
 
         // Disabled due to "java.sql.SQLSyntaxErrorException: The class
         // 'org.apache.derbyTesting.functionTests.tests.derbynet.checkSecMgr'