You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/06/28 19:13:25 UTC

svn commit: r789127 - in /commons/sandbox/runtime/trunk/src: main/java/org/apache/commons/runtime/ main/java/org/apache/commons/runtime/util/ main/native/include/ main/native/os/darwin/ main/native/os/hpux/ main/native/os/linux/ main/native/os/solaris/...

Author: mturk
Date: Sun Jun 28 17:13:24 2009
New Revision: 789127

URL: http://svn.apache.org/viewvc?rev=789127&view=rev
Log:
Update native string support code

Added:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/MbString.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Native.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Platform.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java
    commons/sandbox/runtime/trunk/src/main/native/include/acr_platform.h
    commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h
    commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h
    commons/sandbox/runtime/trunk/src/main/native/os/darwin/platform.c
    commons/sandbox/runtime/trunk/src/main/native/os/hpux/platform.c
    commons/sandbox/runtime/trunk/src/main/native/os/linux/platform.c
    commons/sandbox/runtime/trunk/src/main/native/os/solaris/platform.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/platform.c
    commons/sandbox/runtime/trunk/src/main/native/shared/mbstr.c
    commons/sandbox/runtime/trunk/src/main/native/shared/string.c
    commons/sandbox/runtime/trunk/src/main/native/test/testcase.c
    commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/MbString.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/MbString.java?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/MbString.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/MbString.java Sun Jun 28 17:13:24 2009
@@ -15,6 +15,8 @@
  */
 package org.apache.commons.runtime;
 
+import java.io.UnsupportedEncodingException;
+
 /**
  * Multibyte String class.
  * <p>
@@ -22,18 +24,15 @@
  * As a side effect all strings are {@code zero} terminated, allowing easy
  * exchange between native methods that require the {@code C} strings.
  * </p>
- *
+ * <p>
+ * Use this class in performance critical code where extra character
+ * conversion and zero string termination is frequently used.
+ * </p>
  * @see OS
  * @since Runtime 1.0
  */
