mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 13:42:59 +00:00 
			
		
		
		
	Fix binary handles reading in multiples of 8192
This commit is contained in:
		| @@ -1,3 +1,9 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
| package dan200.computercraft.core.apis.handles; | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
| import com.google.common.collect.ObjectArrays; | import com.google.common.collect.ObjectArrays; | ||||||
| @@ -80,26 +86,29 @@ public class BinaryReadableHandle extends HandleGeneric | |||||||
|                         } |                         } | ||||||
|                         else |                         else | ||||||
|                         { |                         { | ||||||
|  |                             // Read the initial set of characters, failing if none are read. | ||||||
|                             ByteBuffer buffer = ByteBuffer.allocate( BUFFER_SIZE ); |                             ByteBuffer buffer = ByteBuffer.allocate( BUFFER_SIZE ); | ||||||
|  |  | ||||||
|                             int read = m_reader.read( buffer ); |                             int read = m_reader.read( buffer ); | ||||||
|                             if( read < 0 ) return null; |                             if( read < 0 ) return null; | ||||||
|                             int totalRead = read; |  | ||||||
|  |  | ||||||
|                             // If we failed to read "enough" here, let's just abort |                             // If we failed to read "enough" here, let's just abort | ||||||
|                             if( totalRead >= count || read < BUFFER_SIZE ) |                             if( read >= count || read < BUFFER_SIZE ) | ||||||
|                             { |                             { | ||||||
|                                 return new Object[] { Arrays.copyOf( buffer.array(), read ) }; |                                 return new Object[] { Arrays.copyOf( buffer.array(), read ) }; | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|                             // Build up an array of ByteBuffers. Hopefully this means we can perform less allocation |                             // Build up an array of ByteBuffers. Hopefully this means we can perform less allocation | ||||||
|                             // than doubling up the buffer each time. |                             // than doubling up the buffer each time. | ||||||
|  |                             int totalRead = read; | ||||||
|                             List<ByteBuffer> parts = new ArrayList<>( 4 ); |                             List<ByteBuffer> parts = new ArrayList<>( 4 ); | ||||||
|                             parts.add( buffer ); |                             parts.add( buffer ); | ||||||
|                             while( totalRead < count && read >= BUFFER_SIZE ) |                             while( read >= BUFFER_SIZE && totalRead < count ) | ||||||
|                             { |                             { | ||||||
|                                 buffer = ByteBuffer.allocate( BUFFER_SIZE ); |                                 buffer = ByteBuffer.allocate( Math.min( BUFFER_SIZE, count - totalRead ) ); | ||||||
|                                 totalRead += read = m_reader.read( buffer ); |                                 read = m_reader.read( buffer ); | ||||||
|  |                                 if( read < 0 ) break; | ||||||
|  |  | ||||||
|  |                                 totalRead += read; | ||||||
|                                 parts.add( buffer ); |                                 parts.add( buffer ); | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,9 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
| package dan200.computercraft.core.apis.handles; | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
| import com.google.common.collect.ObjectArrays; | import com.google.common.collect.ObjectArrays; | ||||||
|   | |||||||
| @@ -1,3 +1,9 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
| package dan200.computercraft.core.apis.handles; | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
| import dan200.computercraft.api.lua.ILuaContext; | import dan200.computercraft.api.lua.ILuaContext; | ||||||
| @@ -102,6 +108,7 @@ public class EncodedReadableHandle extends HandleGeneric | |||||||
|                 close(); |                 close(); | ||||||
|                 return null; |                 return null; | ||||||
|             case 3: |             case 3: | ||||||
|  |                 // read | ||||||
|                 checkOpen(); |                 checkOpen(); | ||||||
|                 try |                 try | ||||||
|                 { |                 { | ||||||
| @@ -127,19 +134,20 @@ public class EncodedReadableHandle extends HandleGeneric | |||||||
|  |  | ||||||
|                         // Read the initial set of characters, failing if none are read. |                         // Read the initial set of characters, failing if none are read. | ||||||
|                         int read = m_reader.read( buffer, 0, Math.min( buffer.length, count ) ); |                         int read = m_reader.read( buffer, 0, Math.min( buffer.length, count ) ); | ||||||
|                         if( read == -1 ) return null; |                         if( read < 0 ) return null; | ||||||
|  |  | ||||||
|                         StringBuilder out = new StringBuilder( read ); |                         StringBuilder out = new StringBuilder( read ); | ||||||
|                         count -= read; |                         int totalRead = read; | ||||||
|                         out.append( buffer, 0, read ); |                         out.append( buffer, 0, read ); | ||||||
|  |  | ||||||
|                         // Otherwise read until we either reach the limit or we no longer consume |                         // Otherwise read until we either reach the limit or we no longer consume | ||||||
|                         // the full buffer. |                         // the full buffer. | ||||||
|                         while( read >= BUFFER_SIZE && count > 0 ) |                         while( read >= BUFFER_SIZE && totalRead < count ) | ||||||
|                         { |                         { | ||||||
|                             read = m_reader.read( buffer, 0, Math.min( BUFFER_SIZE, count ) ); |                             read = m_reader.read( buffer, 0, Math.min( BUFFER_SIZE, count - totalRead ) ); | ||||||
|                             if( read == -1 ) break; |                             if( read < 0 ) break; | ||||||
|                             count -= read; |  | ||||||
|  |                             totalRead += read; | ||||||
|                             out.append( buffer, 0, read ); |                             out.append( buffer, 0, read ); | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,9 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
| package dan200.computercraft.core.apis.handles; | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
| import dan200.computercraft.api.lua.ILuaContext; | import dan200.computercraft.api.lua.ILuaContext; | ||||||
|   | |||||||
| @@ -1,3 +1,9 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
| package dan200.computercraft.core.apis.handles; | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
| import dan200.computercraft.api.lua.ILuaObject; | import dan200.computercraft.api.lua.ILuaObject; | ||||||
|   | |||||||
| @@ -54,6 +54,17 @@ public class ObjectWrapper implements ILuaContext | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings( "unchecked" ) | ||||||
|  |     public <T> T callOf( String name, Object... args ) throws LuaException | ||||||
|  |     { | ||||||
|  |         return (T) call( name, args )[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public <T> T callOf( Class<T> klass, String name, Object... args ) throws LuaException | ||||||
|  |     { | ||||||
|  |         return klass.cast( call( name, args )[0] ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Nonnull |     @Nonnull | ||||||
|     @Override |     @Override | ||||||
|     public Object[] pullEvent( @Nullable String filter ) |     public Object[] pullEvent( @Nullable String filter ) | ||||||
|   | |||||||
| @@ -0,0 +1,68 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
|  | import dan200.computercraft.api.lua.LuaException; | ||||||
|  | import dan200.computercraft.core.apis.ObjectWrapper; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  |  | ||||||
|  | public class BinaryReadableHandleTest | ||||||
|  | { | ||||||
|  |     @Test | ||||||
|  |     public void testReadChar() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 5 ); | ||||||
|  |         assertEquals( 'A', (int) wrapper.callOf( Integer.class, "read" ) ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadShortComplete() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10 ); | ||||||
|  |         assertEquals( 5, wrapper.<byte[]>callOf( "read", 5 ).length ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadShortPartial() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 5 ); | ||||||
|  |         assertEquals( 5, wrapper.<byte[]>callOf( "read", 10 ).length ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongComplete() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10000 ); | ||||||
|  |         assertEquals( 9000, wrapper.<byte[]>callOf( "read", 9000 ).length ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongPartial() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10000 ); | ||||||
|  |         assertEquals( 10000, wrapper.<byte[]>callOf( "read", 11000 ).length ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongPartialSmaller() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 1000 ); | ||||||
|  |         assertEquals( 1000, wrapper.<byte[]>callOf( "read", 11000 ).length ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static ObjectWrapper fromLength( int length ) | ||||||
|  |     { | ||||||
|  |         byte[] input = new byte[length]; | ||||||
|  |         Arrays.fill( input, (byte) 'A' ); | ||||||
|  |         return new ObjectWrapper( new BinaryReadableHandle( new ArrayByteChannel( input ) ) ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of ComputerCraft - http://www.computercraft.info | ||||||
|  |  * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. | ||||||
|  |  * Send enquiries to dratcliffe@gmail.com | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package dan200.computercraft.core.apis.handles; | ||||||
|  |  | ||||||
|  | import dan200.computercraft.api.lua.LuaException; | ||||||
|  | import dan200.computercraft.core.apis.ObjectWrapper; | ||||||
|  | import org.junit.Test; | ||||||
|  |  | ||||||
|  | import java.io.BufferedReader; | ||||||
|  | import java.io.CharArrayReader; | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  |  | ||||||
|  | public class EncodedReadableHandleTest | ||||||
|  | { | ||||||
|  |     @Test | ||||||
|  |     public void testReadChar() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 5 ); | ||||||
|  |         assertEquals( "A", wrapper.callOf( "read" ) ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadShortComplete() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10 ); | ||||||
|  |         assertEquals( "AAAAA", wrapper.callOf( "read", 5 ) ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadShortPartial() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 5 ); | ||||||
|  |         assertEquals( "AAAAA", wrapper.callOf( "read", 10 ) ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongComplete() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10000 ); | ||||||
|  |         assertEquals( 9000, wrapper.<String>callOf( "read", 9000 ).length() ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongPartial() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 10000 ); | ||||||
|  |         assertEquals( 10000, wrapper.<String>callOf( "read", 11000 ).length() ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void testReadLongPartialSmaller() throws LuaException | ||||||
|  |     { | ||||||
|  |         ObjectWrapper wrapper = fromLength( 1000 ); | ||||||
|  |         assertEquals( 1000, wrapper.<String>callOf( "read", 11000 ).length() ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static ObjectWrapper fromLength( int length ) | ||||||
|  |     { | ||||||
|  |         char[] input = new char[length]; | ||||||
|  |         Arrays.fill( input, 'A' ); | ||||||
|  |         return new ObjectWrapper( new EncodedReadableHandle( new BufferedReader( new CharArrayReader( input ) ) ) ); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev