1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-12 18:30:29 +00:00

Merge pull request #541 from SquidDev-CC/ComputerCraft/feature/unlimited-reads

Remove upper bound on how many bytes/characters can be read
This commit is contained in:
SquidDev 2018-04-23 16:42:28 +01:00
commit a42793024b
2 changed files with 80 additions and 15 deletions

View File

@ -5,6 +5,7 @@ import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
@ -13,6 +14,8 @@ import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
public class BinaryInputHandle extends HandleGeneric public class BinaryInputHandle extends HandleGeneric
{ {
private static final int BUFFER_SIZE = 8192;
private final InputStream m_stream; private final InputStream m_stream;
public BinaryInputHandle( InputStream reader ) public BinaryInputHandle( InputStream reader )
@ -45,16 +48,46 @@ public class BinaryInputHandle extends HandleGeneric
if( args.length > 0 && args[ 0 ] != null ) if( args.length > 0 && args[ 0 ] != null )
{ {
int count = getInt( args, 0 ); int count = getInt( args, 0 );
if( count <= 0 || count >= 1024 * 16 ) if( count < 0 )
{ {
throw new LuaException( "Count out of range" ); // Whilst this may seem absurd to allow reading 0 bytes, PUC Lua it so
// it seems best to remain somewhat consistent.
throw new LuaException( "Cannot read a negative number of bytes" );
} }
else if( count <= BUFFER_SIZE )
{
// If we've got a small count, then allocate that and read it.
byte[] bytes = new byte[ count ];
int read = m_stream.read( bytes );
byte[] bytes = new byte[ count ]; if( read < 0 ) return null;
count = m_stream.read( bytes ); if( read < count ) bytes = Arrays.copyOf( bytes, read );
if( count < 0 ) return null; return new Object[] { bytes };
if( count < bytes.length ) bytes = Arrays.copyOf( bytes, count ); }
return new Object[] { bytes }; else
{
byte[] buffer = new byte[ BUFFER_SIZE ];
// Read the initial set of bytes, failing if none are read.
int read = m_stream.read( buffer, 0, Math.min( buffer.length, count ) );
if( read == -1 ) return null;
ByteArrayOutputStream out = new ByteArrayOutputStream( read );
count -= read;
out.write( buffer, 0, read );
// Otherwise read until we either reach the limit or we no longer consume
// the full buffer.
while( read >= buffer.length && count > 0 )
{
read = m_stream.read( buffer, 0, Math.min( BUFFER_SIZE, count ) );
if( read == -1 ) break;
count -= read;
out.write( buffer, 0, read );
}
return new Object[] { out.toByteArray() };
}
} }
else else
{ {

View File

@ -6,10 +6,12 @@ import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.*; import java.io.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*; import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
public class EncodedInputHandle extends HandleGeneric public class EncodedInputHandle extends HandleGeneric
{ {
private static final int BUFFER_SIZE = 8192;
private final BufferedReader m_reader; private final BufferedReader m_reader;
public EncodedInputHandle( BufferedReader reader ) public EncodedInputHandle( BufferedReader reader )
@ -111,15 +113,45 @@ public class EncodedInputHandle extends HandleGeneric
try try
{ {
int count = optInt( args, 0, 1 ); int count = optInt( args, 0, 1 );
if( count <= 0 || count >= 1024 * 16 ) if( count < 0 )
{ {
throw new LuaException( "Count out of range" ); // Whilst this may seem absurd to allow reading 0 characters, PUC Lua it so
// it seems best to remain somewhat consistent.
throw new LuaException( "Cannot read a negative number of characters" );
}
else if( count <= BUFFER_SIZE )
{
// If we've got a small count, then allocate that and read it.
char[] chars = new char[ count ];
int read = m_reader.read( chars );
return read < 0 ? null : new Object[] { new String( chars, 0, read ) };
}
else
{
// If we've got a large count, read in bunches of 8192.
char[] buffer = new char[ BUFFER_SIZE ];
// Read the initial set of characters, failing if none are read.
int read = m_reader.read( buffer, 0, Math.min( buffer.length, count ) );
if( read == -1 ) return null;
StringBuilder out = new StringBuilder( read );
count -= read;
out.append( buffer, 0, read );
// Otherwise read until we either reach the limit or we no longer consume
// the full buffer.
while( read >= BUFFER_SIZE && count > 0 )
{
read = m_reader.read( buffer, 0, Math.min( BUFFER_SIZE, count ) );
if( read == -1 ) break;
count -= read;
out.append( buffer, 0, read );
}
return new Object[] { out.toString() };
} }
char[] bytes = new char[ count ];
count = m_reader.read( bytes );
if( count < 0 ) return null;
String str = new String( bytes, 0, count );
return new Object[] { str };
} }
catch( IOException e ) catch( IOException e )
{ {