-public class MbString
+public final class MbString
 {
-    /**
-     * Default encoding used to convert to strings. It should be {@code UTF-8},
-     * as most standards seem to converge, but the servlet API requires
-     * {@code 8859_1}, and this class is used mostly for web applications.
-     */
-    public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
 
     /**
      * Default string length.
@@ -42,14 +41,18 @@
      * </p>
      * <pre>
      * MbString s = new MbString();
+     * ...
+     * s.strcat("String");
      * </pre>
      */
-    public static final int    DEFAULT_STRING_LENGTH      = 1024;
+    public static final int    DEFAULT_STRING_LENGTH = 1024;
 
     /*
      * Local Multibyte string container
      */
     private byte[] mbstr;
+    private int    mblen = 0;
+    private int    mbsiz = 0;
 
     public MbString()
     {
@@ -65,6 +68,7 @@
     public MbString(int size)
     {
         mbstr = new byte[size];
+        mbsiz = size;
     }
 
     /**
@@ -76,6 +80,7 @@
     public MbString(byte[] str)
     {
         mbstr = str;
+        mbsiz = str.length;
     }
 
     /**
@@ -87,10 +92,11 @@
     public MbString(MbString src)
         throws NullPointerException
     {
-        int l = src.length();
-        mbstr = new byte[l + 1];
+        mblen = src.length();
+        mbsiz = mblen + 1;
+        mbstr = new byte[mbsiz];
         try {
-            System.arraycopy(src.mbstr, 0, mbstr, 0, l + 1);
+            System.arraycopy(src.mbstr, 0, mbstr, 0, mbsiz);
         } catch (Exception e) {
             // Make compiler happy
         }
@@ -107,9 +113,10 @@
         throws ArrayStoreException, IndexOutOfBoundsException,
                NullPointerException
     {
-        int l = src.length();
-        mbstr = new byte[l + 1];
-        System.arraycopy(src.mbstr, srcPos, mbstr, 0, l + 1);
+        mblen = src.length();
+        mbsiz = mblen + 1;
+        mbstr = new byte[mbsiz];
+        System.arraycopy(src.mbstr, srcPos, mbstr, 0, mbsiz);
     }
 
     private static native byte[] init0(Pointer ptr)
@@ -124,6 +131,8 @@
         throws NullPointerException
     {
         mbstr = init0(src);
+        mbsiz = mbstr.length;
+        mblen = mbsiz - 1;
     }
 
     private static native byte[] init2(Pointer ptr, int n)
@@ -138,6 +147,8 @@
         throws NullPointerException
     {
         mbstr = init2(src, n);
+        mbsiz = mbstr.length;
+        mblen = mbsiz - 1;
     }
 
     private static native byte[] init1(Pointer ptr, long off)
@@ -153,6 +164,8 @@
         throws NullPointerException
     {
         mbstr = init1(src, srcPos);
+        mbsiz = mbstr.length;
+        mblen = mbsiz - 1;
     }
 
     private static native byte[] init3(Pointer ptr, long off, int n)
@@ -168,6 +181,103 @@
         throws NullPointerException
     {
         mbstr = init3(src, srcPos, n);
+        mbsiz = mbstr.length;
+        mblen = mbsiz - 1;
+    }
+
+    /**
+     * Create new {@code MbString} instance from the String
+     * pointed by {@code src}.
+     * <p>
+     * String is converted {@code without} encoding
+     * with all characters larger then {@code 255} replaced with
+     * {@code ?} character.
+     * <p>
+     * @param src String to use.
+     */
+    public MbString(String src)
+        throws NullPointerException
+    {
+        if (src == null)
+            throw new NullPointerException();
+        mblen = src.length();
+        mbsiz = mblen + 1;
+        mbstr = new byte[mbsiz];
+        for (int i = 0; i < mblen; i++) {
+            char chr = src.charAt(i);
+            if (chr > 255)
+                mbstr[i] = (byte)'?';
+            else if (chr == 0) {
+                mblen = i;
+                break;
+            }
+            else
+                mbstr[i] = (byte)chr;
+        }
+    }
+
+    /**
+     * Returns a {@code String} representation of the MbString using the
+     * platform's default charset.
+     *
+     * @return a String.
+     */
+    @Override
+    public String toString()
+    {
+        int length = length();
+        if (length == 0)
+            return "";
+        return new String(mbstr, 0, length);
+    }
+
+    /**
+     * Calculate {@code this} string hash value.
+     * <p>
+     * This is the popular `times 33' hash algorithm which is used by
+     * perl and also appears in Berkeley DB. This is one of the best
+     * known hash functions for strings because it is both computed
+     * very fast and distributes very well.
+     * </p>
+     * @return {@code times 33} has value of the string.
+     */
+    @Override
+    public int hashCode()
+    {
+        int h = 0;
+        int i = 0;
+        while (i < mbstr.length && mbstr[i] != 0) {
+            h = h * 33 + (int)(mbstr[i++] & 0xFF);
+        }
+        return h;
+    }
+
+    public String getString()
+    {
+        int length = length();
+        if (length > 0) {
+            char [] ca = new char[length];
+            for (int i = 0; i < length; i++)
+                ca[i] = (char)(mbstr[i] & 0xFF);
+            return new String(ca);
+        }
+        else
+            return "";
+    }
+
+    public String getString(String charset)
+    {
+        int length = length();
+        if (length == 0)
+            return "";
+        if (charset == null || charset.length() == 0)
+            return new String(mbstr, 0, length);
+        try {
+            return new String(mbstr, 0, length, charset);
+        } catch (UnsupportedEncodingException e) {
+            // Fallback to platform's default encoding.
+            return new String(mbstr, 0, length);
+        }
     }
 
     /**
@@ -175,24 +285,108 @@
      *
      * @return byte array.
      */
-    public byte[] getBytes()
+    public byte[] getStorage()
     {
         return mbstr;
     }
 
     /**
+     * Converts this string to a new character array.
+     * <p>
+     * Encoding used is {@code ISO-8859-1}.
+     * </p>
+     * @return  a newly allocated byte array whose length is the length
+     *          of this string and whose contents are initialized to contain
+     *          the byte sequence represented by this string.
+     */
+    public byte[] getBytes()
+    {
+        return strdup(this);
+    }
+
+    /**
+     * Converts this string to a new character array.
+     * <p>
+     * Encoding used is {@code ISO-8859-1}.
+     * </p>
+     * @return  a newly allocated character array whose length is the length
+     *          of this string and whose contents are initialized to contain
+     *          the character sequence represented by this string.
+     */
+    public char[] getChars()
+    {
+        int length = length();
+        if (length > 0) {
+            char [] ca = new char[length];
+            for (int i = 0; i < length; i++)
+                ca[i] = (char)(mbstr[i] & 0xFF);
+            return ca;
+        }
+        else
+            return null;
+    }
+
+    /**
+     * Converts this string to a new character array.
+     * <p>
+     * Encoding used is {@code ISO-8859-1}.
+     * </p>
+     * @return  a newly allocated character array whose length is the length
+     *          of this string and whose contents are initialized to contain
+     *          the character sequence represented by this string.
+     */
+    public char[] getChars(String charset)
+    {
+        int length = length();
+        if (length == 0)
+            return null;
+        if (charset == null || charset.length() == 0)
+            return (new String(mbstr, 0, length)).toCharArray();
+        try {
+            return (new String(mbstr, 0, length, charset)).toCharArray();
+        } catch (UnsupportedEncodingException e) {
+            // Fallback to platform's default encoding.
+            return (new String(mbstr, 0, length)).toCharArray();
+        }
+    }
+
+    /**
      * Return the string length.
      *
      * @return string length in bytes.
      */
     public int length()
     {
-        int i = 0;
-        while (i < mbstr.length && mbstr[i] != 0)
-            i++;
-        return i;
+        if (mblen == 0) {
+            while (mblen < mbsiz && mbstr[mblen] != 0)
+                mblen++;
+        }
+        return mblen;
+    }
+
+    public int capacity()
+    {
+        return mbsiz - 1;
     }
 
+    public void ensureCapacity(int size)
+    {
+        if (size > capacity()) {
+            byte[] buff = new byte[size + 1];
+            System.arraycopy(mbstr, 0, buff, 0, mbsiz);
+            mbstr = buff;
+            mbsiz = size + 1;
+        }
+    }
+
+    public static final byte[] strdup(MbString src)
+        throws NullPointerException
+    {
+    	byte[] copy = new byte[src.length()];
+        System.arraycopy(src.mbstr, 0, copy, 0, src.mblen);
+
+        return copy;
+    }
 
     public static final byte[] strdup(Pointer src)
         throws NullPointerException
@@ -206,6 +400,16 @@
         return init1(src, srcPos);
     }
 
+    public static final byte[] strndup(MbString src, int len)
+        throws NullPointerException
+    {
+    	int	length  = Math.min(src.length(), len);
+    	byte[] copy = new byte[length];
+        System.arraycopy(src.mbstr, 0, copy, 0, length);
+
+        return copy;
+    }
+
     public static final byte[] strndup(Pointer src, int n)
         throws NullPointerException
     {

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Native.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Native.java?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Native.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Native.java Sun Jun 28 17:13:24 2009
@@ -52,13 +52,17 @@
         throws Throwable
     {
         if (!initialized) {
+            try {
+                initialized = init0();
+            } catch (Throwable t) {
+                // Ignore
+            }
             if (!Platform.supported()) {
                 throw new UnsupportedOperatingSystemException(
                     "Apache Commons Runtime does not support this " +
                     "operating system"
                 );
             }
-            initialized = init0();
         }
         return initialized;
     }

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Platform.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Platform.java?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Platform.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Platform.java Sun Jun 28 17:13:24 2009
@@ -15,6 +15,7 @@
  */
 
 package org.apache.commons.runtime;
+import java.nio.charset.Charset;
 
 /**
  * Running Platform version info.
@@ -41,11 +42,33 @@
      * Get Platform integer property value.
      */
     private static native void init0(int[] p);
+    private static final int default_charset()
+    {
+        int cs;
+        try {
+            String cp = Charset.defaultCharset().name();
+            if (cp == null)
+                cs = -1;
+            else if (cp.equals("ISO-8859-1"))
+                cs = 1;
+            else if (cp.equals("US-ASCII"))
+                cs = 1;
+            else if (cp.equals("UTF-8"))
+                cs = 2;
+            else
+                cs = 0;
+        } catch (Exception e) {
+            // Cannot determine
+            cs = -1;
+        }
+        return cs;
+    }
 
     static {
         int [] i = new int[32];
 
         i[0] = Properties.OS_OPEN_MAX;
+        i[1] = default_charset();
         init0(i);
 
         SIZEOF_INT                      =   i[0];

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java?rev=789127&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java Sun Jun 28 17:13:24 2009
@@ -0,0 +1,159 @@
+/* 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.commons.runtime.util;
+
+import java.io.PrintStream;
+import java.util.Random;
+
+/**
+ * Character Classification routines.
+ *
+ * @author Mladen Turk
+ */
+public final class Ascii
+{
+
+    private static final char _XL_U   = 0x01;
+    private static final char _XL_L   = 0x02;
+    private static final char _XL_N   = 0x04;
+    private static final char _XL_S   = 0x08;
+    private static final char _XL_P   = 0x10;
+    private static final char _XL_C   = 0x20;
+    private static final char _XL_X   = 0x40;
+    private static final char _XL_B   = 0x80;
+
+    private static final char[] ccs_ctype = {
+        _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,
+        _XL_C,  _XL_C|_XL_S|_XL_B, _XL_C|_XL_S, _XL_C|_XL_S, _XL_C|_XL_S,
+        _XL_C|_XL_S,    _XL_C,  _XL_C,
+        _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,
+        _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,  _XL_C,
+        _XL_S|_XL_B, _XL_P,  _XL_P, _XL_P,   _XL_P,  _XL_P,  _XL_P,  _XL_P,
+        _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,
+        _XL_N,  _XL_N,  _XL_N,  _XL_N,  _XL_N,  _XL_N,  _XL_N,  _XL_N,
+        _XL_N,  _XL_N,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,
+        _XL_P,  _XL_U|_XL_X,    _XL_U|_XL_X,    _XL_U|_XL_X,    _XL_U|_XL_X,
+        _XL_U|_XL_X,    _XL_U|_XL_X,    _XL_U,
+        _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,
+        _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,  _XL_U,
+        _XL_U,  _XL_U,  _XL_U,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_P,
+        _XL_P,  _XL_L|_XL_X,    _XL_L|_XL_X,    _XL_L|_XL_X,    _XL_L|_XL_X,
+        _XL_L|_XL_X,    _XL_L|_XL_X,    _XL_L,
+        _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,
+        _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,  _XL_L,
+        _XL_L,  _XL_L,  _XL_L,  _XL_P,  _XL_P,  _XL_P,  _XL_P,  _XL_C
+    };
+
+    public static boolean isascii(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return true;
+        else
+            return false;
+    }
+
+    public static boolean isalnum(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & (_XL_U|_XL_L|_XL_N)) != 0;
+        else
+            return false;
+    }
+
+    public static boolean isalpha(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & (_XL_U|_XL_L)) != 0;
+        else
+            return false;
+    }
+
+    public static boolean isdigit(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_N) != 0;
+        else
+            return false;
+    }
+
+    public static boolean isspace(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_S) != 0;
+        else
+            return false;
+    }
+
+    public static boolean isblank(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & (_XL_S|_XL_B)) == (_XL_S|_XL_B);
+        else
+            return false;
+    }
+
+    public static boolean iscntrl(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_C) != 0;
+        else
+            return false;
+    }
+
+    public static boolean islower(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_L) != 0;
+        else
+            return false;
+    }
+
+    public static boolean isupper(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_U) != 0;
+        else
+            return false;
+    }
+
+    public static boolean ispunct(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & _XL_P) != 0;
+        else
+            return false;
+    }
+
+
+    /**
+     * Checks for a hexadecimal digits, i.e. one of
+     * <pre>
+     * 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F.
+     * </pre>
+     *
+     * return {@code true} if the {@code c} is hexadecimal digit.
+     */
+    public static boolean isxdigit(int c)
+    {
+        if (c >= 0 && c < _XL_B)
+            return (ccs_ctype[c] & (_XL_X|_XL_N)) != 0;
+        else
+            return false;
+    }
+
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Utils.java Sun Jun 28 17:13:24 2009
@@ -36,6 +36,10 @@
     private static long     timer                  = System.currentTimeMillis();
     private static Random   rnd                    = new Random(timer);
 
