109 lines
3.5 KiB
Java
109 lines
3.5 KiB
Java
/*
|
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
* Send enquiries to dratcliffe@gmail.com
|
|
*/
|
|
|
|
package dan200.computercraft.core.apis.handles;
|
|
|
|
import com.google.common.collect.ObjectArrays;
|
|
import dan200.computercraft.api.lua.ILuaContext;
|
|
import dan200.computercraft.api.lua.LuaException;
|
|
import dan200.computercraft.core.apis.ArgumentHelper;
|
|
import dan200.computercraft.shared.util.StringUtil;
|
|
|
|
import javax.annotation.Nonnull;
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.channels.SeekableByteChannel;
|
|
import java.nio.channels.WritableByteChannel;
|
|
|
|
public class BinaryWritableHandle extends HandleGeneric
|
|
{
|
|
private static final String[] METHOD_NAMES = new String[] { "write", "flush", "close" };
|
|
private static final String[] METHOD_SEEK_NAMES = ObjectArrays.concat( METHOD_NAMES, new String[] { "seek" }, String.class );
|
|
|
|
private final WritableByteChannel m_writer;
|
|
private final SeekableByteChannel m_seekable;
|
|
private final ByteBuffer single = ByteBuffer.allocate( 1 );
|
|
|
|
public BinaryWritableHandle( WritableByteChannel channel, Closeable closeable )
|
|
{
|
|
super( closeable );
|
|
m_writer = channel;
|
|
m_seekable = asSeekable( channel );
|
|
}
|
|
|
|
public BinaryWritableHandle( WritableByteChannel channel )
|
|
{
|
|
this( channel, channel );
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String[] getMethodNames()
|
|
{
|
|
return m_seekable == null ? METHOD_NAMES : METHOD_SEEK_NAMES;
|
|
}
|
|
|
|
@Override
|
|
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
|
{
|
|
switch( method )
|
|
{
|
|
case 0: // write
|
|
checkOpen();
|
|
try
|
|
{
|
|
if( args.length > 0 && args[0] instanceof Number )
|
|
{
|
|
int number = ((Number) args[0]).intValue();
|
|
single.clear();
|
|
single.put( (byte) number );
|
|
single.flip();
|
|
|
|
m_writer.write( single );
|
|
}
|
|
else if( args.length > 0 && args[0] instanceof String )
|
|
{
|
|
String value = (String) args[0];
|
|
m_writer.write( ByteBuffer.wrap( StringUtil.encodeString( value ) ) );
|
|
}
|
|
else
|
|
{
|
|
throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[0] : null );
|
|
}
|
|
return null;
|
|
}
|
|
catch( IOException e )
|
|
{
|
|
throw new LuaException( e.getMessage() );
|
|
}
|
|
case 1: // flush
|
|
checkOpen();
|
|
try
|
|
{
|
|
// Technically this is not needed
|
|
if( m_writer instanceof FileChannel ) ((FileChannel) m_writer).force( false );
|
|
|
|
return null;
|
|
}
|
|
catch( IOException e )
|
|
{
|
|
return null;
|
|
}
|
|
case 2: // close
|
|
checkOpen();
|
|
close();
|
|
return null;
|
|
case 3: // seek
|
|
checkOpen();
|
|
return handleSeek( m_seekable, args );
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|