diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index 2c3e8869..08c1022b 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -31,28 +31,28 @@ import java.io.PrintStream; import org.luaj.vm2.lib.MathLib; /** - * Subclass of {@link LuaValue} for representing lua strings. + * Subclass of {@link LuaValue} for representing lua strings. *

- * Because lua string values are more nearly sequences of bytes than + * Because lua string values are more nearly sequences of bytes than * sequences of characters or unicode code points, the {@link LuaString} - * implementation holds the string value in an internal byte array. + * implementation holds the string value in an internal byte array. *

- * {@link LuaString} values are not considered mutable once constructed, + * {@link LuaString} values are not considered mutable once constructed, * so multiple {@link LuaString} values can chare a single byte array. *

* Currently {@link LuaString}s are pooled via a centrally managed weak table. - * To ensure that as many string values as possible take advantage of this, - * Constructors are not exposed directly. As with number, booleans, and nil, + * To ensure that as many string values as possible take advantage of this, + * Constructors are not exposed directly. As with number, booleans, and nil, * instance construction should be via {@link LuaValue#valueOf(byte[])} or similar API. *

* Because of this pooling, users of LuaString must not directly alter the * bytes in a LuaString, or undefined behavior will result. *

- * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. - * The functions + * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. + * The functions * {@link #lengthAsUtf8(char[])}, - * {@link #encodeToUtf8(char[], int, byte[], int)}, and - * {@link #decodeAsUtf8(byte[], int, int)} + * {@link #encodeToUtf8(char[], int, byte[], int)}, and + * {@link #decodeAsUtf8(byte[], int, int)} * are used to convert back and forth between UTF8 byte arrays and character arrays. * * @see LuaValue @@ -63,15 +63,15 @@ public class LuaString extends LuaValue { /** The singleton instance for string metatables that forwards to the string functions. * Typically, this is set to the string metatable as a side effect of loading the string - * library, and is read-write to provide flexible behavior by default. When used in a + * library, and is read-write to provide flexible behavior by default. When used in a * server environment where there may be roge scripts, this should be replaced with a * read-only table since it is shared across all lua code in this Java VM. */ public static LuaValue s_metatable; /** The bytes for the string. These must not be mutated directly because - * the backing may be shared by multiple LuaStrings, and the hash code is - * computed only at construction time. + * the backing may be shared by multiple LuaStrings, and the hash code is + * computed only at construction time. * It is exposed only for performance and legacy reasons. */ public final byte[] m_bytes; @@ -84,29 +84,29 @@ public class LuaString extends LuaValue { /** The hashcode for this string. Computed at construct time. */ private final int m_hashcode; - /** Size of cache of recent short strings. This is the maximum number of LuaStrings that + /** Size of cache of recent short strings. This is the maximum number of LuaStrings that * will be retained in the cache of recent short strings. Exposed to package for testing. */ static final int RECENT_STRINGS_CACHE_SIZE = 128; - /** Maximum length of a string to be considered for recent short strings caching. + /** Maximum length of a string to be considered for recent short strings caching. * This effectively limits the total memory that can be spent on the recent strings cache, - * because no LuaString whose backing exceeds this length will be put into the cache. + * because no LuaString whose backing exceeds this length will be put into the cache. * Exposed to package for testing. */ static final int RECENT_STRINGS_MAX_LENGTH = 32; - /** Simple cache of recently created strings that are short. - * This is simply a list of strings, indexed by their hash codes modulo the cache size - * that have been recently constructed. If a string is being constructed frequently - * from different contexts, it will generally show up as a cache hit and resolve + /** Simple cache of recently created strings that are short. + * This is simply a list of strings, indexed by their hash codes modulo the cache size + * that have been recently constructed. If a string is being constructed frequently + * from different contexts, it will generally show up as a cache hit and resolve * to the same value. */ private static final class RecentShortStrings { - private static final LuaString recent_short_strings[] = + private static final LuaString recent_short_strings[] = new LuaString[RECENT_STRINGS_CACHE_SIZE]; } /** - * Get a {@link LuaString} instance whose bytes match - * the supplied Java String using the UTF8 encoding. + * Get a {@link LuaString} instance whose bytes match + * the supplied Java String using the UTF8 encoding. * @param string Java String containing characters to encode as UTF8 * @return {@link LuaString} with UTF8 bytes corresponding to the supplied String */ @@ -120,7 +120,7 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} for a portion of a byte array. *

