Add some helper methods:

(1) getKeys() in LTable is now public. It provides a convenient interface
    to access the table's elements from Java instead of Lua.
(2) LString.toInputStream produces an instance of InputStream from which
    the string's bytes can be read.
This commit is contained in:
Ian Farmer
2007-09-12 05:22:30 +00:00
parent 31e2d95076
commit 6d0e9bb566
2 changed files with 58 additions and 32 deletions

View File

@@ -1,5 +1,6 @@
package lua.value;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
@@ -161,6 +162,26 @@ public class LString extends LValue {
System.arraycopy( m_bytes, m_offset+strOffset, bytes, arrayOffset, len );
}
/**
* Produce an InputStream instance from which the bytes of this LString can be read.
* Underlying byte array is not copied.
*/
public ByteArrayInputStream toInputStream() {
// Well, this is really something.
// Javadoc for java versions 1.3 and earlier states that if reset() is
// called on a ByteArrayInputStream constructed with the 3-argument
// constructor, then bytes 0 .. offset will be returned by the next
// calls to read(). In JDK 1.4, the behavior improved, so that the
// initial mark is set to the initial offset. We still need to
// override ByteArrayInputStream here just in case we run on a
// JVM with the older behavior.
return new ByteArrayInputStream( m_bytes, m_offset, m_length ) {
public synchronized void reset() {
pos = Math.max( m_offset, mark );
}
};
}
public boolean luaBinCmpUnknown(int opcode, LValue lhs) {
return lhs.luaBinCmpString(opcode, this);
}

View File

@@ -268,17 +268,15 @@ public class LTable extends LValue {
/** Valid for tables */
public LValue luaPairs() {
return new LTableIterator(this);
return new LTableIterator();
}
/** Iterator for tables */
static final class LTableIterator extends LFunction {
private final LTable t;
private final class LTableIterator extends LFunction {
private int arrayIndex;
private int hashIndex;
private LTableIterator(LTable t) {
this.t = t;
private LTableIterator() {
this.arrayIndex = 0;
this.hashIndex = 0;
}
@@ -287,18 +285,18 @@ public class LTable extends LValue {
public boolean luaStackCall(VM vm) {
vm.setResult();
int i;
while ( ( i = arrayIndex++ ) < t.m_vector.length ) {
if ( t.m_vector[i] != LNil.NIL ) {
while ( ( i = arrayIndex++ ) < m_vector.length ) {
if ( m_vector[i] != LNil.NIL ) {
vm.push( new LInteger( arrayIndex ) );
vm.push( t.m_vector[ i ] );
vm.push( m_vector[ i ] );
return false;
}
}
if ( t.m_hashKeys != null ) {
while ( ( i = hashIndex++ ) < t.m_hashKeys.length ) {
if ( t.m_hashKeys[i] != null ) {
vm.push( t.m_hashKeys[i] );
vm.push( t.m_hashValues[i] );
if ( m_hashKeys != null ) {
while ( ( i = hashIndex++ ) < m_hashKeys.length ) {
if ( m_hashKeys[i] != null ) {
vm.push( m_hashKeys[i] );
vm.push( m_hashValues[i] );
return false;
}
}
@@ -307,6 +305,32 @@ public class LTable extends LValue {
}
}
/**
* Helper method to get all the keys in this table in an array. Meant to be
* used instead of keys() (which returns an enumeration) when an array is
* more convenient. Note that for a very large table, getting an Enumeration
* instead would be more space efficient.
*/
public LValue[] getKeys() {
LValue[] keys = new LValue[ m_arrayEntries + m_hashEntries ];
int out = 0;
for ( int i = 0; i < m_vector.length; ++i ) {
if ( m_vector[ i ] != LNil.NIL ) {
keys[ out++ ] = new LInteger( i + 1 );
}
}
if ( m_hashKeys != null ) {
for ( int i = 0; i < m_hashKeys.length; ++i ) {
if ( m_hashKeys[ i ] != null )
keys[ out++ ] = m_hashKeys[i];
}
}
return keys;
}
/** Remove the value in the table with the given integer key. */
private void remove( int key ) {
if ( key > 0 ) {
@@ -490,23 +514,4 @@ public class LTable extends LValue {
return m_vector.length;
}
LValue[] getKeys() {
LValue[] keys = new LValue[ m_arrayEntries + m_hashEntries ];
int out = 0;
for ( int i = 0; i < m_vector.length; ++i ) {
if ( m_vector[ i ] != LNil.NIL ) {
keys[ out++ ] = new LInteger( i + 1 );
}
}
if ( m_hashKeys != null ) {
for ( int i = 0; i < m_hashKeys.length; ++i ) {
if ( m_hashKeys[ i ] != null )
keys[ out++ ] = m_hashKeys[i];
}
}
return keys;
}
}