From cce33612ce995aa5f2a1bbd1479b35fbc838cc4b Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Mon, 5 Nov 2007 19:12:01 +0000 Subject: [PATCH] replace deprecated API's. --- .../java/lua/addon/luacompat/StrLib.java | 124 +++++++++--------- src/main/java/lua/Builtin.java | 2 +- src/main/java/lua/value/LString.java | 72 +++++++--- src/test/java/lua/value/LStringTest.java | 38 ++++++ 4 files changed, 159 insertions(+), 77 deletions(-) diff --git a/src/addon/java/lua/addon/luacompat/StrLib.java b/src/addon/java/lua/addon/luacompat/StrLib.java index ac4d1156..66c76875 100644 --- a/src/addon/java/lua/addon/luacompat/StrLib.java +++ b/src/addon/java/lua/addon/luacompat/StrLib.java @@ -2,8 +2,6 @@ package lua.addon.luacompat; import lua.VM; import lua.value.LFunction; -import lua.value.LInteger; -import lua.value.LNil; import lua.value.LNumber; import lua.value.LString; import lua.value.LTable; @@ -22,12 +20,12 @@ public class StrLib { * @param vm the calling vm */ static void byte_( VM vm ) { - LString ls = vm.getArgAsLuaString(0); + LString ls = vm.tolstring(2); int l = ls.length(); - final int nargs = vm.getArgCount(); - int i = posrelat( ( nargs > 1 ) ? vm.getArgAsInt(1) : 1, l ); - int j = posrelat( ( nargs > 2 ) ? vm.getArgAsInt(2) : i, l ); - vm.setResult(); + final int top = vm.gettop(); + int i = posrelat( ( top >= 3 ) ? vm.tointeger(3) : 1, l ); + int j = posrelat( ( top >= 4 ) ? vm.tointeger(4) : i, l ); + vm.settop(0); if ( i <= 0 ) i = 1; if ( j > l ) @@ -36,7 +34,7 @@ public class StrLib { return; int n = j - i + 1; for ( int k=0; k < n; k++ ) - vm.push( LInteger.valueOf( ls.luaByte(k+i-1) ) ); + vm.pushinteger( ls.luaByte(k+i-1) ); } /** @@ -51,11 +49,12 @@ public class StrLib { * @param vm the calling VM */ public static void char_( VM vm) { - int nargs = vm.getArgCount(); + int nargs = vm.gettop()-1; byte[] bytes = new byte[nargs]; for ( int i=0; i=0 ) { @@ -169,7 +170,7 @@ public class StrLib { return false; } } - vm.push( LNil.NIL ); + vm.pushnil(); return false; } } @@ -221,11 +222,11 @@ public class StrLib { * --> x="lua-5.1.tar.gz" */ static void gsub( VM vm ) { - LString src = vm.getArgAsLuaString( 0 ); + LString src = vm.tolstring(2); final int srclen = src.length(); - LString p = vm.getArgAsLuaString( 1 ); - LValue repl = vm.getArg( 2 ); - int max_s = ( vm.getArgCount() > 3 ? vm.getArgAsInt( 3 ) : srclen + 1 ); + LString p = vm.tolstring(3); + LValue repl = vm.topointer( 4 ); + int max_s = ( vm.gettop() >= 5 ? vm.tointeger( 5 ) : srclen + 1 ); final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^'; LBuffer lbuf = new LBuffer( srclen ); @@ -250,9 +251,9 @@ public class StrLib { break; } lbuf.append( src.substring( soffset, srclen ) ); - vm.setResult(); - vm.push( lbuf.toLuaString() ); - vm.push( LInteger.valueOf( n ) ); + vm.settop(0); + vm.pushlstring( lbuf.toLuaString() ); + vm.pushinteger( n ); } /** @@ -261,8 +262,10 @@ public class StrLib { * Receives a string and returns its length. The empty string "" has length 0. * Embedded zeros are counted, so "a\000bc\000" has length 5. */ - static void len( VM vm ) { - vm.setResult( LInteger.valueOf( vm.getArgAsLuaString(0).length()) ); + static void len( VM vm ) { + int l = vm.tostring(2).length(); + vm.settop(0); + vm.pushinteger( l ); } /** @@ -272,8 +275,10 @@ public class StrLib { * changed to lowercase. All other characters are left unchanged. * The definition of what an uppercase letter is depends on the current locale. */ - static void lower( VM vm ) { - vm.setResult( new LString( vm.getArgAsString(0).toLowerCase() ) ); + static void lower( VM vm ) { + String s = vm.tostring(2).toLowerCase(); + vm.settop(0); + vm.pushstring( s ); } /** @@ -295,18 +300,16 @@ public class StrLib { * Returns a string that is the concatenation of n copies of the string s. */ static void rep( VM vm ) { - LString s = vm.getArgAsLuaString( 0 ); - int n = vm.getArgAsInt( 1 ); + LString s = vm.tolstring(2); + int n = vm.tointeger( 3 ); + vm.settop(0); if ( n >= 0 ) { final byte[] bytes = new byte[ s.length() * n ]; int len = s.length(); for ( int offset = 0; offset < bytes.length; offset += len ) { s.copyInto( 0, bytes, offset, len ); } - - vm.setResult( new LString( bytes ) ); - } else { - vm.setResult( LNil.NIL ); + vm.pushlstring( bytes ); } } @@ -316,12 +319,13 @@ public class StrLib { * Returns a string that is the string s reversed. */ static void reverse( VM vm ) { - LString s = vm.getArgAsLuaString(0); + LString s = vm.tolstring(2); int n = s.length(); byte[] b = new byte[n]; for ( int i=0, j=n-1; i 1 ? vm.getArgAsInt( 1 ) : 1, len ); - int j = posrelat( nargs > 2 ? vm.getArgAsInt( 2 ) : -1, len ); + int i = posrelat( top >= 3 ? vm.tointeger( 3 ) : 1, len ); + int j = posrelat( top >= 4 ? vm.tointeger( 4 ) : -1, len ); if ( i < 1 ) i = 1; if ( j > len ) j = len; + vm.settop(0); if ( i <= j ) { LString result = s.substring( i - 1 , j ); - vm.setResult( result ); + vm.pushlstring( result ); } else { - vm.setResult( new LString( "" ) ); + vm.pushstring( "" ); } } @@ -364,16 +369,18 @@ public class StrLib { * The definition of what a lowercase letter is depends on the current locale. */ static void upper( VM vm ) { - vm.setResult( new LString( vm.getArgAsString(0).toUpperCase() ) ); + String s = vm.tostring(2).toUpperCase(); + vm.settop(0); + vm.pushstring(s); } /** * This utility method implements both string.find and string.match. */ static void str_find_aux( VM vm, boolean find ) { - LString s = vm.getArgAsLuaString( 0 ); - LString pat = vm.getArgAsLuaString( 1 ); - int init = vm.getArgCount() > 2 ? vm.getArgAsInt( 2 ) : 1; + LString s = vm.tolstring(2); + LString pat = vm.tolstring(3); + int init = vm.gettop() >= 4 ? vm.tointeger( 4 ) : 1; if ( init > 0 ) { init = Math.min( init - 1, s.length() ); @@ -381,14 +388,14 @@ public class StrLib { init = Math.max( 0, s.length() + init ); } - boolean fastMatch = find && ( vm.getArgAsBoolean( 3 ) || pat.indexOfAny( SPECIALS ) == -1 ); - vm.setResult(); + boolean fastMatch = find && ( vm.toboolean( 5 ) || pat.indexOfAny( SPECIALS ) == -1 ); + vm.settop(0); if ( fastMatch ) { int result = s.indexOf( pat, init ); if ( result != -1 ) { - vm.push( result + 1 ); - vm.push( result + pat.length() ); + vm.pushinteger( result + 1 ); + vm.pushinteger( result + pat.length() ); return; } } else { @@ -407,8 +414,8 @@ public class StrLib { ms.reset(); if ( ( res = ms.match( soff, poff ) ) != -1 ) { if ( find ) { - vm.push( soff + 1 ); - vm.push( res ); + vm.pushinteger( soff + 1 ); + vm.pushinteger( res ); ms.push_captures( false, soff, res ); } else { ms.push_captures( true, soff, res ); @@ -417,8 +424,7 @@ public class StrLib { } } while ( soff++ < s.length() && !anchor ); } - - vm.setResult( LNil.NIL ); + vm.pushnil(); } private static int posrelat( int pos, int len ) { @@ -521,7 +527,7 @@ public class StrLib { add_s( lbuf, repl.luaAsString(), soffset, end ); return; } else if ( repl instanceof LFunction ) { - vm.push( repl ); + vm.pushlvalue( repl ); int n = push_captures( true, soffset, end ); vm.call( n, 1 ); } else if ( repl instanceof LTable ) { @@ -556,7 +562,7 @@ public class StrLib { private void push_onecapture( int i, int soff, int end ) { if ( i >= this.level ) { if ( i == 0 ) { - vm.push( s.substring( soff, end ) ); + vm.pushlstring( s.substring( soff, end ) ); } else { vm.error( "invalid capture index" ); } @@ -566,10 +572,10 @@ public class StrLib { vm.error( "unfinished capture" ); } if ( l == CAP_POSITION ) { - vm.push( LInteger.valueOf( cinit[i] + 1 ) ); + vm.pushinteger( cinit[i] + 1 ); } else { int begin = cinit[i]; - vm.push( s.substring( begin, begin + l ) ); + vm.pushlstring( s.substring( begin, begin + l ) ); } } } diff --git a/src/main/java/lua/Builtin.java b/src/main/java/lua/Builtin.java index 17c15d7a..cb0ecf2d 100644 --- a/src/main/java/lua/Builtin.java +++ b/src/main/java/lua/Builtin.java @@ -59,7 +59,7 @@ final class Builtin extends JavaFunction { for ( int i=1; i<=n; i++ ) { if ( i > 1 ) stdout.print( "\t" ); - stdout.print( vm.topointer(i).toJavaString() ); + stdout.print( vm.tostring(i) ); } stdout.println(); return 0; diff --git a/src/main/java/lua/value/LString.java b/src/main/java/lua/value/LString.java index 1e7f1843..d363dc3b 100644 --- a/src/main/java/lua/value/LString.java +++ b/src/main/java/lua/value/LString.java @@ -42,20 +42,66 @@ public class LString extends LValue { } /** - * Construct a Lua string from the given Java string. Characters are encoded - * using UTF-8. + * Construct a Lua string from the given Java string. + * Characters are encoded using UTF-8. */ public LString(String string) { - byte[] bytes; - try { - bytes = string.getBytes( "UTF-8" ); - } catch ( UnsupportedEncodingException exn ) { - bytes = stringToUtf8Bytes( string ); + + // measure bytes required to encode + int n = string.length(); + int b = n; + char c; + for ( int i=0; i= 0x80 ) { + ++b; + if ( c >= 0x800 ) + ++b; + } + } + byte[] bytes = new byte[b]; + int j = 0; + for ( int i=0; i>6) & 0x1f)); + bytes[j++] = (byte) (0x80 | ( c & 0x3f)); + } else { + bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f)); + bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f)); + bytes[j++] = (byte) (0x80 | ( c & 0x3f)); + } } this.m_bytes = bytes; this.m_offset = 0; - this.m_length = m_bytes.length; - this.m_hash = hashBytes( m_bytes, 0, m_length ); + this.m_length = b; + this.m_hash = hashBytes( bytes, 0, b ); + } + + /** + * Convert to Java string using UTF-8 encoding + */ + public String toJavaString() { + char[] c = new char[m_length]; + int n = 0; + int b; + for ( int i=0; i= 0x80 ) { + sb.append( "\\u"+Integer.toHexString(0x10000+c).substring(1) ); + } else { + sb.append( (char) c ); + } + } + return sb.toString(); + } + + public void testUtf8() { + for ( int i=4; i<0xffff; i+=4 ) { + char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) }; + String before = new String(c)+" "+i+"-"+(i+4); + LString ls = new LString(before); + String after = ls.toJavaString(); + assertEquals( userFriendly( before ), userFriendly( after ) ); + } + char[] c = { (char) (1), (char) (2), (char) (3) }; + String before = new String(c)+" 1-3"; + LString ls = new LString(before); + String after = ls.toJavaString(); + assertEquals( userFriendly( before ), userFriendly( after ) ); + + } + public void testNullTerminated() { + char[] c = { 'a', 'b', 'c', '\0', 'd', 'e', 'f' }; + String before = new String(c); + LString ls = new LString(before); + String after = ls.toJavaString(); + assertEquals( userFriendly( "abc" ), userFriendly( after ) ); + + } }