/*
* $Id: AnyInputStream.java,v 1.29 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.io;
import anvil.core.Any;
import anvil.core.AnyAbstractClass;
import anvil.core.AnyBinary;
import anvil.core.AnyString;
import anvil.core.AnyList;
import anvil.core.Array;
import anvil.core.Serialization;
import anvil.core.UnserializationException;
import anvil.script.Context;
import anvil.java.util.BindingEnumeration;
import anvil.java.io.GenericInputStream;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.IOException;
/// @class InputStream
///
/// Datatype representing an input stream of bytes.
///
/// @operator "enumeration *<b>this</b>"
/// Returns enumeration (of strings) that will read the stream
/// line-by-line.
///
public class AnyInputStream extends AnyAbstractClass
{
private GenericInputStream _input;
public AnyInputStream(InputStream input)
{
_input = new GenericInputStream(input);
}
public final anvil.script.ClassType classOf() {
return __class__;
}
public Object toObject()
{
return _input;
}
public BindingEnumeration enumeration()
{
return new InputStreamEnumeration(_input);
}
/// @method available
/// Returns number of bytes available from this stream
/// without blocking.
/// @synopsis int available()
/// @throws IOError If an I/O error occurs.
public Any m_available(Context context)
{
try {
return Any.create(_input.available());
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method close
/// Closes this input stream and releases any system resources associated with the stream.
/// @synopsis void close()
/// @throws IOError If an I/O error occurs.
public Any m_close(Context context)
{
try {
_input.close();
return this;
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method read
/// Reads bytes from stream.
/// @synopsis int read() ; Reads a single byte from stream.
/// @synopsis string read(int maxBytes) ; Reads upto given
/// amount of bytes from stream.
/// @return Byte read, or bytes read as string, or <code>null</code>
/// if end of stream has been reached.
/// @throws IOError If an I/O error occurs.
public static final Object[] p_read = new Object[] { null, "*maxBytes", null };
public Any m_read(Context context, Any max)
{
try {
if (max == null) {
int ch = _input.read();
if (ch == -1) {
return NULL;
} else {
return Any.create((char)ch);
}
} else {
int amount = max.toInt();
if (amount>1) {
return Any.create(_input.read(amount));
} else {
return NULL;
}
}
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method readBinary
/// Reads bytes from stream.
/// @synopsis int readBinary(binary bin)
/// @synopsis int readBinary(binary bin, int offset, int length)
/// @param array The binary into which the data is written
/// @param offset The start offset in binary
/// @param length The maximum number of bytes to read.
/// @return Number of bytes read, or -1 if end of stream has been
/// reached.
/// @throws IOError If an I/O error occurs.
public static final Object[] p_readBinary = new Object[] { null, "array", "*offset", null, "*length", null };
public Any m_readBinary(Context context, Any binary, Any offset_, Any length_)
{
if (!binary.isBinary()) {
throw context.BadParameter("First parameter it not binary");
}
byte[] array = binary.toBinary();
try {
int size = array.length;
int offset = 0;
int length = size;
if (offset_ != null) {
offset = offset_.toInt();
if (length_ != null) {
length = length_.toInt();
}
if (offset < 0) {
offset = 0;
}
if (offset >= size) {
return ZERO;
}
if (offset + length > size) {
length = size - offset;
}
}
return Any.create(_input.read(array, offset, length));
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method readLine
/// Reads single line from stream.
/// @synopsis string readLine()
/// @return Line read or, <code>null</code> if end of stream was
/// reached.
/// @throws IOError If an I/O error occurs.
public Any m_readLine(Context context)
{
try {
String buffer = _input.readLine();
return (buffer == null) ? NULL : new AnyString(buffer);
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method readLines
/// @synopsis list readLines() ;
/// Reads all available lines from stream
/// @synopsis list readLines(int maxLines) ;
/// Reads upto given amount of lines from stream.
/// @param maxLinex Maximum number of lines to return
/// @return Lines read as list of strings with linefeeds
/// stripped.
/// @throws IOError If an I/O error occurs.
public static final Object[] p_readLines = new Object[] { null, "*maxLines", new Integer(0) };
public Any m_readLines(Context context, int max)
{
try {
String buffer;
if (max > 0) {
Any[] list = new Any[max];
int index = 0;
while((max > 0) && (buffer = _input.readLine()) != null) {
list[index] = Any.create(buffer);
max--;
index++;
}
return new AnyList(list, index);
} else {
AnyList lines = new AnyList(new Any[8], 0);
while((buffer = _input.readLine()) != null) {
lines.append(Any.create(buffer));
}
return lines;
}
} catch (IOException e) {
throw context.exception(e);
}
}
/// @method readData
/// Reads serialized data from this stream.
/// @see anvil.lang.OutputStream.write
/// @synopsis object readData()
/// @return Unserialized data
/// @throws IOError If an I/O error occurs.
/// @throws CorruptedSerialization If serialized data is corrupted
public Any m_readData(Context context)
{
try {
return Serialization.unserialize(context, _input);
} catch (IOException e) {
throw context.exception(e);
} catch (UnserializationException e) {
throw context.CorruptedSerialization();
}
}
/// @method getColumnNumber
/// Gets the current column number of this stream.
/// Useful only with text content.
/// @synopsis int getColumnNumber()
public Any m_getColumnNumber()
{
return Any.create(_input.getColumnNumber());
}
/// @method getLineNumber
/// Gets the current line number of this stream.
/// Useful only with text content.
/// @synopsis int getLineNumber()
public Any m_getLineNumber()
{
return Any.create(_input.getLineNumber());
}
/// @method skip
/// Skips over some bytes in this stream.
/// @synopsis int skip(int amount)
/// @param amount Amount of bytes to skip
/// @return Amount of bytes skipped, or -1 if end of stream was reached
/// before any bytes were skipped.
/// @throws IOError If an I/O error occurs.
public static final Object[] p_skip = new Object[] { null, "amount" };
public Any m_skip(Context context, int amount)
{
try {
return Any.create(_input.skip(amount));
} catch (IOException e) {
throw context.exception(e);
}
}
public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("InputStream", AnyInputStream.class,
//DOC{{
""+
" @class InputStream\n" +
"\n" +
" Datatype representing an input stream of bytes.\n" +
"\n" +
" @operator \"enumeration *<b>this</b>\"\n" +
" Returns enumeration (of strings) that will read the stream\n" +
" line-by-line.\n" +
"\n" +
" @method available\n" +
" Returns number of bytes available from this stream\n" +
" without blocking.\n" +
" @synopsis int available()\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method close\n" +
" Closes this input stream and releases any system resources associated with the stream. \n" +
" @synopsis void close()\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method read\n" +
" Reads bytes from stream.\n" +
" @synopsis int read() ; Reads a single byte from stream.\n" +
" @synopsis string read(int maxBytes) ; Reads upto given\n" +
" amount of bytes from stream.\n" +
" @return Byte read, or bytes read as string, or <code>null</code>\n" +
" if end of stream has been reached.\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method readBinary\n" +
" Reads bytes from stream.\n" +
" @synopsis int readBinary(binary bin)\n" +
" @synopsis int readBinary(binary bin, int offset, int length)\n" +
" @param array The binary into which the data is written\n" +
" @param offset The start offset in binary\n" +
" @param length The maximum number of bytes to read.\n" +
" @return Number of bytes read, or -1 if end of stream has been\n" +
" reached.\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method readLine\n" +
" Reads single line from stream.\n" +
" @synopsis string readLine()\n" +
" @return Line read or, <code>null</code> if end of stream was\n" +
" reached.\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method readLines\n" +
" @synopsis list readLines() ; \n" +
" Reads all available lines from stream\n" +
" @synopsis list readLines(int maxLines) ; \n" +
" Reads upto given amount of lines from stream. \n" +
" @param maxLinex Maximum number of lines to return\n" +
" @return Lines read as list of strings with linefeeds\n" +
" stripped.\n" +
" @throws IOError If an I/O error occurs.\n" +
" @method readData\n" +
" Reads serialized data from this stream.\n" +
" @see anvil.lang.OutputStream.write\n" +
" @synopsis object readData()\n" +
" @return Unserialized data\n" +
" @throws IOError If an I/O error occurs.\n" +
" @throws CorruptedSerialization If serialized data is corrupted\n" +
" @method getColumnNumber\n" +
" Gets the current column number of this stream. \n" +
" Useful only with text content.\n" +
" @synopsis int getColumnNumber()\n" +
" @method getLineNumber\n" +
" Gets the current line number of this stream. \n" +
" Useful only with text content.\n" +
" @synopsis int getLineNumber()\n" +
" @method skip\n" +
" Skips over some bytes in this stream.\n" +
" @synopsis int skip(int amount)\n" +
" @param amount Amount of bytes to skip\n" +
" @return Amount of bytes skipped, or -1 if end of stream was reached\n" +
" before any bytes were skipped.\n" +
" @throws IOError If an I/O error occurs.\n"
//}}DOC
);
static {
IOModule.class.getName();
}
}