* The array is first be used as the backing for this object, so clients must not change contents. - * If the supplied value for 'len' is more than half the length of the container, the + * If the supplied value for 'len' is more than half the length of the container, the * supplied byte array will be used as the backing, otherwise the bytes will be copied to a * new byte array, and cache lookup may be performed. *

@@ -172,11 +172,11 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} using the supplied characters as byte values. *

- * Only the low-order 8-bits of each character are used, the remainder is ignored. + * Only the low-order 8-bits of each character are used, the remainder is ignored. *

- * This is most useful for constructing byte sequences that do not conform to UTF8. - * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. - * @return {@link LuaString} wrapping a copy of the byte buffer + * This is most useful for constructing byte sequences that do not conform to UTF8. + * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. + * @return {@link LuaString} wrapping a copy of the byte buffer */ public static LuaString valueOf(char[] bytes) { return valueOf(bytes, 0, bytes.length); @@ -184,11 +184,11 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} using the supplied characters as byte values. *

- * Only the low-order 8-bits of each character are used, the remainder is ignored. + * Only the low-order 8-bits of each character are used, the remainder is ignored. *

- * This is most useful for constructing byte sequences that do not conform to UTF8. - * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. - * @return {@link LuaString} wrapping a copy of the byte buffer + * This is most useful for constructing byte sequences that do not conform to UTF8. + * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. + * @return {@link LuaString} wrapping a copy of the byte buffer */ public static LuaString valueOf(char[] bytes, int off, int len) { byte[] b = new byte[len]; @@ -215,7 +215,7 @@ public class LuaString extends LuaValue { * The LuaString returned will either be a new LuaString containing the byte array, * or be an existing LuaString used already having the same value. *

- * The caller must not mutate the contents of the byte array after this call, as + * The caller must not mutate the contents of the byte array after this call, as * it may be used elsewhere due to recent short string caching. * @param bytes byte buffer * @return {@link LuaString} wrapping the byte buffer @@ -241,11 +241,11 @@ public class LuaString extends LuaValue { } public boolean isstring() { - return true; + return true; } - public LuaValue getmetatable() { - return s_metatable; + public LuaValue getmetatable() { + return s_metatable; } public int type() { @@ -289,20 +289,20 @@ public class LuaString extends LuaValue { public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); } // relational operators, these only work with other strings - public LuaValue lt( LuaValue rhs ) { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; } - public boolean lt_b( LuaValue rhs ) { return rhs.strcmp(this)>0; } + public LuaValue lt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>0? LuaValue.TRUE: FALSE) : super.lt(rhs); } + public boolean lt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>0 : super.lt_b(rhs); } public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue lteq( LuaValue rhs ) { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; } - public boolean lteq_b( LuaValue rhs ) { return rhs.strcmp(this)>=0; } + public LuaValue lteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE) : super.lteq(rhs); } + public boolean lteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>=0 : super.lteq_b(rhs); } public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue gt( LuaValue rhs ) { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; } - public boolean gt_b( LuaValue rhs ) { return rhs.strcmp(this)<0; } + public LuaValue gt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<0? LuaValue.TRUE: FALSE) : super.gt(rhs); } + public boolean gt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<0 : super.gt_b(rhs); } public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue gteq( LuaValue rhs ) { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; } - public boolean gteq_b( LuaValue rhs ) { return rhs.strcmp(this)<=0; } + public LuaValue gteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE) : super.gteq(rhs); } + public boolean gteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<=0 : super.gteq_b(rhs); } public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } @@ -310,14 +310,14 @@ public class LuaString extends LuaValue { public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); } public Buffer concat(Buffer rhs) { return rhs.concatTo(this); } public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); } - public LuaValue concatTo(LuaString lhs) { + public LuaValue concatTo(LuaString lhs) { byte[] b = new byte[lhs.m_length+this.m_length]; System.arraycopy(lhs.m_bytes, lhs.m_offset, b, 0, lhs.m_length); System.arraycopy(this.m_bytes, this.m_offset, b, lhs.m_length, this.m_length); return valueUsing(b, 0, b.length); } - // string comparison + // string comparison public int strcmp(LuaValue lhs) { return -lhs.strcmp(this); } public int strcmp(LuaString rhs) { for ( int i=0, j=0; i=0 ) + while ( --n>=0 ) if ( a[i++]!=b[j++] ) return false; return true; @@ -535,8 +535,8 @@ public class LuaString extends LuaValue { return luaByte( index ); } - public String checkjstring() { - return tojstring(); + public String checkjstring() { + return tojstring(); } public LuaString checkstring() { @@ -552,7 +552,7 @@ public class LuaString extends LuaValue { } /** - * Copy the bytes of the string into the given byte array. + * Copy the bytes of the string into the given byte array. * @param strOffset offset from which to copy * @param bytes destination byte array * @param arrayOffset offset in destination @@ -626,12 +626,12 @@ public class LuaString extends LuaValue { /** - * Convert to Java String interpreting as utf8 characters. + * Convert to Java String interpreting as utf8 characters. * * @param bytes byte array in UTF8 encoding to convert * @param offset starting index in byte array * @param length number of bytes to convert - * @return Java String corresponding to the value of bytes interpreted using UTF8 + * @return Java String corresponding to the value of bytes interpreted using UTF8 * @see #lengthAsUtf8(char[]) * @see #encodeToUtf8(char[], int, byte[], int) * @see #isValidUtf8() @@ -662,7 +662,7 @@ public class LuaString extends LuaValue { * @see #decodeAsUtf8(byte[], int, int) * @see #isValidUtf8() */ - public static int lengthAsUtf8(char[] chars) { + public static int lengthAsUtf8(char[] chars) { int i,b; char c; for ( i=b=chars.length; --i>=0; ) @@ -673,7 +673,7 @@ public class LuaString extends LuaValue { /** * Encode the given Java string as UTF-8 bytes, writing the result to bytes - * starting at offset. + * starting at offset. *

* The string should be measured first with lengthAsUtf8 * to make sure the given byte array is large enough. @@ -694,11 +694,11 @@ public class LuaString extends LuaValue { bytes[j++] = (byte) c; } else if ( c < 0x800 ) { bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f)); - bytes[j++] = (byte) (0x80 | ( c & 0x3f)); + 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)); + bytes[j++] = (byte) (0x80 | ( c & 0x3f)); } } return j - off; @@ -714,12 +714,12 @@ public class LuaString extends LuaValue { for (int i=m_offset,j=m_offset+m_length; i= 0 ) continue; - if ( ((c & 0xE0) == 0xC0) - && i 36 ) @@ -788,7 +788,7 @@ public class LuaString extends LuaValue { * @param base the base to use, such as 10 * @param start the index to start searching from * @param end the first index beyond the search range - * @return double value if conversion is valid, + * @return double value if conversion is valid, * or Double.NaN if not */ private double scanlong( int base, int start, int end ) { @@ -798,7 +798,7 @@ public class LuaString extends LuaValue { int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0': m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10)); if ( digit < 0 || digit >= base ) - return Double.NaN; + return Double.NaN; x = x * base + digit; if ( x < 0 ) return Double.NaN; // overflow @@ -810,7 +810,7 @@ public class LuaString extends LuaValue { * Scan and convert a double value, or return Double.NaN if not a double. * @param start the index to start searching from * @param end the first index beyond the search range - * @return double value if conversion is valid, + * @return double value if conversion is valid, * or Double.NaN if not */ private double scandouble(int start, int end) { @@ -833,7 +833,7 @@ public class LuaString extends LuaValue { c[i-start] = (char) m_bytes[i]; try { return Double.parseDouble(new String(c)); - } catch ( Exception e ) { + } catch ( Exception e ) { return Double.NaN; } }