mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 19:20:29 +00:00
Refactor the filesystem and HTTP code
- Move the encoding/decoding from the Filesystem implementation to the individual handles. - Move each handle into an core.apis.handles package from the main fs API. - Move the HTTP response to inherit from these handles. - Allow binary handles' read function to accept a number, specifying how many characters to read - these will be returned as a Lua string. - Add readAll to binary handles - Allow binary handles' write function to accept a string which is decoded into the individual bytes. - Add "binary" argument to http.request and friends in order to return a binary handle. - Ensure file handles are open when reading from/writing to them. - Return the error message when opening a file fails.
This commit is contained in:
parent
2fd01b2adf
commit
6ccffe9742
@ -7,15 +7,17 @@
|
||||
package dan200.computercraft.core.apis;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.ILuaObject;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.core.apis.handles.BinaryInputHandle;
|
||||
import dan200.computercraft.core.apis.handles.BinaryOutputHandle;
|
||||
import dan200.computercraft.core.apis.handles.EncodedInputHandle;
|
||||
import dan200.computercraft.core.apis.handles.EncodedOutputHandle;
|
||||
import dan200.computercraft.core.filesystem.FileSystem;
|
||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||
import dan200.computercraft.core.filesystem.IMountedFileBinary;
|
||||
import dan200.computercraft.core.filesystem.IMountedFileNormal;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -259,33 +261,33 @@ public class FSAPI implements ILuaAPI
|
||||
try {
|
||||
if( mode.equals( "r" ) ) {
|
||||
// Open the file for reading, then create a wrapper around the reader
|
||||
IMountedFileNormal reader = m_fileSystem.openForRead( path );
|
||||
return wrapBufferedReader( reader );
|
||||
InputStream reader = m_fileSystem.openForRead( path );
|
||||
return new Object[] { new EncodedInputHandle( reader ) };
|
||||
|
||||
} else if( mode.equals( "w" ) ) {
|
||||
// Open the file for writing, then create a wrapper around the writer
|
||||
IMountedFileNormal writer = m_fileSystem.openForWrite( path, false );
|
||||
return wrapBufferedWriter( writer );
|
||||
OutputStream writer = m_fileSystem.openForWrite( path, false );
|
||||
return new Object[] { new EncodedOutputHandle( writer ) };
|
||||
|
||||
} else if( mode.equals( "a" ) ) {
|
||||
// Open the file for appending, then create a wrapper around the writer
|
||||
IMountedFileNormal writer = m_fileSystem.openForWrite( path, true );
|
||||
return wrapBufferedWriter( writer );
|
||||
OutputStream writer = m_fileSystem.openForWrite( path, true );
|
||||
return new Object[] { new EncodedOutputHandle( writer ) };
|
||||
|
||||
} else if( mode.equals( "rb" ) ) {
|
||||
// Open the file for binary reading, then create a wrapper around the reader
|
||||
IMountedFileBinary reader = m_fileSystem.openForBinaryRead( path );
|
||||
return wrapInputStream( reader );
|
||||
InputStream reader = m_fileSystem.openForRead( path );
|
||||
return new Object[] { new BinaryInputHandle( reader ) };
|
||||
|
||||
} else if( mode.equals( "wb" ) ) {
|
||||
// Open the file for binary writing, then create a wrapper around the writer
|
||||
IMountedFileBinary writer = m_fileSystem.openForBinaryWrite( path, false );
|
||||
return wrapOutputStream( writer );
|
||||
OutputStream writer = m_fileSystem.openForWrite( path, false );
|
||||
return new Object[] { new BinaryOutputHandle( writer ) };
|
||||
|
||||
} else if( mode.equals( "ab" ) ) {
|
||||
// Open the file for binary appending, then create a wrapper around the reader
|
||||
IMountedFileBinary writer = m_fileSystem.openForBinaryWrite( path, true );
|
||||
return wrapOutputStream( writer );
|
||||
OutputStream writer = m_fileSystem.openForWrite( path, true );
|
||||
return new Object[] { new BinaryOutputHandle( writer ) };
|
||||
|
||||
} else {
|
||||
throw new LuaException( "Unsupported mode" );
|
||||
@ -368,288 +370,4 @@ public class FSAPI implements ILuaAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] wrapBufferedReader( final IMountedFileNormal reader )
|
||||
{
|
||||
return new Object[] { new ILuaObject() {
|
||||
private boolean open = true;
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"readLine",
|
||||
"readAll",
|
||||
"close"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// readLine
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
try {
|
||||
String line = reader.readLine();
|
||||
if( line != null ) {
|
||||
return new Object[] { line };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// readAll
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
try {
|
||||
StringBuilder result = new StringBuilder( "" );
|
||||
String line = reader.readLine();
|
||||
while( line != null ) {
|
||||
result.append( line );
|
||||
line = reader.readLine();
|
||||
if( line != null ) {
|
||||
result.append( "\n" );
|
||||
}
|
||||
}
|
||||
return new Object[] { result.toString() };
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// close
|
||||
try {
|
||||
reader.close();
|
||||
open = false;
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} };
|
||||
}
|
||||
|
||||
private static Object[] wrapBufferedWriter( final IMountedFileNormal writer )
|
||||
{
|
||||
return new Object[] { new ILuaObject() {
|
||||
private boolean open = true;
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"write",
|
||||
"writeLine",
|
||||
"close",
|
||||
"flush"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// write
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
String text;
|
||||
if( args.length > 0 && args[0] != null ) {
|
||||
text = args[0].toString();
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
try {
|
||||
writer.write( text, 0, text.length(), false );
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
throw new LuaException( e.getMessage() );
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// writeLine
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
|
||||
String text;
|
||||
if( args.length > 0 && args[0] != null ) {
|
||||
text = args[0].toString();
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
try {
|
||||
writer.write( text, 0, text.length(), true );
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
throw new LuaException( e.getMessage() );
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// close
|
||||
try {
|
||||
writer.close();
|
||||
open = false;
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
try {
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
writer.flush();
|
||||
return null;
|
||||
} catch ( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert( false );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} };
|
||||
}
|
||||
|
||||
private static Object[] wrapInputStream( final IMountedFileBinary reader )
|
||||
{
|
||||
|
||||
return new Object[] { new ILuaObject() {
|
||||
private boolean open = true;
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames() {
|
||||
return new String[] {
|
||||
"read",
|
||||
"close"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args) throws LuaException {
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// read
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
try {
|
||||
int b = reader.read();
|
||||
if( b != -1 ) {
|
||||
return new Object[] { b };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
//close
|
||||
try {
|
||||
reader.close();
|
||||
open = false;
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert( false );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
private static Object[] wrapOutputStream( final IMountedFileBinary writer )
|
||||
{
|
||||
|
||||
return new Object[] { new ILuaObject() {
|
||||
private boolean open = true;
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames() {
|
||||
return new String[] {
|
||||
"write",
|
||||
"close",
|
||||
"flush"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args) throws LuaException {
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// write
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
try {
|
||||
if( args.length > 0 && args[0] instanceof Number )
|
||||
{
|
||||
int number = ((Number)args[0]).intValue();
|
||||
writer.write( number );
|
||||
}
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
throw new LuaException(e.getMessage());
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
//close
|
||||
try {
|
||||
writer.close();
|
||||
open = false;
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if( !open ) throw new LuaException( "attempt to use a closed file" );
|
||||
try {
|
||||
writer.flush();
|
||||
return null;
|
||||
} catch ( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert( false );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,11 @@ package dan200.computercraft.core.apis;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.ILuaObject;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.core.apis.handles.BinaryInputHandle;
|
||||
import dan200.computercraft.core.apis.handles.EncodedInputHandle;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class HTTPAPI implements ILuaAPI
|
||||
@ -52,15 +53,21 @@ public class HTTPAPI implements ILuaAPI
|
||||
final String url = h.getURL();
|
||||
if( h.wasSuccessful() ) {
|
||||
// Queue the "http_success" event
|
||||
final BufferedReader contents = h.getContents();
|
||||
final Object result = wrapBufferedReader( contents, h.getResponseCode(), h.getResponseHeaders() );
|
||||
InputStream contents = h.getContents();
|
||||
Object result = wrapStream(
|
||||
h.isBinary() ? new BinaryInputHandle( contents ) : new EncodedInputHandle( contents, h.getEncoding() ),
|
||||
h.getResponseCode(), h.getResponseHeaders()
|
||||
);
|
||||
m_apiEnvironment.queueEvent( "http_success", new Object[] { url, result } );
|
||||
} else {
|
||||
// Queue the "http_failure" event
|
||||
BufferedReader contents = h.getContents();
|
||||
InputStream contents = h.getContents();
|
||||
Object result = null;
|
||||
if( contents != null ) {
|
||||
result = wrapBufferedReader( contents, h.getResponseCode(), h.getResponseHeaders() );
|
||||
result = wrapStream(
|
||||
h.isBinary() ? new BinaryInputHandle( contents ) : new EncodedInputHandle( contents, h.getEncoding() ),
|
||||
h.getResponseCode(), h.getResponseHeaders()
|
||||
);
|
||||
}
|
||||
m_apiEnvironment.queueEvent( "http_failure", new Object[]{ url, "Could not connect", result } );
|
||||
}
|
||||
@ -69,80 +76,40 @@ public class HTTPAPI implements ILuaAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ILuaObject wrapBufferedReader( final BufferedReader reader, final int responseCode, final Map<String, String> responseHeaders )
|
||||
|
||||
private static ILuaObject wrapStream( final ILuaObject reader, final int responseCode, final Map<String, String> responseHeaders )
|
||||
{
|
||||
return new ILuaObject() {
|
||||
private boolean open = true;
|
||||
String[] oldMethods = reader.getMethodNames();
|
||||
final int methodOffset = oldMethods.length;
|
||||
|
||||
final String[] newMethods = Arrays.copyOf( oldMethods, oldMethods.length + 2 );
|
||||
newMethods[ methodOffset + 0 ] = "getResponseCode";
|
||||
newMethods[ methodOffset + 1 ] = "getResponseHeaders";
|
||||
|
||||
return new ILuaObject()
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"readLine",
|
||||
"readAll",
|
||||
"close",
|
||||
"getResponseCode",
|
||||
"getResponseHeaders",
|
||||
};
|
||||
return newMethods;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch( method )
|
||||
if( method < methodOffset )
|
||||
{
|
||||
return reader.callMethod( context, method, args );
|
||||
}
|
||||
switch( method - methodOffset )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// readLine
|
||||
if( !open ) throw new LuaException( "attempt to use a closed response" );
|
||||
try {
|
||||
String line = reader.readLine();
|
||||
if( line != null ) {
|
||||
return new Object[] { line };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// readAll
|
||||
if( !open ) throw new LuaException( "attempt to use a closed response" );
|
||||
try {
|
||||
StringBuilder result = new StringBuilder( "" );
|
||||
String line = reader.readLine();
|
||||
while( line != null ) {
|
||||
result.append( line );
|
||||
line = reader.readLine();
|
||||
if( line != null ) {
|
||||
result.append( "\n" );
|
||||
}
|
||||
}
|
||||
return new Object[] { result.toString() };
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// close
|
||||
try {
|
||||
reader.close();
|
||||
open = false;
|
||||
return null;
|
||||
} catch( IOException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// getResponseCode
|
||||
return new Object[] { responseCode };
|
||||
}
|
||||
case 4:
|
||||
case 1:
|
||||
{
|
||||
// getResponseHeaders
|
||||
return new Object[] { responseHeaders };
|
||||
@ -216,11 +183,18 @@ public class HTTPAPI implements ILuaAPI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get binary
|
||||
boolean binary = false;
|
||||
if( args.length >= 4 )
|
||||
{
|
||||
binary = args[ 3 ] != null && !args[ 3 ].equals( Boolean.FALSE );
|
||||
}
|
||||
|
||||
// Make the request
|
||||
try
|
||||
{
|
||||
HTTPRequest request = new HTTPRequest( urlString, postString, headers );
|
||||
HTTPRequest request = new HTTPRequest( urlString, postString, headers, binary );
|
||||
synchronized( m_httpRequests )
|
||||
{
|
||||
m_httpRequests.add( request );
|
||||
|
@ -7,6 +7,7 @@
|
||||
package dan200.computercraft.core.apis;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
|
||||
import java.io.*;
|
||||
@ -60,11 +61,12 @@ public class HTTPRequest
|
||||
return url;
|
||||
}
|
||||
|
||||
public HTTPRequest( String url, final String postText, final Map<String, String> headers ) throws HTTPRequestException
|
||||
public HTTPRequest( String url, final String postText, final Map<String, String> headers, boolean binary ) throws HTTPRequestException
|
||||
{
|
||||
// Parse the URL
|
||||
m_urlString = url;
|
||||
m_url = checkURL( m_urlString );
|
||||
m_binary = binary;
|
||||
|
||||
// Start the thread
|
||||
m_cancelled = false;
|
||||
@ -136,54 +138,10 @@ public class HTTPRequest
|
||||
is = connection.getErrorStream();
|
||||
responseSuccess = false;
|
||||
}
|
||||
InputStreamReader isr;
|
||||
try
|
||||
{
|
||||
String contentEncoding = connection.getContentEncoding();
|
||||
if( contentEncoding != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
isr = new InputStreamReader( is, contentEncoding );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
isr = new InputStreamReader( is, "UTF-8" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isr = new InputStreamReader( is, "UTF-8" );
|
||||
}
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
isr = new InputStreamReader( is );
|
||||
}
|
||||
|
||||
// Download the contents
|
||||
BufferedReader reader = new BufferedReader( isr );
|
||||
StringBuilder result = new StringBuilder();
|
||||
while( true )
|
||||
{
|
||||
synchronized( m_lock )
|
||||
{
|
||||
if( m_cancelled )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String line = reader.readLine();
|
||||
if( line == null )
|
||||
{
|
||||
break;
|
||||
}
|
||||
result.append( line );
|
||||
result.append( '\n' );
|
||||
}
|
||||
reader.close();
|
||||
|
||||
|
||||
byte[] result = ByteStreams.toByteArray( is );
|
||||
is.close();
|
||||
|
||||
synchronized( m_lock )
|
||||
{
|
||||
if( m_cancelled )
|
||||
@ -198,8 +156,9 @@ public class HTTPRequest
|
||||
// We completed
|
||||
m_complete = true;
|
||||
m_success = responseSuccess;
|
||||
m_result = result.toString();
|
||||
m_result = result;
|
||||
m_responseCode = connection.getResponseCode();
|
||||
m_encoding = connection.getContentEncoding();
|
||||
|
||||
Joiner joiner = Joiner.on( ',' );
|
||||
Map<String, String> headers = m_responseHeaders = new HashMap<String, String>();
|
||||
@ -264,20 +223,29 @@ public class HTTPRequest
|
||||
return m_success;
|
||||
}
|
||||
}
|
||||
|
||||
public BufferedReader getContents()
|
||||
|
||||
public boolean isBinary()
|
||||
{
|
||||
String result;
|
||||
return m_binary;
|
||||
}
|
||||
|
||||
public InputStream getContents()
|
||||
{
|
||||
byte[] result;
|
||||
synchronized(m_lock) {
|
||||
result = m_result;
|
||||
}
|
||||
|
||||
if( result != null ) {
|
||||
return new BufferedReader( new StringReader( result ) );
|
||||
return new ByteArrayInputStream( result );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return m_encoding;
|
||||
}
|
||||
|
||||
private final Object m_lock = new Object();
|
||||
private final URL m_url;
|
||||
private final String m_urlString;
|
||||
@ -285,7 +253,9 @@ public class HTTPRequest
|
||||
private boolean m_complete;
|
||||
private boolean m_cancelled;
|
||||
private boolean m_success;
|
||||
private String m_result;
|
||||
private String m_encoding;
|
||||
private byte[] m_result;
|
||||
private boolean m_binary;
|
||||
private int m_responseCode;
|
||||
private Map<String, String> m_responseHeaders;
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BinaryInputHandle extends HandleGeneric
|
||||
{
|
||||
private final InputStream m_stream;
|
||||
|
||||
public BinaryInputHandle( InputStream reader )
|
||||
{
|
||||
super( reader );
|
||||
this.m_stream = reader;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"read",
|
||||
"readAll",
|
||||
"close",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
// read
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
if( args.length > 0 && args[ 0 ] != null )
|
||||
{
|
||||
if( !(args[ 0 ] instanceof Number) )
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
|
||||
int count = ((Number) args[ 0 ]).intValue();
|
||||
|
||||
if( count <= 0 || count >= 1024 * 16 )
|
||||
{
|
||||
throw new LuaException( "Count out of range" );
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[ count ];
|
||||
count = m_stream.read( bytes );
|
||||
if( count < 0 ) return null;
|
||||
if( count < bytes.length ) bytes = Arrays.copyOf( bytes, count );
|
||||
return new Object[] { bytes };
|
||||
}
|
||||
else
|
||||
{
|
||||
int b = m_stream.read();
|
||||
return b == -1 ? null : new Object[] { b };
|
||||
}
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
// readAll
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
byte[] out = ByteStreams.toByteArray( m_stream );
|
||||
return out == null ? null : new Object[] { out };
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
//close
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.shared.util.StringUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BinaryOutputHandle extends HandleGeneric
|
||||
{
|
||||
private final OutputStream m_writer;
|
||||
|
||||
public BinaryOutputHandle( OutputStream writer )
|
||||
{
|
||||
super( writer );
|
||||
this.m_writer = writer;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"write",
|
||||
"flush",
|
||||
"close",
|
||||
};
|
||||
}
|
||||
|
||||
@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();
|
||||
m_writer.write( number );
|
||||
}
|
||||
else if( args.length > 0 && args[ 0 ] instanceof String )
|
||||
{
|
||||
String value = (String) args[ 0 ];
|
||||
m_writer.write( StringUtil.encodeString( value ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LuaException( "Expected number" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
throw new LuaException( e.getMessage() );
|
||||
}
|
||||
case 1:
|
||||
// flush
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
m_writer.flush();
|
||||
return null;
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
//close
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.*;
|
||||
|
||||
public class EncodedInputHandle extends HandleGeneric
|
||||
{
|
||||
private final BufferedReader m_reader;
|
||||
|
||||
public EncodedInputHandle( BufferedReader reader )
|
||||
{
|
||||
super( reader );
|
||||
this.m_reader = reader;
|
||||
}
|
||||
|
||||
public EncodedInputHandle( InputStream stream )
|
||||
{
|
||||
this( stream, "UTF-8" );
|
||||
}
|
||||
|
||||
public EncodedInputHandle( InputStream stream, String encoding )
|
||||
{
|
||||
super( stream );
|
||||
if( encoding == null ) encoding = "UTF-8";
|
||||
InputStreamReader streamReader;
|
||||
try
|
||||
{
|
||||
streamReader = new InputStreamReader( stream, encoding );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
streamReader = new InputStreamReader( stream );
|
||||
}
|
||||
this.m_reader = new BufferedReader( streamReader );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"readLine",
|
||||
"readAll",
|
||||
"close",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
// readLine
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
String line = m_reader.readLine();
|
||||
if( line != null )
|
||||
{
|
||||
return new Object[] { line };
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 1:
|
||||
// readAll
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
StringBuilder result = new StringBuilder( "" );
|
||||
String line = m_reader.readLine();
|
||||
while( line != null )
|
||||
{
|
||||
result.append( line );
|
||||
line = m_reader.readLine();
|
||||
if( line != null )
|
||||
{
|
||||
result.append( "\n" );
|
||||
}
|
||||
}
|
||||
return new Object[] { result.toString() };
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 2:
|
||||
// close
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.*;
|
||||
|
||||
public class EncodedOutputHandle extends HandleGeneric
|
||||
{
|
||||
private final BufferedWriter m_writer;
|
||||
|
||||
public EncodedOutputHandle( BufferedWriter writer )
|
||||
{
|
||||
super( writer );
|
||||
this.m_writer = writer;
|
||||
}
|
||||
|
||||
public EncodedOutputHandle( OutputStream stream )
|
||||
{
|
||||
this( stream, "UTF-8" );
|
||||
}
|
||||
|
||||
public EncodedOutputHandle( OutputStream stream, String encoding )
|
||||
{
|
||||
super( stream );
|
||||
if( encoding == null ) encoding = "UTF-8";
|
||||
OutputStreamWriter streamWriter;
|
||||
try
|
||||
{
|
||||
streamWriter = new OutputStreamWriter( stream, encoding );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
streamWriter = new OutputStreamWriter( stream );
|
||||
}
|
||||
this.m_writer = new BufferedWriter( streamWriter );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"write",
|
||||
"writeLine",
|
||||
"flush",
|
||||
"close",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// write
|
||||
checkOpen();
|
||||
String text;
|
||||
if( args.length > 0 && args[ 0 ] != null )
|
||||
{
|
||||
text = args[ 0 ].toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
try
|
||||
{
|
||||
m_writer.write( text, 0, text.length() );
|
||||
return null;
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
throw new LuaException( e.getMessage() );
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// writeLine
|
||||
checkOpen();
|
||||
String text;
|
||||
if( args.length > 0 && args[ 0 ] != null )
|
||||
{
|
||||
text = args[ 0 ].toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
try
|
||||
{
|
||||
m_writer.write( text, 0, text.length() );
|
||||
m_writer.newLine();
|
||||
return null;
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
throw new LuaException( e.getMessage() );
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
// flush
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
m_writer.flush();
|
||||
return null;
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case 3:
|
||||
// close
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package dan200.computercraft.core.apis.handles;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaObject;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class HandleGeneric implements ILuaObject
|
||||
{
|
||||
protected final Closeable m_closable;
|
||||
protected boolean m_open = true;
|
||||
|
||||
public HandleGeneric( Closeable m_closable )
|
||||
{
|
||||
this.m_closable = m_closable;
|
||||
}
|
||||
|
||||
protected void checkOpen() throws LuaException
|
||||
{
|
||||
if( !m_open ) throw new LuaException( "attempt to use a closed file" );
|
||||
}
|
||||
|
||||
protected void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_closable.close();
|
||||
m_open = false;
|
||||
}
|
||||
catch( IOException ignored )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ package dan200.computercraft.core.filesystem;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.filesystem.IMount;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@ -291,7 +292,7 @@ public class FileSystem
|
||||
}
|
||||
|
||||
private final Map<String, MountWrapper> m_mounts = new HashMap<String, MountWrapper>();
|
||||
private final Set<IMountedFile> m_openFiles = Collections.newSetFromMap( new WeakHashMap<IMountedFile, Boolean>() );
|
||||
private final Set<Closeable> m_openFiles = Collections.newSetFromMap( new WeakHashMap<Closeable, Boolean>() );
|
||||
|
||||
public FileSystem( String rootLabel, IMount rootMount ) throws FileSystemException
|
||||
{
|
||||
@ -308,7 +309,7 @@ public class FileSystem
|
||||
// Close all dangling open files
|
||||
synchronized( m_openFiles )
|
||||
{
|
||||
for(IMountedFile file : m_openFiles)
|
||||
for( Closeable file : m_openFiles )
|
||||
{
|
||||
try {
|
||||
file.close();
|
||||
@ -647,7 +648,7 @@ public class FileSystem
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized <T extends IMountedFile> T openFile(T file, Closeable handle) throws FileSystemException
|
||||
private synchronized <T> T openFile( T file, Closeable handle ) throws FileSystemException
|
||||
{
|
||||
synchronized( m_openFiles )
|
||||
{
|
||||
@ -665,199 +666,44 @@ public class FileSystem
|
||||
throw new FileSystemException("Too many files already open");
|
||||
}
|
||||
|
||||
m_openFiles.add( file );
|
||||
m_openFiles.add( handle );
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void closeFile( IMountedFile file, Closeable handle ) throws IOException
|
||||
private synchronized void closeFile( Closeable handle ) throws IOException
|
||||
{
|
||||
synchronized( m_openFiles )
|
||||
{
|
||||
m_openFiles.remove( file );
|
||||
if( handle != null )
|
||||
{
|
||||
handle.close();
|
||||
}
|
||||
m_openFiles.remove( handle );
|
||||
handle.close();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized IMountedFileNormal openForRead( String path ) throws FileSystemException
|
||||
public synchronized InputStream openForRead( String path ) throws FileSystemException
|
||||
{
|
||||
path = sanitizePath ( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
InputStream stream = mount.openForRead( path );
|
||||
if( stream != null )
|
||||
{
|
||||
InputStreamReader isr;
|
||||
try
|
||||
{
|
||||
isr = new InputStreamReader( stream, "UTF-8" );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
isr = new InputStreamReader( stream );
|
||||
}
|
||||
final BufferedReader reader = new BufferedReader( isr );
|
||||
IMountedFileNormal file = new IMountedFileNormal()
|
||||
{
|
||||
@Override
|
||||
public String readLine() throws IOException
|
||||
{
|
||||
return reader.readLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String s, int off, int len, boolean newLine) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
closeFile( this, reader );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return openFile( file, reader );
|
||||
return openFile( new ClosingInputStream( stream ), stream );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized IMountedFileNormal openForWrite( String path, boolean append ) throws FileSystemException
|
||||
|
||||
public synchronized OutputStream openForWrite( String path, boolean append ) throws FileSystemException
|
||||
{
|
||||
path = sanitizePath ( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
OutputStream stream = append ? mount.openForAppend( path ) : mount.openForWrite( path );
|
||||
if( stream != null )
|
||||
{
|
||||
OutputStreamWriter osw;
|
||||
try
|
||||
{
|
||||
osw = new OutputStreamWriter( stream, "UTF-8" );
|
||||
}
|
||||
catch( UnsupportedEncodingException e )
|
||||
{
|
||||
osw = new OutputStreamWriter( stream );
|
||||
}
|
||||
final BufferedWriter writer = new BufferedWriter( osw );
|
||||
IMountedFileNormal file = new IMountedFileNormal()
|
||||
{
|
||||
@Override
|
||||
public String readLine() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write( String s, int off, int len, boolean newLine ) throws IOException
|
||||
{
|
||||
writer.write( s, off, len );
|
||||
if( newLine )
|
||||
{
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
closeFile( this, writer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
writer.flush();
|
||||
}
|
||||
};
|
||||
return openFile( file, writer );
|
||||
return openFile( new ClosingOutputStream( stream ), stream );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized IMountedFileBinary openForBinaryRead( String path ) throws FileSystemException
|
||||
{
|
||||
path = sanitizePath ( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
final InputStream stream = mount.openForRead( path );
|
||||
if( stream != null )
|
||||
{
|
||||
IMountedFileBinary file = new IMountedFileBinary()
|
||||
{
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
return stream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int i) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
closeFile( this, stream );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return openFile( file, stream );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized IMountedFileBinary openForBinaryWrite( String path, boolean append ) throws FileSystemException
|
||||
{
|
||||
path = sanitizePath ( path );
|
||||
MountWrapper mount = getMount( path );
|
||||
final OutputStream stream = append ? mount.openForAppend( path ) : mount.openForWrite( path );
|
||||
if( stream != null )
|
||||
{
|
||||
IMountedFileBinary file = new IMountedFileBinary()
|
||||
{
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int i) throws IOException
|
||||
{
|
||||
stream.write(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
closeFile( this, stream );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
stream.flush();
|
||||
}
|
||||
};
|
||||
return openFile( file, stream );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getFreeSpace( String path ) throws FileSystemException
|
||||
{
|
||||
path = sanitizePath( path );
|
||||
@ -1010,4 +856,34 @@ public class FileSystem
|
||||
return local;
|
||||
}
|
||||
}
|
||||
|
||||
private class ClosingInputStream extends FilterInputStream
|
||||
{
|
||||
protected ClosingInputStream( InputStream in )
|
||||
{
|
||||
super( in );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
super.close();
|
||||
closeFile( in );
|
||||
}
|
||||
}
|
||||
|
||||
private class ClosingOutputStream extends FilterOutputStream
|
||||
{
|
||||
protected ClosingOutputStream( OutputStream out )
|
||||
{
|
||||
super( out );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
super.close();
|
||||
closeFile( out );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IMountedFile {
|
||||
void close() throws IOException;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IMountedFileBinary extends IMountedFile {
|
||||
int read() throws IOException;
|
||||
void write( int i ) throws IOException;
|
||||
void close() throws IOException;
|
||||
void flush() throws IOException;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IMountedFileNormal extends IMountedFile {
|
||||
String readLine() throws IOException;
|
||||
void write( String s, int off, int len, boolean newLine ) throws IOException;
|
||||
void close() throws IOException;
|
||||
void flush() throws IOException;
|
||||
}
|
@ -23,6 +23,7 @@ import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
@ -509,6 +510,11 @@ public class LuaJLuaMachine implements ILuaMachine
|
||||
String s = object.toString();
|
||||
return LuaValue.valueOf( s );
|
||||
}
|
||||
else if( object instanceof byte[] )
|
||||
{
|
||||
byte[] b = (byte[]) object;
|
||||
return LuaValue.valueOf( Arrays.copyOf( b, b.length ) );
|
||||
}
|
||||
else if( object instanceof Map )
|
||||
{
|
||||
// Table:
|
||||
|
@ -41,4 +41,17 @@ public class StringUtil
|
||||
{
|
||||
return net.minecraft.util.text.translation.I18n.translateToLocalFormatted( key, format );
|
||||
}
|
||||
|
||||
public static byte[] encodeString( String string )
|
||||
{
|
||||
byte[] chars = new byte[ string.length() ];
|
||||
|
||||
for( int i = 0; i < chars.length; ++i )
|
||||
{
|
||||
char c = string.charAt( i );
|
||||
chars[ i ] = c < 256 ? (byte) c : 63;
|
||||
}
|
||||
|
||||
return chars;
|
||||
}
|
||||
}
|
||||
|
@ -639,8 +639,8 @@ end
|
||||
if http then
|
||||
local nativeHTTPRequest = http.request
|
||||
|
||||
local function wrapRequest( _url, _post, _headers )
|
||||
local ok, err = nativeHTTPRequest( _url, _post, _headers )
|
||||
local function wrapRequest( _url, _post, _headers, _binary )
|
||||
local ok, err = nativeHTTPRequest( _url, _post, _headers, _binary )
|
||||
if ok then
|
||||
while true do
|
||||
local event, param1, param2, param3 = os.pullEvent()
|
||||
@ -654,16 +654,16 @@ if http then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
http.get = function( _url, _headers )
|
||||
return wrapRequest( _url, nil, _headers )
|
||||
http.get = function( _url, _headers, _binary)
|
||||
return wrapRequest( _url, nil, _headers, _binary)
|
||||
end
|
||||
|
||||
http.post = function( _url, _post, _headers )
|
||||
return wrapRequest( _url, _post or "", _headers )
|
||||
http.post = function( _url, _post, _headers, _binary)
|
||||
return wrapRequest( _url, _post or "", _headers, _binary)
|
||||
end
|
||||
|
||||
http.request = function( _url, _post, _headers )
|
||||
local ok, err = nativeHTTPRequest( _url, _post, _headers )
|
||||
http.request = function( _url, _post, _headers, _binary )
|
||||
local ok, err = nativeHTTPRequest( _url, _post, _headers, _binary )
|
||||
if not ok then
|
||||
os.queueEvent( "http_failure", _url, err )
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user