+    private static final char[] hc = { 
+                '0', '1', '2', '3', '4', '5', '6', '7',
+                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
     /**
      * Returns the unique 64 bit id.
      * Values lower then 1024 are reseved for system ID's.
@@ -80,6 +84,22 @@
         return ("0000000000000000" + h).substring(h.length());
     }
 
+    public static String hex(byte[] src, int srcPos, int len)
+    {
+        int    p = 0;
+        char[] c = new char[len * 2];
+        for (int i = srcPos; i < len; i++) {
+            c[p++] = hc[(src[i] >> 4) & 0x0F];
+            c[p++] = hc[(src[i] >> 0) & 0x0F];
+        }
+        return new String(c);
+    }
+
+    public static String hex(byte[] src)
+    {
+        return hex(src, 0, src.length);
+    }
+
     public static String dumpBuffer(byte[] data, int offset, int len)
     {
         int i;
@@ -88,7 +108,7 @@
         if (offset >= data.length)
             return null;
         StringBuffer sb = new StringBuffer();
-        sb.append(hex((short)offset));
+        sb.append(hex((short)(offset & 0x7FFF)));
         sb.append(": ");
         for (i = 0; i < 16; i++) {
             if (i < data.length) {
@@ -105,8 +125,8 @@
         sb.append(" | ");
         for (i = offset; i < offset + 16; i++) {
             if (i < data.length) {
-                if (!Character.isISOControl((char)data[i]))
-                    sb.append(new Character((char)data[i]));
+                if (!Character.isISOControl((char)(data[i] & 0xFF)))
+                    sb.append(new Character((char)(data[i] & 0xFF)));
                 else
                     sb.append(".");
             }
@@ -114,11 +134,21 @@
         return sb.toString();
     }
 
+    public static String dumpBuffer(byte[] data)
+    {
+        return dumpBuffer(data, 0, data.length);
+    }
+
     public static void dumpBuffer(byte[] data, int offset, int len,
                                   PrintStream out)
     {
         out.println(dumpBuffer(data, offset, len));
     }
 
+    public static void dumpBuffer(byte[] data, PrintStream out)
+    {
+        out.println(dumpBuffer(data));
+    }
+
 }
 

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_platform.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_platform.h?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_platform.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_platform.h Sun Jun 28 17:13:24 2009
@@ -31,9 +31,11 @@
  * ACR platform private structures
  *
  */
+int acr_get_native_codepage(const char *);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _ACR_PLATFORM_H */
+

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h Sun Jun 28 17:13:24 2009
@@ -72,6 +72,9 @@
 #define ACR_MBUFF_SIZ           1024
 #define ACR_MBUFF_LEN           (ACR_MBUFF_SIZ - 1)
 
+#define ACR_PBUFF_SIZ           4096
+#define ACR_PBUFF_LEN           (ACR_PBUFF_SIZ - 1)
+
 #define ACR_HBUFF_SIZ           8192
 #define ACR_HBUFF_LEN           (ACR_HBUFF_SIZ - 1)
 
@@ -84,6 +87,7 @@
 #define ACR_TB                  (ACR_GB * ACR_KB)
 
 #define CSTR_TO_JSTRING(V)      ACR_NewJavaStringA(_E, (const char *)(V))
+#define CSTR_TO_MSTRING(V)      ACR_NewMbStringA(_E, (const char *)(V))
 #define WSTR_TO_JSTRING(V)      ACR_NewJavaStringW(_E, (const wchar_t *)(V))
 #if defined(_MSC_VER)
 #define PSTR_TO_JSTRING(V)      ACR_NewJavaStringW(_E, (const wchar_t *)(V))
@@ -107,34 +111,48 @@
         (*_E)->ReleaseStringUTFChars(_E, V, _c##V);                 \
     } } else ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, 0)
 
+#define WITH_BSTR(V)                                                       \
+    if ((V)) {                                                             \
+    const char *_c##V;                                                     \
+    _c##V = (const char *)((*_E)->GetByteArrayElements(_E, V, NULL));      \
+    if (_c##V) {                                                           \
+
+#define END_WITH_BSTR(V)                                                   \
+        (*_E)->ReleaseByteArrayElements(_E, V, (jbyte *)_c##V, JNI_ABORT); \
+    } } else ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, 0)
+
 #define WITH_WSTR(V)                                                \
     if ((V)) {                                                      \
-    wchar_t *_w##V = ACR_GetJavaStringW(_E, (V));                   \
+    wchar_t  _b##V[ACR_MBUFF_SIZ];                                  \
+    wchar_t *_w##V = ACR_GetJavaStringW(_E, (V), _b##V);            \
     if (!_w##V) goto _cw##V;
 
 #define WITH_ZWSTR(V)                                               \
     if (_E) {                                                       \
-    wchar_t *_w##V = ACR_GetJavaStringW(_E, (V));                   \
+    wchar_t  _b##V[ACR_MBUFF_SIZ];                                  \
+    wchar_t *_w##V = ACR_GetJavaStringW(_E, (V), _b##V);            \
     if (!_w##V && (V)) goto _cw##V;
 
-#define END_WITH_WSTR(V)            \
-        _cw##V :                    \
-        if (_w##V) free (_w##V);    \
+#define END_WITH_WSTR(V)                           \
+        _cw##V :                                   \
+        if (_w##V && _w##V != _b##V) free (_w##V); \
     } else ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, 0)
 
 #define WITH_CSTR(V)                                                \
     if ((V)) {                                                      \
-    char *_c##V = ACR_GetJavaStringA(_E, (V));                      \
+    char  _b##V[ACR_PBUFF_SIZ];                                     \
+    char *_c##V = ACR_GetJavaStringA(_E, (V), _b##V);               \
     if (!_c##V) goto _ca##V;
 
 #define WITH_ZCSTR(V)                                               \
     if (_E) {                                                       \
-    char *_c##V = ACR_GetJavaStringA(_E, (V));                      \
+    char  _b##V[ACR_PBUFF_SIZ];                                     \
+    char *_c##V = ACR_GetJavaStringA(_E, (V), _b##V);               \
     if (!_c##V && (V)) goto _ca##V;
 
-#define END_WITH_CSTR(V)            \
-        _ca##V :                    \
-        if (_c##V) free (_c##V);    \
+#define END_WITH_CSTR(V)                           \
+        _ca##V :                                   \
+        if (_c##V && _c##V != _b##V) free (_c##V); \
     } else ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, 0)
 
 #define RETURN_UCSTR(V)     \
@@ -143,6 +161,7 @@
 
 #define RETURN_JWSTR(V)  return ACR_NewJavaStringW(_E, (V))
 #define RETURN_JCSTR(V)  return ACR_NewJavaStringA(_E, (V))
+#define RETURN_MBSTR(V)  return ACR_NewMbStringA(_E, (V))
 
 #define ACR_OS_WINDOWS   0x1000
 #define ACR_OS_WIN64     0x1001
@@ -153,6 +172,9 @@
 #define ACR_OS_DARWIN    0x2004
 #define ACR_OS_HPUX      0x2008
 
+#define ACR_CP_DEFAULT        0
+#define ACR_CP_ISO8859_1      1
+#define ACR_CP_UTF_8          2
 
 #define ACR_LOG_EMERG         1
 #define ACR_LOG_ERROR         2
@@ -484,3 +506,4 @@
 #endif
 
 #endif /* _ACR_PRIVATE_H */
+

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_string.h Sun Jun 28 17:13:24 2009
@@ -78,39 +78,47 @@
  * @param s String to convert.
  * @remark When done use ACR_Free to free the allocated memory.
  */
-ACR_DECLARE(wchar_t *) ACR_GetJavaStringW(JNIEnv *env, jstring s);
+ACR_DECLARE(wchar_t *) ACR_GetJavaStringW(JNIEnv *env, jstring s, wchar_t *b);
 
-/** Convert java string to UTF-8 string
+/** Convert java string to platform char string.
  * @param env Current JNI environment.
  * @param s String to convert.
  * @remark When done use ACR_Free to free the allocated memory.
  */
-ACR_DECLARE(char *) ACR_GetJavaStringU(JNIEnv *env, jstring s);
+ACR_DECLARE(char *)ACR_GetJavaStringA(JNIEnv *env, jstring s, char *b);
 
-/** Convert java string to platform char string.
+/** Convert wchar_t to java string
  * @param env Current JNI environment.
  * @param s String to convert.
- * @remark When done use ACR_Free to free the allocated memory.
  */
-ACR_DECLARE(char *)ACR_GetJavaStringA(JNIEnv *_E, jstring s);
+ACR_DECLARE(jstring) ACR_NewJavaStringW(JNIEnv *env, const wchar_t *s);
 
-/** Convert wchar_t to java string
+/** Convert platform string to java string
  * @param env Current JNI environment.
  * @param s String to convert.
  */
-ACR_DECLARE(jstring) ACR_NewJavaStringW(JNIEnv *_E, const wchar_t *s);
+ACR_DECLARE(jstring) ACR_NewJavaStringA(JNIEnv *env, const char *s);
 
-/** Convert UTF-8 encoded string to java string
+/** Convert platform string to MbString object
  * @param env Current JNI environment.
  * @param s String to convert.
  */
-ACR_DECLARE(jstring) ACR_NewJavaStringU(JNIEnv *_E, const char *s);
+ACR_DECLARE(jobject) ACR_NewMbString(JNIEnv *env, const char *s);
 
-/** Convert platform string to java string
+/** Get platform string from MbString object
  * @param env Current JNI environment.
  * @param s String to convert.
+ * @param b Where to store the string from the byte array
+ * @note Returned byteArray must be freed using ACR_ReleaseMbString.
  */
-ACR_DECLARE(jstring) ACR_NewJavaStringA(JNIEnv *_E, const char *s);
+ACR_DECLARE(jbyteArray) ACR_GetMbString(JNIEnv *env, jobject s, char **b);
+
+/** Release MbString byte array.
+ * @param env Current JNI environment.
+ * @param arr Java byte array to release.
+ * @param s String from the arr to release.
+ */
+ACR_DECLARE(void) ACR_ReleaseMbString(JNIEnv *env, jbyteArray arr, char *s);
 
 /** Match ascii string to the pattern.
  * Based loosely on sections of wildmat.c by Rich Salz
@@ -163,3 +171,4 @@
 #endif
 
 #endif /* _ACR_STRING_H */
+

Modified: commons/sandbox/runtime/trunk/src/main/native/os/darwin/platform.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/darwin/platform.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/darwin/platform.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/darwin/platform.c Sun Jun 28 17:13:24 2009
@@ -19,9 +19,12 @@
 #include "acr_arch.h"
 #include "acr_string.h"
 #include "acr_platform.h"
+#include <locale.h>
+#include <langinfo.h>
 
 static const char unknown[] = "unknown";
 acr_size_t acr_page_size;
+int        acr_native_codepage = ACR_CP_DEFAULT;
 
 typedef struct struct_align_t {
     char        c;
@@ -36,6 +39,9 @@
 
     UNREFERENCED_O;
 
+    (*_E)->GetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+    acr_native_codepage = ia[1];
+
     ia[0]  =   sizeof(int);
     ia[1]  =   sizeof(long);
     ia[2]  =   sizeof(size_t);
@@ -53,6 +59,12 @@
     ia[9]  =   (jint)sizeof(struct_align_t);
 
     (*_E)->SetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+
+    if (acr_native_codepage == -1) {
+        const char *sls = setlocale(LC_ALL, "");
+        acr_native_codepage = acr_get_native_codepage(nl_langinfo(CODESET));
+        setlocale(LC_ALL, sls);
+    }
 }
 
 ACR_JNI_EXPORT_DECLARE(jboolean, Platform, supported)(ACR_JNISTDARGS)
@@ -63,3 +75,4 @@
      */
     return JNI_TRUE;
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/os/hpux/platform.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/hpux/platform.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/hpux/platform.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/hpux/platform.c Sun Jun 28 17:13:24 2009
@@ -19,9 +19,12 @@
 #include "acr_arch.h"
 #include "acr_string.h"
 #include "acr_platform.h"
+#include <locale.h>
+#include <langinfo.h>
 
 static const char unknown[] = "unknown";
 acr_size_t acr_page_size;
+int        acr_native_codepage = ACR_CP_DEFAULT;
 
 typedef struct struct_align_t {
     char        c;
@@ -36,6 +39,9 @@
 
     UNREFERENCED_O;
 
+    (*_E)->GetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+    acr_native_codepage = ia[1];
+
     ia[0]  =   sizeof(int);
     ia[1]  =   sizeof(long);
     ia[2]  =   sizeof(size_t);
@@ -53,6 +59,12 @@
     ia[9]  =   (jint)sizeof(struct_align_t);
 
     (*_E)->SetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+
+    if (acr_native_codepage == -1) {
+        const char *sls = setlocale(LC_ALL, "");
+        acr_native_codepage = acr_get_native_codepage(nl_langinfo(CODESET));
+        setlocale(LC_ALL, sls);
+    }
 }
 
 ACR_JNI_EXPORT_DECLARE(jboolean, Platform, supported)(ACR_JNISTDARGS)
@@ -63,3 +75,4 @@
      */
     return JNI_TRUE;
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/os/linux/platform.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/linux/platform.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/linux/platform.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/linux/platform.c Sun Jun 28 17:13:24 2009
@@ -19,9 +19,12 @@
 #include "acr_arch.h"
 #include "acr_string.h"
 #include "acr_platform.h"
+#include <locale.h>
+#include <langinfo.h>
 
 static const char unknown[] = "unknown";
 acr_size_t acr_page_size;
+int        acr_native_codepage = ACR_CP_DEFAULT;
 
 typedef struct struct_align_t {
     char        c;
@@ -36,6 +39,9 @@
 
     UNREFERENCED_O;
 
+    (*_E)->GetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+    acr_native_codepage = ia[1];
+
     ia[0]  =   sizeof(int);
     ia[1]  =   sizeof(long);
     ia[2]  =   sizeof(size_t);
@@ -51,8 +57,13 @@
     acr_page_size = (acr_size_t)getpagesize();
     ia[8]  =   (jint)acr_page_size;
     ia[9]  =   (jint)sizeof(struct_align_t);
-
     (*_E)->SetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+
+    if (acr_native_codepage == -1) {
+        const char *sls = setlocale(LC_ALL, "");
+        acr_native_codepage = acr_get_native_codepage(nl_langinfo(CODESET));
+        setlocale(LC_ALL, sls);
+    }
 }
 
 ACR_JNI_EXPORT_DECLARE(jboolean, Platform, supported)(ACR_JNISTDARGS)
@@ -63,3 +74,4 @@
      */
     return JNI_TRUE;
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/os/solaris/platform.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/solaris/platform.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/solaris/platform.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/solaris/platform.c Sun Jun 28 17:13:24 2009
@@ -19,9 +19,12 @@
 #include "acr_arch.h"
 #include "acr_string.h"
 #include "acr_platform.h"
+#include <locale.h>
+#include <langinfo.h>
 
 static const char unknown[] = "unknown";
 acr_size_t acr_page_size;
+int        acr_native_codepage = ACR_CP_DEFAULT;
 
 typedef struct struct_align_t {
     char        c;
@@ -36,6 +39,9 @@
 
     UNREFERENCED_O;
 
+    (*_E)->GetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+    acr_native_codepage = ia[1];
+
     ia[0]  =   sizeof(int);
     ia[1]  =   sizeof(long);
     ia[2]  =   sizeof(size_t);
@@ -53,6 +59,12 @@
     ia[9]  =   (jint)sizeof(struct_align_t);
 
     (*_E)->SetIntArrayRegion(_E, p, 0, 16, &ia[0]);
+
+    if (acr_native_codepage == -1) {
+        const char *sls = setlocale(LC_ALL, "");
+        acr_native_codepage = acr_get_native_codepage(nl_langinfo(CODESET));
+        setlocale(LC_ALL, sls);
+    }
 }
 
 ACR_JNI_EXPORT_DECLARE(jboolean, Platform, supported)(ACR_JNISTDARGS)
@@ -63,3 +75,4 @@
      */
     return JNI_TRUE;
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/platform.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/platform.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/platform.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/platform.c Sun Jun 28 17:13:24 2009
@@ -27,6 +27,7 @@
 extern int  acr_ioh_init(int);
 extern LPSYSTEM_INFO acr_osinf;
 acr_size_t  acr_page_size;
+int         acr_native_codepage = ACR_CP_DEFAULT;
 
 typedef struct struct_align_t {
     char        c;
@@ -50,6 +51,8 @@
         ACR_ThrowException(_E, THROW_NMARK, ACR_EX_OSERR, e);
         return;
     }
+	acr_native_codepage = ia[1];
+
     ia[0]  =   sizeof(int);
     ia[1]  =   sizeof(long);
     ia[2]  =   sizeof(size_t);
@@ -88,3 +91,4 @@
 
     return JNI_TRUE;
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/mbstr.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/mbstr.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/mbstr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/mbstr.c Sun Jun 28 17:13:24 2009
@@ -36,10 +36,10 @@
     "([B)V"
 };
 
-J_DECLARE_M_ID(0001) = {
+J_DECLARE_F_ID(0000) = {
     NULL,
-    "getBytes",
-    "()[B"
+    "mbstr",
+    "[B"
 };
 
 ACR_CLASS_LDEF(MbString)
@@ -49,7 +49,7 @@
     if ((rv = ACR_LoadClass(_E, &_clazzn, 0)) != ACR_SUCCESS)
         return rv;
     J_LOAD_METHOD(0000);
-    J_LOAD_METHOD(0001);
+    J_LOAD_IFIELD(0000);
 
     return ACR_SUCCESS;
 }
@@ -59,7 +59,7 @@
     ACR_UnloadClass(_E, &_clazzn);
 }
 
-ACR_DECLARE(jobject) ACR_MbStringObjectCreate(JNIEnv *_E, const char *str)
+ACR_DECLARE(jobject) ACR_NewMbString(JNIEnv *_E, const char *str)
 {
     if (_clazzn.i && J4MID(0000)) {
         jbyteArray ba;
@@ -80,6 +80,34 @@
     }
 }
 
+ACR_DECLARE(jbyteArray) ACR_GetMbString(ACR_JNISTDARGS, char **str)
+{
+    if (_clazzn.i && J4MID(0000)) {
+        jbyteArray ba = GET_IFIELD_O(0000, _O);
+        if (ba) {
+            *str = (char *)(*_E)->GetByteArrayElements(_E, ba, NULL);
+            return ba;
+        }
+        else {
+            *str = NULL;
+            return NULL;
+        }
+    }
+    else {
+        ACR_SET_OS_ERROR(ACR_ECLASSNOTFOUND);
+        *str = NULL;
+        return NULL;
+    }
+}
+
+ACR_DECLARE(void) ACR_ReleaseMbString(JNIEnv *_E, jbyteArray arr, char *str)
+{
+    if (arr) {
+       (*_E)->ReleaseByteArrayElements(_E, (jbyteArray)arr,
+                                       (jbyte *)str, JNI_ABORT);
+    }
+}
+
 ACR_JNI_EXPORT_DECLARE(jbyteArray, MbString, init0)(ACR_JNISTDARGS, jobject ptr)
 {
     jbyteArray ba;
@@ -92,7 +120,7 @@
     }
     cs = strlen(p);
     ba = (*_E)->NewByteArray(_E, cs + 1);
-    if (ba) {
+    if (ba && cs) {
         (*_E)->SetByteArrayRegion(_E, ba, 0, cs, (jbyte *)p);
     }
     return ba;
@@ -117,7 +145,7 @@
     }
     cs = strlen(p + dn);
     ba = (*_E)->NewByteArray(_E, cs + 1);
-    if (ba) {
+    if (ba && cs) {
         (*_E)->SetByteArrayRegion(_E, ba, 0, cs, (jbyte *)(p + dn));
     }
     return ba;
@@ -138,7 +166,7 @@
     if ((size_t)n < cs)
         cs = (size_t)n;
     ba = (*_E)->NewByteArray(_E, cs + 1);
-    if (ba) {
+    if (ba && cs) {
         (*_E)->SetByteArrayRegion(_E, ba, 0, cs, (jbyte *)p);
     }
     return ba;
@@ -165,9 +193,87 @@
     if ((size_t)n < cs)
         cs = (size_t)n;
     ba = (*_E)->NewByteArray(_E, cs + 1);
-    if (ba) {
+    if (ba && cs) {
         (*_E)->SetByteArrayRegion(_E, ba, 0, cs, (jbyte *)(p + dn));
     }
     return ba;
 }
 
+ACR_JNI_EXPORT_DECLARE(void, MbString, upper0)(ACR_JNISTDARGS, jbyteArray ba,
+                                               jint off, jint n)
+{
+    jbyte *p, *str;
+
+    str = (*_E)->GetByteArrayElements(_E, ba, NULL);
+    if (!str)
+        return;
+    p = str + (size_t)off;
+    while (*p && n) {
+        *p = acr_toupper(*p);
+        p++;
+        n--;
+    }
+    (*_E)->ReleaseByteArrayElements(_E, ba, str, JNI_COMMIT);
+}
+
+ACR_JNI_EXPORT_DECLARE(void, MbString, lower0)(ACR_JNISTDARGS, jbyteArray ba,
+                                               jint off, jint n)
+{
+    jbyte *p, *str;
+
+    str = (*_E)->GetByteArrayElements(_E, ba, NULL);
+    if (!str)
+        return;
+    p = str + (size_t)off;
+    while (*p && n) {
+        *p = acr_tolower(*p);
+        p++;
+        n--;
+    }
+    (*_E)->ReleaseByteArrayElements(_E, ba, str, JNI_COMMIT);
+}
+
+ACR_JNI_EXPORT_DECLARE(int, MbString, scmp0)(ACR_JNISTDARGS,
+                                             jbyteArray a,
+                                             jbyteArray b)
+{
+    int    rc = -1;
+    jbyte *sa;
+    jbyte *sb;
+
+    sa = (*_E)->GetByteArrayElements(_E, a, NULL);
+    if (!sa)
+        goto done;
+    sb = (*_E)->GetByteArrayElements(_E, b, NULL);
+    if (!sb)
+        goto clra;
+    rc = strcmp((const char *)sa, (const char *)sb);
+    (*_E)->ReleaseByteArrayElements(_E, b, sb, JNI_ABORT);
+clra:
+    (*_E)->ReleaseByteArrayElements(_E, a, sa, JNI_ABORT);
+done:
+    return rc;
+}
+
+ACR_JNI_EXPORT_DECLARE(int, MbString, ccmp0)(ACR_JNISTDARGS,
+                                             jbyteArray a,
+                                             jbyteArray b)
+{
+    int    rc = -1;
+    jbyte *sa;
+    jbyte *sb;
+
+    sa = (*_E)->GetByteArrayElements(_E, a, NULL);
+    if (!sa)
+        goto done;
+    sb = (*_E)->GetByteArrayElements(_E, b, NULL);
+    if (!sb)
+        goto clra;
+    rc = strcasecmp((const char *)sa, (const char *)sb);
+    (*_E)->ReleaseByteArrayElements(_E, b, sb, JNI_ABORT);
+clra:
+    (*_E)->ReleaseByteArrayElements(_E, a, sa, JNI_ABORT);
+done:
+    return rc;
+}
+

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/string.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/string.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Sun Jun 28 17:13:24 2009
@@ -23,6 +23,8 @@
 #include "acr_clazz.h"
 #include "acr_vm.h"
 
+extern int acr_native_codepage;
+
 J_DECLARE_CLAZZ = {
     NULL,
     NULL,
@@ -58,6 +60,173 @@
     ACR_UnloadClass(_E, &_clazzn);
 }
 
+static const char *iso_8859_1_aliases[] = {
+    "iso-8859-1", "8859-1", "8859_1", "iso_8859-1:1987", "iso8859-1",
+    "iso_8859-1", "iso8859_1 ", "latin1", "ibm-819", "ibm819",
+    "cp819", "819", "28591", "windows-28591", NULL
+};
+
+static const char *utf_8_aliases[] = {
+    "utf8", "utf-8", "cp1208", "65001", "windows-65001", NULL
+};
+
+static const char *us_ascii_aliases[] = {
+    "us-ascii", "ascii", "ascii7", "iso646-us", "us", "ibm367",
+    "cp367", "ansi_x3.4-1968", "646", "646us", "windows-20127", NULL
+};
+
+int acr_get_native_codepage(const char *cs)
+{
+    int i;
+    if (cs && *cs) {
+        for (i = 0; iso_8859_1_aliases[i]; i++) {
+            if (strcasecmp(cs, iso_8859_1_aliases[i]) == 0)
+                return ACR_CP_ISO8859_1;
+        }
+        for (i = 0; utf_8_aliases[i]; i++) {
+            if (strcasecmp(cs, utf_8_aliases[i]) == 0)
+                return ACR_CP_UTF_8;
+        }
+        for (i = 0; us_ascii_aliases[i]; i++) {
+            if (strcasecmp(cs, us_ascii_aliases[i]) == 0)
+                return ACR_CP_ISO8859_1;
+        }
+    }
+    return ACR_CP_DEFAULT;
+}
+
+static char *get_string_iso_8859_1(JNIEnv *_E, jstring str, char *b)
+{
+    jsize sl;
+    const jchar *sr;
+    char *rv = NULL;
+
+    sl = (*_E)->GetStringLength(_E, str);
+    if (b && sl < ACR_MBUFF_LEN)
+        rv = b;
+    else {
+        rv = (char *)ACR_Malloc(_E, THROW_FMARK, sl + 1);
+        if (!rv) {
+            /* Exception has already neen throw from ACR_Malloc
+             */
+            return NULL;
+        }
+    }
+    sr = (*_E)->GetStringCritical(_E, str, NULL);
+    if (!sr) {
+        if (rv != b)
+            free(rv);
+        return NULL;
+    }
+    else {
+        jsize i;
+        for (i = 0; i < sl; i++)
+            rv[i] = sr[i];
+    }
+    rv[sl] = '\0';
+    (*_E)->ReleaseStringCritical(_E, str, sr);
+    return rv;
+}
+
+static char *get_string_utf_8(JNIEnv *_E, jstring str, char *b)
+{
+    const char *sr;
+    char *rv = NULL;
+    size_t sl;
+
+    sr = (const char *)(*_E)->GetStringUTFChars(_E, str, NULL);
+    if (!sr) {
+        return NULL;
+    }
+    sl = strlen(sr);
+    if (b && sl < ACR_PBUFF_LEN)
+        rv = b;
+    else {
+        rv = (char *)ACR_Malloc(_E, THROW_FMARK, sl + 1);
+        if (rv == NULL) {
+            (*_E)->ReleaseStringUTFChars(_E, str, sr);
+            return NULL;
+        }
+    }
+    strcpy(rv, sr);
+    (*_E)->ReleaseStringUTFChars(_E, str, sr);
+    return rv;
+}
+
+static char *get_string_default(JNIEnv *_E, jstring str, char *b)
+{
+    jbyteArray sb = NULL;
+    char *rs = NULL;
+
+    sb = CALL_METHOD0(Object, 0001, str);
+    if ((*_E)->ExceptionCheck(_E))
+        return NULL;
+    else {
+        jint len = (*_E)->GetArrayLength(_E, sb);
+        if (b && len < ACR_PBUFF_LEN) {
+            /* Use provided stack storage */
+            rs = b;
+        }
+        else {
+            rs = (char *)ACR_Malloc(_E, THROW_FMARK, len + 1);
+            if (rs == NULL) {
+                (*_E)->DeleteLocalRef(_E, sb);
+                return NULL;
+            }
+        }
+        (*_E)->GetByteArrayRegion(_E, sb, 0, len, (jbyte *)rs);
+        rs[len] = '\0'; /* NUL-terminate */
+    }
+    (*_E)->DeleteLocalRef(_E, sb);
+    return rs;
+}
+
+static jstring new_string_default(JNIEnv *_E, const char *str)
+{
+    jstring    rs;
+    jbyteArray ba;
+    jsize      sl;
+
+    sl = (jsize)strlen(str);
+    ba = (*_E)->NewByteArray(_E, sl);
+    if (ba != NULL) {
+        (*_E)->SetByteArrayRegion(_E, ba, 0, sl, (jbyte *)str);
+        rs = (*_E)->NewObject(_E, _clazzn.i, J4MID(0000), ba);
+        (*_E)->DeleteLocalRef(_E, ba);
+        return rs;
+    }
+    return NULL;
+}
+
+static jstring new_string_iso_8859_1(JNIEnv *_E, const char *s)
+{
+    jstring rs = NULL;
+    if (s) {
+        size_t l = strlen(s);
+        if (l < ACR_MBUFF_SIZ) {
+            jchar  cc[ACR_MBUFF_SIZ];
+            size_t  i;
+            for (i = 0; i < l; i++) {
+                cc[i] = s[i];
+            }
+            rs = (*_E)->NewString(_E, cc, l);
+        }
+        else {
+            jchar  *cc;
+            if ((cc = ACR_Malloc(_E, THROW_FMARK, (l + 1) * sizeof(jchar)))) {
+                size_t  i;
+                for (i = 0; i < l; i++) {
+                    cc[i] = s[i];
+                }
+                rs = (*_E)->NewString(_E, cc, l);
+                free(cc);
+            }
+        }
+    }
+    return rs;
+}
+
+
 /*
  * Apache's "replacement" for the strncpy() function. We roll our
  * own to implement these specific changes:
@@ -220,7 +389,7 @@
     return src;
 }
 
-ACR_DECLARE(wchar_t *) ACR_GetJavaStringW(JNIEnv *_E, jstring str)
+ACR_DECLARE(wchar_t *) ACR_GetJavaStringW(JNIEnv *_E, jstring str, wchar_t *b)
 {
     jsize sl;
     const jchar *sr;
@@ -234,15 +403,20 @@
         return NULL;
     }
     sl = (*_E)->GetStringLength(_E, str);
-    rv = (wchar_t *)ACR_Malloc(_E, THROW_FMARK, (sl + 1) * sizeof(wchar_t));
-    if (!rv) {
-        /* Exception has already neen throw from ACR_Malloc
-         */
-        return NULL;
+    if (b && sl < ACR_MBUFF_LEN)
+        rv = b;
+    else {
+        rv = (wchar_t *)ACR_Malloc(_E, THROW_FMARK, (sl + 1) * sizeof(wchar_t));
+        if (!rv) {
+            /* Exception has already neen throw from ACR_Malloc
+             */
+            return NULL;
+        }
     }
     sr = (*_E)->GetStringCritical(_E, str, NULL);
     if (!sr) {
-        free(rv);
+        if (rv != b)
+            free(rv);
         return NULL;
     }
     else {
@@ -259,11 +433,8 @@
     return rv;
 }
 
-ACR_DECLARE(char *) ACR_GetJavaStringU(JNIEnv *_E, jstring str)
+ACR_DECLARE(char *) ACR_GetJavaStringA(JNIEnv *_E, jstring str, char *b)
 {
-    const char *sr;
-    char *rv = NULL;
-
     if (!str) {
         return NULL;
     }
@@ -271,84 +442,57 @@
         /* JNI out of memory error */
         return NULL;
     }
-    sr = (const char *)(*_E)->GetStringUTFChars(_E, str, NULL);
-    if (!sr) {
-        return NULL;
-    }
-    if (!(rv = strdup(sr))) {
-        /* Throw OutOfMemoryError
-         */
-        ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENOMEM,
-                           ACR_GET_OS_ERROR());
+    switch (acr_native_codepage) {
+        case ACR_CP_ISO8859_1:
+            return get_string_iso_8859_1(_E, str, b);
+        break;
+        case ACR_CP_UTF_8:
+            return get_string_utf_8(_E, str, b);
+        break;
+        default:
+            return get_string_default(_E, str, b);
+        break;
     }
-    (*_E)->ReleaseStringUTFChars(_E, str, sr);
-    return rv;
-}
-
-ACR_DECLARE(char *) ACR_GetJavaStringA(JNIEnv *_E, jstring str)
-{
-    jbyteArray sb = NULL;
-    char *rs = NULL;
-
-    if (!str) {
-        return NULL;
-    }
-    if ((*_E)->EnsureLocalCapacity(_E, 2) < 0) {
-        /* JNI out of memory error */
-        return NULL;
-    }
-    sb = CALL_METHOD0(Object, 0001, str);
-    if ((*_E)->ExceptionCheck(_E))
-        return NULL;
-    else {
-        jint len = (*_E)->GetArrayLength(_E, sb);
-        rs = (char *)ACR_Malloc(_E, THROW_FMARK, len + 1);
-        if (rs == NULL) {
-            (*_E)->DeleteLocalRef(_E, sb);
-            return NULL;
-        }
-        (*_E)->GetByteArrayRegion(_E, sb, 0, len, (jbyte *)rs);
-        rs[len] = '\0'; /* NUL-terminate */
-    }
-    (*_E)->DeleteLocalRef(_E, sb);
-    return rs;
+    /* Never reached */
+    return NULL;
 }
 
 ACR_DECLARE(jstring) ACR_NewJavaStringW(JNIEnv *_E, const wchar_t *s)
 {
     jstring r = NULL;
     if (s) {
-        size_t len = wcslen(s);
+        size_t l = wcslen(s);
 #if CC_SIZEOF_WCHAR_T == 2
-        r = (*_E)->NewString(_E, (const jchar *)s, (jsize)len);
+        r = (*_E)->NewString(_E, (const jchar *)s, (jsize)l);
 #else
-        jchar  *cc;
-        if ((cc = ACR_Malloc(_E, THROW_FMARK, (len + 1) * sizeof(jchar)))) {
+        if (l < ACR_MBUFF_SIZ) {
+            jchar  cc[ACR_MBUFF_SIZ];
             size_t  i;
-            for (i = 0; i < len; i++) {
+            for (i = 0; i < l; i++) {
                 /* Simply assign utf32 to utf16 */
                 cc[i] = (jchar)s[i];
             }
-            r = (*_E)->NewString(_E, cc, len);
-            free(cc);
+            r = (*_E)->NewString(_E, cc, l);
+        }
+        else {
+            jchar  *cc;
+            if ((cc = ACR_Malloc(_E, THROW_FMARK, (l + 1) * sizeof(jchar)))) {
+                size_t  i;
+                for (i = 0; i < l; i++) {
+                    /* Simply assign utf32 to utf16 */
+                    cc[i] = (jchar)s[i];
+                }
+                r = (*_E)->NewString(_E, cc, l);
+                free(cc);
+            }
         }
 #endif
     }
     return r;
 }
 
-ACR_DECLARE(jstring) ACR_NewJavaStringU(JNIEnv *_E, const char *str)
-{
-    if (!str)
-        return NULL;
-    return (*_E)->NewStringUTF(_E, str);
-}
-
 ACR_DECLARE(jstring) ACR_NewJavaStringA(JNIEnv *_E, const char *str)
 {
-    jstring    rs;
-    jbyteArray ba;
-    jsize      sl;
 
     if (!str)
         return NULL;
@@ -356,16 +500,19 @@
         /* JNI out of memory error */
         return NULL;
     }
-    sl = (jsize)strlen(str);
-    ba = (*_E)->NewByteArray(_E, sl);
-    if (ba != NULL) {
-        (*_E)->SetByteArrayRegion(_E, ba, 0, sl, (jbyte *)str);
-        rs = (*_E)->NewObject(_E, _clazzn.i, J4MID(0000), ba);
-        (*_E)->DeleteLocalRef(_E, ba);
-        return rs;
+    switch (acr_native_codepage) {
+        case ACR_CP_ISO8859_1:
+            return new_string_iso_8859_1(_E, str);
+        break;
+        case ACR_CP_UTF_8:
+            return (*_E)->NewStringUTF(_E, str);
+        break;
+        default:
+            return new_string_default(_E, str);
+        break;
     }
+    /* Never reached */
     return NULL;
-
 }
 
 /* Match = 0, NoMatch = 1, Abort = -1
@@ -440,3 +587,4 @@
     }
     return (str[x] != L'\0');
 }
+

Modified: commons/sandbox/runtime/trunk/src/main/native/test/testcase.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testcase.c?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/testcase.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/test/testcase.c Sun Jun 28 17:13:24 2009
@@ -145,7 +145,7 @@
 ACR_JNI_EXPORT_DECLARE(jint, TestPrivate, test009)(ACR_JNISTDARGS, jstring s)
 {
     jint l;
-    wchar_t *str = ACR_GetJavaStringW(_E, s);
+    wchar_t *str = ACR_GetJavaStringW(_E, s, NULL);
 
     l = (jint)wcslen(str);
     ACR_Free(_E, THROW_FMARK, str);
@@ -155,7 +155,7 @@
 ACR_JNI_EXPORT_DECLARE(jint, TestPrivate, test010)(ACR_JNISTDARGS, jstring s)
 {
     jint l;
-    char *str = ACR_GetJavaStringU(_E, s);
+    char *str = ACR_GetJavaStringA(_E, s, NULL);
 
     l = (jint)strlen(str);
     ACR_Free(_E, THROW_FMARK, str);

Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java?rev=789127&r1=789126&r2=789127&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java Sun Jun 28 17:13:24 2009
@@ -17,6 +17,7 @@
 package org.apache.commons.runtime;
 
 import org.apache.commons.runtime.exception.*;
+import org.apache.commons.runtime.util.Ascii;
 import java.lang.System;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -45,7 +46,7 @@
     {
         byte [] ba = { (byte)'S', (byte)'t', (byte)'r', (byte)0 };
         MbString s = new MbString(ba);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", ba[0], ca[0]);
         assertEquals("length", ba.length, ca.length);
     }
@@ -57,7 +58,7 @@
         Pointer p = Memory.malloc(16);
         Memory.copy(ba, 0, p, 0, ba.length);
         MbString s = new MbString(p);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", ba[0], ca[0]);
         assertEquals("length", ba.length, ca.length);
     }
@@ -70,7 +71,7 @@
         p.poke(1, 'B');
         p.poke(2, 0);
         MbString s = new MbString(p);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", 'A', ca[0]);
         assertEquals("Value", 'B', ca[1]);
         assertEquals("Value",  0,  ca[2]);
@@ -85,7 +86,7 @@
         p.poke(1, 'B');
         p.poke(2, 0);
         MbString s = new MbString(p, 1);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", 'A', ca[0]);
         assertEquals("Value",  0,  ca[1]);
         assertEquals("length", 1,  s.length());
@@ -99,7 +100,7 @@
         p.poke(1, 'B');
         p.poke(2, 0);
         MbString s = new MbString(p, 1L);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", 'B', ca[0]);
         assertEquals("Value",  0,  ca[1]);
         assertEquals("length", 1,  s.length());
@@ -114,12 +115,31 @@
         p.poke(2, 'C');
         p.poke(3, 0);
         MbString s = new MbString(p, 1L, 1);
-        byte [] ca = s.getBytes();
+        byte [] ca = s.getStorage();
         assertEquals("Value", 'B', ca[0]);
         assertEquals("Value",  0,  ca[1]);
         assertEquals("length", 1,  s.length());
     }
 
+    public void testMbStringC5()
+        throws Exception
+    {
+        MbString s = new MbString("ABC");
+        byte [] ca = s.getStorage();
+        assertEquals("Value", 'B', ca[1]);
+        assertEquals("Value",  0,  ca[3]);
+        assertEquals("length", 3,  s.length());
+        assertEquals("size",   4,  ca.length);
+    }
+
+    public void testAscii()
+        throws Exception
+    {
+    	byte b = (byte)0xF4;    	
+        assertTrue("Lower Ascii",  Ascii.islower('a'));      
+        assertTrue("Upper Ascii",  Ascii.isupper('A'));      
+        assertFalse("Lower Char",  Ascii.islower(b));
+    }    
 
 }