Initial revision

From-SVN: r102074
This commit is contained in:
Tom Tromey
2005-07-16 00:30:23 +00:00
parent 6f4434b39b
commit f911ba985a
4557 changed files with 1000262 additions and 0 deletions
@@ -0,0 +1,379 @@
/* BufferedInputStream.java -- An input stream that implements buffering
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This subclass of <code>FilterInputStream</code> buffers input from an
* underlying implementation to provide a possibly more efficient read
* mechanism. It maintains the buffer and buffer state in instance
* variables that are available to subclasses. The default buffer size
* of 2048 bytes can be overridden by the creator of the stream.
* <p>
* This class also implements mark/reset functionality. It is capable
* of remembering any number of input bytes, to the limits of
* system memory or the size of <code>Integer.MAX_VALUE</code>
* <p>
* Please note that this class does not properly handle character
* encodings. Consider using the <code>BufferedReader</code> class which
* does.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @author Jeroen Frijters (jeroen@frijters.net)
*/
public class BufferedInputStream extends FilterInputStream
{
/**
* This is the default buffer size
*/
private static final int DEFAULT_BUFFER_SIZE = 2048;
/**
* The buffer used for storing data from the underlying stream.
*/
protected byte[] buf;
/**
* The number of valid bytes currently in the buffer. It is also the index
* of the buffer position one byte past the end of the valid data.
*/
protected int count;
/**
* The index of the next character that will by read from the buffer.
* When <code>pos == count</code>, the buffer is empty.
*/
protected int pos;
/**
* The value of <code>pos</code> when the <code>mark()</code> method was
* called.
* This is set to -1 if there is no mark set.
*/
protected int markpos = -1;
/**
* This is the maximum number of bytes than can be read after a
* call to <code>mark()</code> before the mark can be discarded.
* After this may bytes are read, the <code>reset()</code> method
* may not be called successfully.
*/
protected int marklimit;
/**
* This is the initial buffer size. When the buffer is grown because
* of marking requirements, it will be grown by bufferSize increments.
* The underlying stream will be read in chunks of bufferSize.
*/
private final int bufferSize;
/**
* This method initializes a new <code>BufferedInputStream</code> that will
* read from the specified subordinate stream with a default buffer size
* of 2048 bytes
*
* @param in The subordinate stream to read from
*/
public BufferedInputStream(InputStream in)
{
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>BufferedInputStream</code> that will
* read from the specified subordinate stream with a buffer size that
* is specified by the caller.
*
* @param in The subordinate stream to read from
* @param size The buffer size to use
*
* @exception IllegalArgumentException when size is smaller then 1
*/
public BufferedInputStream(InputStream in, int size)
{
super(in);
if (size <= 0)
throw new IllegalArgumentException();
buf = new byte[size];
// initialize pos & count to bufferSize, to prevent refill from
// allocating a new buffer (if the caller starts out by calling mark()).
pos = count = bufferSize = size;
}
/**
* This method returns the number of bytes that can be read from this
* stream before a read can block. A return of 0 indicates that blocking
* might (or might not) occur on the very next read attempt.
* <p>
* The number of available bytes will be the number of read ahead bytes
* stored in the internal buffer plus the number of available bytes in
* the underlying stream.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public synchronized int available() throws IOException
{
return count - pos + super.available();
}
/**
* This method closes the underlying input stream and frees any
* resources associated with it. Sets <code>buf</code> to <code>null</code>.
*
* @exception IOException If an error occurs.
*/
public void close() throws IOException
{
// Free up the array memory.
buf = null;
pos = count = 0;
markpos = -1;
super.close();
}
/**
* This method marks a position in the input to which the stream can be
* "reset" by calling the <code>reset()</code> method. The parameter
* <code>readlimit</code> is the number of bytes that can be read from the
* stream after setting the mark before the mark becomes invalid. For
* example, if <code>mark()</code> is called with a read limit of 10, then
* when 11 bytes of data are read from the stream before the
* <code>reset()</code> method is called, then the mark is invalid and the
* stream object instance is not required to remember the mark.
* <p>
* Note that the number of bytes that can be remembered by this method
* can be greater than the size of the internal read buffer. It is also
* not dependent on the subordinate stream supporting mark/reset
* functionality.
*
* @param readlimit The number of bytes that can be read before the mark
* becomes invalid
*/
public synchronized void mark(int readlimit)
{
marklimit = readlimit;
markpos = pos;
}
/**
* This method returns <code>true</code> to indicate that this class
* supports mark/reset functionality.
*
* @return <code>true</code> to indicate that mark/reset functionality is
* supported
*
*/
public boolean markSupported()
{
return true;
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public synchronized int read() throws IOException
{
if (pos >= count && !refill())
return -1; // EOF
return buf[pos++] & 0xFF;
}
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>off</code>
* into the buffer and attempts to read <code>len</code> bytes. This method
* can return before reading the number of bytes requested, but it will try
* to read the requested number of bytes by repeatedly calling the underlying
* stream as long as available() for this stream continues to return a
* non-zero value (or until the requested number of bytes have been read).
* The actual number of bytes read is returned as an int. A -1 is returned
* to indicate the end of the stream.
* <p>
* This method will block until some data can be read.
*
* @param b The array into which the bytes read should be stored
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
* @exception IndexOutOfBoundsException when <code>off</code> or
* <code>len</code> are negative, or when <code>off + len</code>
* is larger then the size of <code>b</code>,
*/
public synchronized int read(byte[] b, int off, int len) throws IOException
{
if (off < 0 || len < 0 || b.length - off < len)
throw new IndexOutOfBoundsException();
if (len == 0)
return 0;
if (pos >= count && !refill())
return -1; // No bytes were read before EOF.
int totalBytesRead = Math.min(count - pos, len);
System.arraycopy(buf, pos, b, off, totalBytesRead);
pos += totalBytesRead;
off += totalBytesRead;
len -= totalBytesRead;
while (len > 0 && super.available() > 0 && refill())
{
int remain = Math.min(count - pos, len);
System.arraycopy(buf, pos, b, off, remain);
pos += remain;
off += remain;
len -= remain;
totalBytesRead += remain;
}
return totalBytesRead;
}
/**
* This method resets a stream to the point where the <code>mark()</code>
* method was called. Any bytes that were read after the mark point was
* set will be re-read during subsequent reads.
* <p>
* This method will throw an IOException if the number of bytes read from
* the stream since the call to <code>mark()</code> exceeds the mark limit
* passed when establishing the mark.
*
* @exception IOException If <code>mark()</code> was never called or more
* then <code>marklimit</code> bytes were read since the last
* call to <code>mark()</code>
*/
public synchronized void reset() throws IOException
{
if (markpos == -1)
throw new IOException(buf == null ? "Stream closed." : "Invalid mark.");
pos = markpos;
}
/**
* This method skips the specified number of bytes in the stream. It
* returns the actual number of bytes skipped, which may be less than the
* requested amount.
*
* @param n The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs
*/
public synchronized long skip(long n) throws IOException
{
if (buf == null)
throw new IOException("Stream closed.");
final long origN = n;
while (n > 0L)
{
if (pos >= count && !refill())
break;
int numread = (int) Math.min((long) (count - pos), n);
pos += numread;
n -= numread;
}
return origN - n;
}
/**
* Called to refill the buffer (when count is equal to pos).
*
* @return <code>true</code> when at least one additional byte was read
* into <code>buf</code>, <code>false</code> otherwise (at EOF).
*/
private boolean refill() throws IOException
{
if (buf == null)
throw new IOException("Stream closed.");
if (markpos == -1 || count - markpos >= marklimit)
{
markpos = -1;
pos = count = 0;
}
else
{
byte[] newbuf = buf;
if (markpos < bufferSize)
{
newbuf = new byte[count - markpos + bufferSize];
}
System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
buf = newbuf;
count -= markpos;
pos -= markpos;
markpos = 0;
}
int numread = super.read(buf, count, bufferSize);
if (numread <= 0) // EOF
return false;
count += numread;
return true;
}
}
@@ -0,0 +1,192 @@
/* BufferedOutputStream.java -- Buffer output into large blocks before writing
Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class accumulates bytes written in a buffer instead of immediately
* writing the data to the underlying output sink. The bytes are instead
* as one large block when the buffer is filled, or when the stream is
* closed or explicitly flushed. This mode operation can provide a more
* efficient mechanism for writing versus doing numerous small unbuffered
* writes.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class BufferedOutputStream extends FilterOutputStream
{
/**
* This is the default buffer size
*/
private static final int DEFAULT_BUFFER_SIZE = 512;
/**
* This is the internal byte array used for buffering output before
* writing it.
*/
protected byte[] buf;
/**
* This is the number of bytes that are currently in the buffer and
* are waiting to be written to the underlying stream. It always points to
* the index into the buffer where the next byte of data will be stored
*/
protected int count;
/**
* This method initializes a new <code>BufferedOutputStream</code> instance
* that will write to the specified subordinate <code>OutputStream</code>
* and which will use a default buffer size of 512 bytes.
*
* @param out The underlying <code>OutputStream</code> to write data to
*/
public BufferedOutputStream(OutputStream out)
{
this(out, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>BufferedOutputStream</code> instance
* that will write to the specified subordinate <code>OutputStream</code>
* and which will use the specified buffer size
*
* @param out The underlying <code>OutputStream</code> to write data to
* @param size The size of the internal buffer
*/
public BufferedOutputStream(OutputStream out, int size)
{
super(out);
buf = new byte[size];
}
/**
* This method causes any currently buffered bytes to be immediately
* written to the underlying output stream.
*
* @exception IOException If an error occurs
*/
public synchronized void flush() throws IOException
{
if (count == 0)
return;
out.write(buf, 0, count);
count = 0;
out.flush();
}
/**
* This method flushes any remaining buffered bytes then closes the
* underlying output stream. Any further attempts to write to this stream
* may throw an exception
*
public synchronized void close() throws IOException
{
flush();
out.close();
}
*/
/**
* This method runs when the object is garbage collected. It is
* responsible for ensuring that all buffered bytes are written and
* for closing the underlying stream.
*
* @exception IOException If an error occurs (ignored by the Java runtime)
*
protected void finalize() throws IOException
{
close();
}
*/
/**
* This method writes a single byte of data. This will be written to the
* buffer instead of the underlying data source. However, if the buffer
* is filled as a result of this write request, it will be flushed to the
* underlying output stream.
*
* @param b The byte of data to be written, passed as an int
*
* @exception IOException If an error occurs
*/
public synchronized void write(int b) throws IOException
{
if (count == buf.length)
flush();
buf[count] = (byte)(b & 0xFF);
++count;
}
/**
* This method writes <code>len</code> bytes from the byte array
* <code>buf</code> starting at position <code>offset</code> in the buffer.
* These bytes will be written to the internal buffer. However, if this
* write operation fills the buffer, the buffer will be flushed to the
* underlying output stream.
*
* @param buf The array of bytes to write.
* @param offset The index into the byte array to start writing from.
* @param len The number of bytes to write.
*
* @exception IOException If an error occurs
*/
public synchronized void write(byte[] buf, int offset, int len)
throws IOException
{
// Buffer can hold everything. Note that the case where LEN < 0
// is automatically handled by the downstream write.
if (len < (this.buf.length - count))
{
System.arraycopy(buf, offset, this.buf, count, len);
count += len;
}
else
{
// The write was too big. So flush the buffer and write the new
// bytes directly to the underlying stream, per the JDK 1.2
// docs.
flush();
out.write (buf, offset, len);
}
}
} // class BufferedOutputStream
@@ -0,0 +1,581 @@
/* BufferedReader.java
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This subclass of <code>FilterReader</code> buffers input from an
* underlying implementation to provide a possibly more efficient read
* mechanism. It maintains the buffer and buffer state in instance
* variables that are available to subclasses. The default buffer size
* of 8192 chars can be overridden by the creator of the stream.
* <p>
* This class also implements mark/reset functionality. It is capable
* of remembering any number of input chars, to the limits of
* system memory or the size of <code>Integer.MAX_VALUE</code>
*
* @author Per Bothner (bothner@cygnus.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class BufferedReader extends Reader
{
Reader in;
char[] buffer;
/* Index of current read position. Must be >= 0 and <= limit. */
/* There is a special case where pos may be equal to limit+1; this
* is used as an indicator that a readLine was done with a '\r' was
* the very last char in the buffer. Since we don't want to read-ahead
* and potentially block, we set pos this way to indicate the situation
* and deal with it later. Doing it this way rather than having a
* separate boolean field to indicate the condition has the advantage
* that it is self-clearing on things like mark/reset.
*/
int pos;
/* Limit of valid data in buffer. Must be >= pos and <= buffer.length. */
/* This can be < pos in the one special case described above. */
int limit;
/* The value -1 means there is no mark, or the mark has been invalidated.
Otherwise, markPos is the index in the buffer of the marked position.
Must be >= 0 and <= pos.
Note we do not explicitly store the read-limit.
The implicit read-limit is (buffer.length - markPos), which is
guaranteed to be >= the read-limit requested in the call to mark. */
int markPos = -1;
// The JCL book specifies the default buffer size as 8K characters.
// This is package-private because it is used by LineNumberReader.
static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* The line buffer for <code>readLine</code>.
*/
private StringBuffer sbuf = null;
/**
* Create a new <code>BufferedReader</code> that will read from the
* specified subordinate stream with a default buffer size of 8192 chars.
*
* @param in The subordinate stream to read from
*/
public BufferedReader(Reader in)
{
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* Create a new <code>BufferedReader</code> that will read from the
* specified subordinate stream with a buffer size that is specified by the
* caller.
*
* @param in The subordinate stream to read from
* @param size The buffer size to use
*
* @exception IllegalArgumentException if size &lt;= 0
*/
public BufferedReader(Reader in, int size)
{
super(in.lock);
if (size <= 0)
throw new IllegalArgumentException("Illegal buffer size: " + size);
this.in = in;
buffer = new char[size];
}
/**
* This method closes the underlying stream and frees any associated
* resources.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
synchronized (lock)
{
if (in != null)
in.close();
in = null;
buffer = null;
}
}
/**
* Returns <code>true</code> to indicate that this class supports mark/reset
* functionality.
*
* @return <code>true</code>
*/
public boolean markSupported()
{
return true;
}
/**
* Mark a position in the input to which the stream can be
* "reset" by calling the <code>reset()</code> method. The parameter
* <code>readLimit</code> is the number of chars that can be read from the
* stream after setting the mark before the mark becomes invalid. For
* example, if <code>mark()</code> is called with a read limit of 10, then
* when 11 chars of data are read from the stream before the
* <code>reset()</code> method is called, then the mark is invalid and the
* stream object instance is not required to remember the mark.
* <p>
* Note that the number of chars that can be remembered by this method
* can be greater than the size of the internal read buffer. It is also
* not dependent on the subordinate stream supporting mark/reset
* functionality.
*
* @param readLimit The number of chars that can be read before the mark
* becomes invalid
*
* @exception IOException If an error occurs
* @exception IllegalArgumentException if readLimit is negative.
*/
public void mark(int readLimit) throws IOException
{
if (readLimit < 0)
throw new IllegalArgumentException("Read-ahead limit is negative");
synchronized (lock)
{
checkStatus();
// In this method we need to be aware of the special case where
// pos + 1 == limit. This indicates that a '\r' was the last char
// in the buffer during a readLine. We'll want to maintain that
// condition after we shift things around and if a larger buffer is
// needed to track readLimit, we'll have to make it one element
// larger to ensure we don't invalidate the mark too early, if the
// char following the '\r' is NOT a '\n'. This is ok because, per
// the spec, we are not required to invalidate when passing readLimit.
//
// Note that if 'pos > limit', then doing 'limit -= pos' will cause
// limit to be negative. This is the only way limit will be < 0.
if (pos + readLimit > limit)
{
char[] old_buffer = buffer;
int extraBuffSpace = 0;
if (pos > limit)
extraBuffSpace = 1;
if (readLimit + extraBuffSpace > limit)
buffer = new char[readLimit + extraBuffSpace];
limit -= pos;
if (limit >= 0)
{
System.arraycopy(old_buffer, pos, buffer, 0, limit);
pos = 0;
}
}
if (limit < 0)
{
// Maintain the relationship of 'pos > limit'.
pos = 1;
limit = markPos = 0;
}
else
markPos = pos;
// Now pos + readLimit <= buffer.length. thus if we need to read
// beyond buffer.length, then we are allowed to invalidate markPos.
}
}
/**
* Reset the stream to the point where the <code>mark()</code> method
* was called. Any chars that were read after the mark point was set will
* be re-read during subsequent reads.
* <p>
* This method will throw an IOException if the number of chars read from
* the stream since the call to <code>mark()</code> exceeds the mark limit
* passed when establishing the mark.
*
* @exception IOException If an error occurs;
*/
public void reset() throws IOException
{
synchronized (lock)
{
checkStatus();
if (markPos < 0)
throw new IOException("mark never set or invalidated");
// Need to handle the extremely unlikely case where a readLine was
// done with a '\r' as the last char in the buffer; which was then
// immediately followed by a mark and a reset with NO intervening
// read of any sort. In that case, setting pos to markPos would
// lose that info and a subsequent read would thus not skip a '\n'
// (if one exists). The value of limit in this rare case is zero.
// We can assume that if limit is zero for other reasons, then
// pos is already set to zero and doesn't need to be readjusted.
if (limit > 0)
pos = markPos;
}
}
/**
* This method determines whether or not a stream is ready to be read. If
* this method returns <code>false</code> then this stream could (but is
* not guaranteed to) block on the next read attempt.
*
* @return <code>true</code> if this stream is ready to be read,
* <code>false</code> otherwise
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException
{
synchronized (lock)
{
checkStatus();
return pos < limit || in.ready();
}
}
/**
* This method read chars from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index
* <code>offset</code> into
* the buffer and attempts to read <code>len</code> chars. This method can
* return before reading the number of chars requested. The actual number
* of chars read is returned as an int. A -1 is returned to indicate the
* end of the stream.
* <p>
* This method will block until some data can be read.
*
* @param buf The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
* @param count The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
* @exception IndexOutOfBoundsException If offset and count are not
* valid regarding buf.
*/
public int read(char[] buf, int offset, int count) throws IOException
{
if (offset < 0 || offset + count > buf.length || count < 0)
throw new IndexOutOfBoundsException();
synchronized (lock)
{
checkStatus();
// Once again, we need to handle the special case of a readLine
// that has a '\r' at the end of the buffer. In this case, we'll
// need to skip a '\n' if it is the next char to be read.
// This special case is indicated by 'pos > limit'.
boolean retAtEndOfBuffer = false;
int avail = limit - pos;
if (count > avail)
{
if (avail > 0)
count = avail;
else // pos >= limit
{
if (limit == buffer.length)
markPos = -1; // read too far - invalidate the mark.
if (pos > limit)
{
// Set a boolean and make pos == limit to simplify things.
retAtEndOfBuffer = true;
--pos;
}
if (markPos < 0)
{
// Optimization: can read directly into buf.
if (count >= buffer.length && !retAtEndOfBuffer)
return in.read(buf, offset, count);
pos = limit = 0;
}
avail = in.read(buffer, limit, buffer.length - limit);
if (retAtEndOfBuffer && avail > 0 && buffer[limit] == '\n')
{
--avail;
limit++;
}
if (avail < count)
{
if (avail <= 0)
return avail;
count = avail;
}
limit += avail;
}
}
System.arraycopy(buffer, pos, buf, offset, count);
pos += count;
return count;
}
}
/* Read more data into the buffer. Update pos and limit appropriately.
Assumes pos==limit initially. May invalidate the mark if read too much.
Return number of chars read (never 0), or -1 on eof. */
private int fill() throws IOException
{
checkStatus();
// Handle the special case of a readLine that has a '\r' at the end of
// the buffer. In this case, we'll need to skip a '\n' if it is the
// next char to be read. This special case is indicated by 'pos > limit'.
boolean retAtEndOfBuffer = false;
if (pos > limit)
{
retAtEndOfBuffer = true;
--pos;
}
if (markPos >= 0 && limit == buffer.length)
markPos = -1;
if (markPos < 0)
pos = limit = 0;
int count = in.read(buffer, limit, buffer.length - limit);
if (count > 0)
limit += count;
if (retAtEndOfBuffer && buffer[pos] == '\n')
{
--count;
// If the mark was set to the location of the \n, then we
// must change it to fully pretend that the \n does not
// exist.
if (markPos == pos)
++markPos;
++pos;
}
return count;
}
public int read() throws IOException
{
synchronized (lock)
{
checkStatus();
if (pos >= limit && fill () <= 0)
return -1;
return buffer[pos++];
}
}
/* Return the end of the line starting at this.pos and ending at limit.
* The index returns is *before* any line terminators, or limit
* if no line terminators were found.
*/
private int lineEnd(int limit)
{
int i = pos;
for (; i < limit; i++)
{
char ch = buffer[i];
if (ch == '\n' || ch == '\r')
break;
}
return i;
}
/**
* This method reads a single line of text from the input stream, returning
* it as a <code>String</code>. A line is terminated by "\n", a "\r", or
* an "\r\n" sequence. The system dependent line separator is not used.
* The line termination characters are not returned in the resulting
* <code>String</code>.
*
* @return The line of text read, or <code>null</code> if end of stream.
*
* @exception IOException If an error occurs
*/
public String readLine() throws IOException
{
checkStatus();
// Handle the special case where a previous readLine (with no intervening
// reads/skips) had a '\r' at the end of the buffer.
// In this case, we'll need to skip a '\n' if it's the next char to be read.
// This special case is indicated by 'pos > limit'.
if (pos > limit)
{
int ch = read();
if (ch < 0)
return null;
if (ch != '\n')
--pos;
}
int i = lineEnd(limit);
if (i < limit)
{
String str = String.valueOf(buffer, pos, i - pos);
pos = i + 1;
// If the last char in the buffer is a '\r', we must remember
// to check if the next char to be read after the buffer is refilled
// is a '\n'. If so, skip it. To indicate this condition, we set pos
// to be limit + 1, which normally is never possible.
if (buffer[i] == '\r')
if (pos == limit || buffer[pos] == '\n')
pos++;
return str;
}
if (sbuf == null)
sbuf = new StringBuffer(200);
else
sbuf.setLength(0);
sbuf.append(buffer, pos, i - pos);
pos = i;
// We only want to return null when no characters were read before
// EOF. So we must keep track of this separately. Otherwise we
// would treat an empty `sbuf' as an EOF condition, which is wrong
// when there is just a newline.
boolean eof = false;
for (;;)
{
// readLine should block. So we must not return until a -1 is reached.
if (pos >= limit)
{
// here count == 0 isn't sufficient to give a failure.
int count = fill();
if (count < 0)
{
eof = true;
break;
}
continue;
}
int ch = buffer[pos++];
if (ch == '\n' || ch == '\r')
{
// Check here if a '\r' was the last char in the buffer; if so,
// mark it as in the comment above to indicate future reads
// should skip a newline that is the next char read after
// refilling the buffer.
if (ch == '\r')
if (pos == limit || buffer[pos] == '\n')
pos++;
break;
}
i = lineEnd(limit);
sbuf.append(buffer, pos - 1, i - (pos - 1));
pos = i;
}
return (sbuf.length() == 0 && eof) ? null : sbuf.toString();
}
/**
* This method skips the specified number of chars in the stream. It
* returns the actual number of chars skipped, which may be less than the
* requested amount.
* <p>
* This method first discards chars in the buffer, then calls the
* <code>skip</code> method on the underlying stream to skip the
* remaining chars.
*
* @param count The requested number of chars to skip
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs.
* @exception IllegalArgumentException If count is negative.
*/
public long skip(long count) throws IOException
{
synchronized (lock)
{
checkStatus();
if (count < 0)
throw new IllegalArgumentException("skip value is negative");
if (count == 0)
return 0;
// Yet again, we need to handle the special case of a readLine
// that has a '\r' at the end of the buffer. In this case, we need
// to ignore a '\n' if it is the next char to be read.
// This special case is indicated by 'pos > limit' (i.e. avail < 0).
// To simplify things, if we're dealing with the special case for
// readLine, just read the next char (since the fill method will
// skip the '\n' for us). By doing this, we'll have to back up pos.
// That's easier than trying to keep track of whether we've skipped
// one element or not.
if (pos > limit)
{
if (read() < 0)
return 0;
else
--pos;
}
int avail = limit - pos;
if (count < avail)
{
pos += count;
return count;
}
pos = limit;
long todo = count - avail;
if (todo > buffer.length)
{
markPos = -1;
todo -= in.skip(todo);
}
else
{
while (todo > 0)
{
avail = fill();
if (avail <= 0)
break;
if (avail > todo)
avail = (int) todo;
pos += avail;
todo -= avail;
}
}
return count - todo;
}
}
private void checkStatus() throws IOException
{
if (in == null)
throw new IOException("Stream closed");
}
}
@@ -0,0 +1,262 @@
/* BufferedWriter.java -- Buffer output into large blocks before writing
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This class accumulates chars written in a buffer instead of immediately
* writing the data to the underlying output sink. The chars are instead
* as one large block when the buffer is filled, or when the stream is
* closed or explicitly flushed. This mode operation can provide a more
* efficient mechanism for writing versus doing numerous small unbuffered
* writes.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @date September 25, 1998
*/
public class BufferedWriter extends Writer
{
/**
* This is the default buffer size
*/
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* This is the underlying <code>Writer</code> to which this object
* sends its output.
*/
private Writer out;
/**
* This is the internal char array used for buffering output before
* writing it.
*/
char[] buffer;
/**
* This is the number of chars that are currently in the buffer and
* are waiting to be written to the underlying stream. It always points to
* the index into the buffer where the next char of data will be stored
*/
int count;
/**
* This method initializes a new <code>BufferedWriter</code> instance
* that will write to the specified subordinate <code>Writer</code>
* and which will use a default buffer size of 8192 chars.
*
* @param out The underlying <code>Writer</code> to write data to
*/
public BufferedWriter (Writer out)
{
this (out, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>BufferedWriter</code> instance
* that will write to the specified subordinate <code>Writer</code>
* and which will use the specified buffer size
*
* @param out The underlying <code>Writer</code> to write data to
* @param size The size of the internal buffer
*/
public BufferedWriter (Writer out, int size)
{
super(out.lock);
this.out = out;
this.buffer = new char[size];
this.count = 0;
}
/**
* This method flushes any remaining buffered chars then closes the
* underlying output stream. Any further attempts to write to this stream
* may throw an exception
*
* @exception IOException If an error occurs.
*/
public void close () throws IOException
{
synchronized (lock)
{
// It is safe to call localFlush even if the stream is already
// closed.
localFlush ();
out.close();
buffer = null;
}
}
/**
* This method causes any currently buffered chars to be immediately
* written to the underlying output stream.
*
* @exception IOException If an error occurs
*/
public void flush () throws IOException
{
synchronized (lock)
{
if (buffer == null)
throw new IOException ("Stream closed");
localFlush ();
out.flush();
}
}
/**
* This method writes out a system depedent line separator sequence. The
* actual value written is detemined from the <xmp>line.separator</xmp>
* system property.
*
* @exception IOException If an error occurs
*/
public void newLine () throws IOException
{
write (System.getProperty("line.separator"));
}
/**
* This method writes a single char of data. This will be written to the
* buffer instead of the underlying data source. However, if the buffer
* is filled as a result of this write request, it will be flushed to the
* underlying output stream.
*
* @param oneChar The char of data to be written, passed as an int
*
* @exception IOException If an error occurs
*/
public void write (int oneChar) throws IOException
{
synchronized (lock)
{
if (buffer == null)
throw new IOException ("Stream closed");
buffer[count++] = (char) oneChar;
if (count == buffer.length)
localFlush ();
}
}
/**
* This method writes <code>len</code> chars from the char array
* <code>buf</code> starting at position <code>offset</code> in the buffer.
* These chars will be written to the internal buffer. However, if this
* write operation fills the buffer, the buffer will be flushed to the
* underlying output stream.
*
* @param buf The array of chars to write.
* @param offset The index into the char array to start writing from.
* @param len The number of chars to write.
*
* @exception IOException If an error occurs
*/
public void write (char[] buf, int offset, int len) throws IOException
{
synchronized (lock)
{
if (buffer == null)
throw new IOException ("Stream closed");
// Bypass buffering if there is too much incoming data.
if (count + len > buffer.length)
{
localFlush ();
out.write(buf, offset, len);
}
else
{
System.arraycopy(buf, offset, buffer, count, len);
count += len;
if (count == buffer.length)
localFlush ();
}
}
}
/**
* This method writes <code>len</code> chars from the <code>String</code>
* <code>str</code> starting at position <code>offset</code> in the string.
* These chars will be written to the internal buffer. However, if this
* write operation fills the buffer, the buffer will be flushed to the
* underlying output stream.
*
* @param str The <code>String</code> to write.
* @param offset The index into the string to start writing from.
* @param len The number of chars to write.
*
* @exception IOException If an error occurs
*/
public void write (String str, int offset, int len) throws IOException
{
synchronized (lock)
{
if (buffer == null)
throw new IOException ("Stream closed");
if (count + len > buffer.length)
{
localFlush ();
out.write(str, offset, len);
}
else
{
str.getChars(offset, offset + len, buffer, count);
count += len;
if (count == buffer.length)
localFlush ();
}
}
}
// This should only be called with the lock held.
private void localFlush () throws IOException
{
if (count > 0)
{
out.write(buffer, 0, count);
count = 0;
}
}
}
@@ -0,0 +1,251 @@
/* ByteArrayInputStream.java -- Read an array as a stream
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class permits an array of bytes to be read as an input stream.
*
* @author Warren Levy (warrenl@cygnus.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class ByteArrayInputStream extends InputStream
{
/**
* The array that contains the data supplied during read operations
*/
protected byte[] buf;
/**
* The array index of the next byte to be read from the buffer
* <code>buf</code>
*/
protected int pos;
/**
* The currently marked position in the stream. This defaults to 0, so a
* reset operation on the stream resets it to read from array index 0 in
* the buffer - even if the stream was initially created with an offset
* greater than 0
*/
protected int mark;
/**
* This indicates the maximum number of bytes that can be read from this
* stream. It is the array index of the position after the last valid
* byte in the buffer <code>buf</code>
*/
protected int count;
/**
* Create a new ByteArrayInputStream that will read bytes from the passed
* in byte array. This stream will read from the beginning to the end
* of the array. It is identical to calling an overloaded constructor
* as <code>ByteArrayInputStream(buf, 0, buf.length)</code>.
* <p>
* Note that this array is not copied. If its contents are changed
* while this stream is being read, those changes will be reflected in the
* bytes supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
* @param buffer The byte array buffer this stream will read from.
*/
public ByteArrayInputStream(byte[] buffer)
{
this(buffer, 0, buffer.length);
}
/**
* Create a new ByteArrayInputStream that will read bytes from the
* passed in byte array. This stream will read from position
* <code>offset</code> in the array for a length of
* <code>length</code> bytes past <code>offset</code>. If the
* stream is reset to a position before <code>offset</code> then
* more than <code>length</code> bytes can be read from the stream.
* The <code>length</code> value should be viewed as the array index
* one greater than the last position in the buffer to read.
* <p>
* Note that this array is not copied. If its contents are changed
* while this stream is being read, those changes will be reflected in the
* bytes supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
* @param buffer The byte array buffer this stream will read from.
* @param offset The index into the buffer to start reading bytes from
* @param length The number of bytes to read from the buffer
*/
public ByteArrayInputStream(byte[] buffer, int offset, int length)
{
if (offset < 0 || length < 0 || offset > buffer.length)
throw new IllegalArgumentException();
buf = buffer;
count = offset + length;
if (count > buf.length)
count = buf.length;
pos = offset;
mark = pos;
}
/**
* This method returns the number of bytes available to be read from this
* stream. The value returned will be equal to <code>count - pos</code>.
*
* @return The number of bytes that can be read from this stream
* before blocking, which is all of them
*/
public synchronized int available()
{
return count - pos;
}
/**
* This method sets the mark position in this stream to the current
* position. Note that the <code>readlimit</code> parameter in this
* method does nothing as this stream is always capable of
* remembering all the bytes int it.
* <p>
* Note that in this class the mark position is set by default to
* position 0 in the stream. This is in constrast to some other
* stream types where there is no default mark position.
*
* @param readLimit The number of bytes this stream must remember.
* This parameter is ignored.
*/
public synchronized void mark(int readLimit)
{
// readLimit is ignored per Java Class Lib. book, p.220.
mark = pos;
}
/**
* This method overrides the <code>markSupported</code> method in
* <code>InputStream</code> in order to return <code>true</code> -
* indicating that this stream class supports mark/reset
* functionality.
*
* @return <code>true</code> to indicate that this class supports
* mark/reset.
*/
public boolean markSupported()
{
return true;
}
/**
* This method reads one byte from the stream. The <code>pos</code>
* counter is advanced to the next byte to be read. The byte read is
* returned as an int in the range of 0-255. If the stream position
* is already at the end of the buffer, no byte is read and a -1 is
* returned in order to indicate the end of the stream.
*
* @return The byte read, or -1 if end of stream
*/
public synchronized int read()
{
if (pos < count)
return ((int) buf[pos++]) & 0xFF;
return -1;
}
/**
* This method reads bytes from the stream and stores them into a
* caller supplied buffer. It starts storing the data at index
* <code>offset</code> into the buffer and attempts to read
* <code>len</code> bytes. This method can return before reading
* the number of bytes requested if the end of the stream is
* encountered first. The actual number of bytes read is returned.
* If no bytes can be read because the stream is already at the end
* of stream position, a -1 is returned.
* <p>
* This method does not block.
*
* @param buffer The array into which the bytes read should be stored.
* @param offset The offset into the array to start storing bytes
* @param length The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*/
public synchronized int read(byte[] buffer, int offset, int length)
{
if (pos >= count)
return -1;
int numBytes = Math.min(count - pos, length);
System.arraycopy(buf, pos, buffer, offset, numBytes);
pos += numBytes;
return numBytes;
}
/**
* This method sets the read position in the stream to the mark
* point by setting the <code>pos</code> variable equal to the
* <code>mark</code> variable. Since a mark can be set anywhere in
* the array, the mark/reset methods int this class can be used to
* provide random search capabilities for this type of stream.
*/
public synchronized void reset()
{
pos = mark;
}
/**
* This method attempts to skip the requested number of bytes in the
* input stream. It does this by advancing the <code>pos</code>
* value by the specified number of bytes. It this would exceed the
* length of the buffer, then only enough bytes are skipped to
* position the stream at the end of the buffer. The actual number
* of bytes skipped is returned.
*
* @param num The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*/
public synchronized long skip(long num)
{
// Even though the var numBytes is a long, in reality it can never
// be larger than an int since the result of subtracting 2 positive
// ints will always fit in an int. Since we have to return a long
// anyway, numBytes might as well just be a long.
long numBytes = Math.min((long) (count - pos), num < 0 ? 0L : num);
pos += numBytes;
return numBytes;
}
}
@@ -0,0 +1,283 @@
/* BufferedReader.java
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This class allows data to be written to a byte array buffer and
* and then retrieved by an application. The internal byte array
* buffer is dynamically resized to hold all the data written. Please
* be aware that writing large amounts to data to this stream will
* cause large amounts of memory to be allocated.
* <p>
* The size of the internal buffer defaults to 32 and it is resized
* by doubling the size of the buffer. This default size can be
* overridden by using the
* <code>gnu.java.io.ByteArrayOutputStream.initialBufferSize</code>
* property.
* <p>
* There is a constructor that specified the initial buffer size and
* that is the preferred way to set that value because it it portable
* across all Java class library implementations.
* <p>
* Note that this class also has methods that convert the byte array
* buffer to a <code>String</code> using either the system default or an
* application specified character encoding. Thus it can handle
* multibyte character encodings.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @date September 24, 1998
*/
public class ByteArrayOutputStream extends OutputStream
{
/**
* This method initializes a new <code>ByteArrayOutputStream</code>
* with the default buffer size of 32 bytes. If a different initial
* buffer size is desired, see the constructor
* <code>ByteArrayOutputStream(int size)</code>. For applications
* where the source code is not available, the default buffer size
* can be set using the system property
* <code>gnu.java.io.ByteArrayOutputStream.initialBufferSize</code>
*/
public ByteArrayOutputStream ()
{
this (initial_buffer_size);
}
/**
* This method initializes a new <code>ByteArrayOutputStream</code> with
* a specified initial buffer size.
*
* @param size The initial buffer size in bytes
*/
public ByteArrayOutputStream (int size)
{
buf = new byte[size];
count = 0;
}
/**
* This method discards all of the bytes that have been written to
* the internal buffer so far by setting the <code>count</code>
* variable to 0. The internal buffer remains at its currently
* allocated size.
*/
public synchronized void reset ()
{
count = 0;
}
/**
* This method returns the number of bytes that have been written to
* the buffer so far. This is the same as the value of the protected
* <code>count</code> variable. If the <code>reset</code> method is
* called, then this value is reset as well. Note that this method does
* not return the length of the internal buffer, but only the number
* of bytes that have been written to it.
*
* @return The number of bytes in the internal buffer
*
* @see #reset()
*/
public int size ()
{
return count;
}
/**
* This method returns a byte array containing the bytes that have been
* written to this stream so far. This array is a copy of the valid
* bytes in the internal buffer and its length is equal to the number of
* valid bytes, not necessarily to the the length of the current
* internal buffer. Note that since this method allocates a new array,
* it should be used with caution when the internal buffer is very large.
*/
public synchronized byte[] toByteArray ()
{
byte[] ret = new byte[count];
System.arraycopy(buf, 0, ret, 0, count);
return ret;
}
/**
* Returns the bytes in the internal array as a <code>String</code>. The
* bytes in the buffer are converted to characters using the system default
* encoding. There is an overloaded <code>toString()</code> method that
* allows an application specified character encoding to be used.
*
* @return A <code>String</code> containing the data written to this
* stream so far
*/
public String toString ()
{
return new String (buf, 0, count);
}
/**
* Returns the bytes in the internal array as a <code>String</code>. The
* bytes in the buffer are converted to characters using the specified
* encoding.
*
* @param enc The name of the character encoding to use
*
* @return A <code>String</code> containing the data written to this
* stream so far
*
* @exception UnsupportedEncodingException If the named encoding is
* not available
*/
public String toString (String enc) throws UnsupportedEncodingException
{
return new String (buf, 0, count, enc);
}
/**
* This method returns the bytes in the internal array as a
* <code>String</code>. It uses each byte in the array as the low
* order eight bits of the Unicode character value and the passed in
* parameter as the high eight bits.
* <p>
* This method does not convert bytes to characters in the proper way and
* so is deprecated in favor of the other overloaded <code>toString</code>
* methods which use a true character encoding.
*
* @param hibyte The high eight bits to use for each character in
* the <code>String</code>
*
* @return A <code>String</code> containing the data written to this
* stream so far
*
* @deprecated
*/
public String toString (int hibyte)
{
return new String (buf, 0, count, hibyte);
}
// Resize buffer to accommodate new bytes.
private void resize (int add)
{
if (count + add > buf.length)
{
int newlen = buf.length * 2;
if (count + add > newlen)
newlen = count + add;
byte[] newbuf = new byte[newlen];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
}
/**
* This method writes the writes the specified byte into the internal
* buffer.
*
* @param oneByte The byte to be read passed as an int
*/
public synchronized void write (int oneByte)
{
resize (1);
buf[count++] = (byte) oneByte;
}
/**
* This method writes <code>len</code> bytes from the passed in array
* <code>buf</code> starting at index <code>offset</code> into the
* internal buffer.
*
* @param buffer The byte array to write data from
* @param offset The index into the buffer to start writing data from
* @param add The number of bytes to write
*/
public synchronized void write (byte[] buffer, int offset, int add)
{
// If ADD < 0 then arraycopy will throw the appropriate error for
// us.
if (add >= 0)
resize (add);
System.arraycopy(buffer, offset, buf, count, add);
count += add;
}
/**
* This method writes all the bytes that have been written to this stream
* from the internal buffer to the specified <code>OutputStream</code>.
*
* @param out The <code>OutputStream</code> to write to
*
* @exception IOException If an error occurs
*/
public synchronized void writeTo (OutputStream out) throws IOException
{
out.write(buf, 0, count);
}
/**
* The internal buffer where the data written is stored
*/
protected byte[] buf;
/**
* The number of bytes that have been written to the buffer
*/
protected int count;
/**
* The default initial buffer size. Specified by the JCL.
*/
private static final int DEFAULT_INITIAL_BUFFER_SIZE = 32;
// The default buffer size which can be overridden by the user.
private static final int initial_buffer_size;
static
{
int r
= Integer.getInteger ("gnu.java.io.ByteArrayOutputStream.initialBufferSize",
DEFAULT_INITIAL_BUFFER_SIZE).intValue ();
if (r <= 0)
r = DEFAULT_INITIAL_BUFFER_SIZE;
initial_buffer_size = r;
}
}
@@ -0,0 +1,305 @@
/* CharArrayReader.java -- Read an array of characters as a stream
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class permits an array of chars to be read as an input stream.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class CharArrayReader extends Reader
{
/**
* The array that contains the data supplied during read operations
*/
protected char[] buf;
/**
* The array index of the next char to be read from the buffer
* <code>buf</code>
*/
protected int pos;
/**
* The currently marked position in the stream. This defaults to 0, so a
* reset operation on the stream resets it to read from array index 0 in
* the buffer - even if the stream was initially created with an offset
* greater than 0
*/
protected int markedPos;
/**
* This indicates the maximum number of chars that can be read from this
* stream. It is the array index of the position after the last valid
* char in the buffer <code>buf</code>
*/
protected int count;
/**
* Create a new CharArrayReader that will read chars from the passed
* in char array. This stream will read from the beginning to the end
* of the array. It is identical to calling an overloaded constructor
* as <code>CharArrayReader(buf, 0, buf.length)</code>.
* <p>
* Note that this array is not copied. If its contents are changed
* while this stream is being read, those changes will be reflected in the
* chars supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
* @param buffer The char array buffer this stream will read from.
*/
public CharArrayReader(char[] buffer)
{
this(buffer, 0, buffer.length);
}
/**
* Create a new CharArrayReader that will read chars from the passed
* in char array. This stream will read from position
* <code>offset</code> in the array for a length of
* <code>length</code> chars past <code>offset</code>. If the
* stream is reset to a position before <code>offset</code> then
* more than <code>length</code> chars can be read from the stream.
* The <code>length</code> value should be viewed as the array index
* one greater than the last position in the buffer to read.
* <p>
* Note that this array is not copied. If its contents are changed
* while this stream is being read, those changes will be reflected in the
* chars supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
* @param buffer The char array buffer this stream will read from.
* @param offset The index into the buffer to start reading chars from
* @param length The number of chars to read from the buffer
*/
public CharArrayReader(char[] buffer, int offset, int length)
{
super();
if (offset < 0 || length < 0 || offset > buffer.length)
throw new IllegalArgumentException();
buf = buffer;
count = offset + length;
if (count > buf.length)
count = buf.length;
pos = offset;
markedPos = pos;
}
/**
* This method closes the stream.
*/
public void close()
{
synchronized (lock)
{
buf = null;
}
}
/**
* This method sets the mark position in this stream to the current
* position. Note that the <code>readlimit</code> parameter in this
* method does nothing as this stream is always capable of
* remembering all the chars int it.
* <p>
* Note that in this class the mark position is set by default to
* position 0 in the stream. This is in constrast to some other
* stream types where there is no default mark position.
*
* @param readAheadLimit The number of chars this stream must
* remember. This parameter is ignored.
*
* @exception IOException If an error occurs
*/
public void mark(int readAheadLimit) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
// readAheadLimit is ignored per Java Class Lib. book, p. 318.
markedPos = pos;
}
}
/**
* This method overrides the <code>markSupported</code> method in
* <code>Reader</code> in order to return <code>true</code> -
* indicating that this stream class supports mark/reset
* functionality.
*
* @return <code>true</code> to indicate that this class supports
* mark/reset.
*/
public boolean markSupported()
{
return true;
}
/**
* This method reads one char from the stream. The <code>pos</code>
* counter is advanced to the next char to be read. The char read
* is returned as an int in the range of 0-65535. If the stream
* position is already at the end of the buffer, no char is read and
* a -1 is returned in order to indicate the end of the stream.
*
* @return The char read, or -1 if end of stream
*/
public int read() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
if (pos < 0)
throw new ArrayIndexOutOfBoundsException(pos);
if (pos < count)
return ((int) buf[pos++]) & 0xFFFF;
return -1;
}
}
/**
* This method reads chars from the stream and stores them into a
* caller supplied buffer. It starts storing the data at index
* <code>offset</code> into the buffer and attempts to read
* <code>len</code> chars. This method can return before reading
* the number of chars requested if the end of the stream is
* encountered first. The actual number of chars read is returned.
* If no chars can be read because the stream is already at the end
* of stream position, a -1 is returned.
* <p>
* This method does not block.
*
* @param b The array into which the chars read should be stored.
* @param off The offset into the array to start storing chars
* @param len The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*/
public int read(char[] b, int off, int len) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
/* Don't need to check pos value, arraycopy will check it. */
if (off < 0 || len < 0 || off + len > b.length)
throw new IndexOutOfBoundsException();
if (pos >= count)
return -1;
int numChars = Math.min(count - pos, len);
System.arraycopy(buf, pos, b, off, numChars);
pos += numChars;
return numChars;
}
}
/**
* Return true if more characters are available to be read.
*
* @return <code>true</code> to indicate that this stream is ready
* to be read.
*
* @specnote The JDK 1.3 API docs are wrong here. This method will
* return false if there are no more characters available.
*/
public boolean ready() throws IOException
{
if (buf == null)
throw new IOException("Stream closed");
return (pos < count);
}
/**
* This method sets the read position in the stream to the mark
* point by setting the <code>pos</code> variable equal to the
* <code>mark</code> variable. Since a mark can be set anywhere in
* the array, the mark/reset methods int this class can be used to
* provide random search capabilities for this type of stream.
*/
public void reset() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
pos = markedPos;
}
}
/**
* This method attempts to skip the requested number of chars in the
* input stream. It does this by advancing the <code>pos</code> value by the
* specified number of chars. It this would exceed the length of the
* buffer, then only enough chars are skipped to position the stream at
* the end of the buffer. The actual number of chars skipped is returned.
*
* @param n The requested number of chars to skip
*
* @return The actual number of chars skipped.
*/
public long skip(long n) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
// Even though the var numChars is a long, in reality it can never
// be larger than an int since the result of subtracting 2 positive
// ints will always fit in an int. Since we have to return a long
// anyway, numChars might as well just be a long.
long numChars = Math.min((long) (count - pos), n < 0 ? 0L : n);
pos += numChars;
return numChars;
}
}
}
@@ -0,0 +1,274 @@
/* CharArrayWriter.java -- Write chars to a buffer
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class allows data to be written to a char array buffer and
* and then retrieved by an application. The internal char array
* buffer is dynamically resized to hold all the data written. Please
* be aware that writing large amounts to data to this stream will
* cause large amounts of memory to be allocated.
* <p>
* The size of the internal buffer defaults to 32 and it is resized
* in increments of 1024 chars. This behavior can be over-ridden by using the
* following two properties:
* <p>
* <ul>
* <li><xmp>gnu.java.io.CharArrayWriter.initialBufferSize</xmp></li>
* <li><xmp>gnu.java.io.CharArrayWriter.bufferIncrementSize</xmp></li>
* </ul>
* <p>
* There is a constructor that specified the initial buffer size and
* that is the preferred way to set that value because it it portable
* across all Java class library implementations.
* <p>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class CharArrayWriter extends Writer
{
/**
* The default initial buffer size
*/
private static final int DEFAULT_INITIAL_BUFFER_SIZE = 32;
/**
* This method initializes a new <code>CharArrayWriter</code> with
* the default buffer size of 32 chars. If a different initial
* buffer size is desired, see the constructor
* <code>CharArrayWriter(int size)</code>.
*/
public CharArrayWriter ()
{
this (DEFAULT_INITIAL_BUFFER_SIZE);
}
/**
* This method initializes a new <code>CharArrayWriter</code> with
* a specified initial buffer size.
*
* @param size The initial buffer size in chars
*/
public CharArrayWriter (int size)
{
super ();
buf = new char[size];
}
/**
* Closes the stream. This method is guaranteed not to free the contents
* of the internal buffer, which can still be retrieved.
*/
public void close ()
{
}
/**
* This method flushes all buffered chars to the stream.
*/
public void flush ()
{
}
/**
* This method discards all of the chars that have been written to the
* internal buffer so far by setting the <code>count</code> variable to
* 0. The internal buffer remains at its currently allocated size.
*/
public void reset ()
{
synchronized (lock)
{
count = 0;
}
}
/**
* This method returns the number of chars that have been written to
* the buffer so far. This is the same as the value of the protected
* <code>count</code> variable. If the <code>reset</code> method is
* called, then this value is reset as well. Note that this method does
* not return the length of the internal buffer, but only the number
* of chars that have been written to it.
*
* @return The number of chars in the internal buffer
*
* @see #reset()
*/
public int size ()
{
return count;
}
/**
* This method returns a char array containing the chars that have been
* written to this stream so far. This array is a copy of the valid
* chars in the internal buffer and its length is equal to the number of
* valid chars, not necessarily to the the length of the current
* internal buffer. Note that since this method allocates a new array,
* it should be used with caution when the internal buffer is very large.
*/
public char[] toCharArray ()
{
synchronized (lock)
{
char[] nc = new char[count];
System.arraycopy(buf, 0, nc, 0, count);
return nc;
}
}
/**
* Returns the chars in the internal array as a <code>String</code>. The
* chars in the buffer are converted to characters using the system default
* encoding. There is an overloaded <code>toString()</code> method that
* allows an application specified character encoding to be used.
*
* @return A <code>String</code> containing the data written to this
* stream so far
*/
public String toString ()
{
synchronized (lock)
{
return new String (buf, 0, count);
}
}
/**
* This method writes the writes the specified char into the internal
* buffer.
*
* @param oneChar The char to be read passed as an int
*/
public void write (int oneChar)
{
synchronized (lock)
{
resize (1);
buf[count++] = (char) oneChar;
}
}
/**
* This method writes <code>len</code> chars from the passed in array
* <code>buf</code> starting at index <code>offset</code> into that buffer
*
* @param buffer The char array to write data from
* @param offset The index into the buffer to start writing data from
* @param len The number of chars to write
*/
public void write (char[] buffer, int offset, int len)
{
synchronized (lock)
{
if (len >= 0)
resize (len);
System.arraycopy(buffer, offset, buf, count, len);
count += len;
}
}
/**
* This method writes <code>len</code> chars from the passed in
* <code>String</code> <code>buf</code> starting at index
* <code>offset</code> into the internal buffer.
*
* @param str The <code>String</code> to write data from
* @param offset The index into the string to start writing data from
* @param len The number of chars to write
*/
public void write (String str, int offset, int len)
{
synchronized (lock)
{
if (len >= 0)
resize (len);
str.getChars(offset, offset + len, buf, count);
count += len;
}
}
/**
* This method writes all the chars that have been written to this stream
* from the internal buffer to the specified <code>Writer</code>.
*
* @param out The <code>Writer</code> to write to
*
* @exception IOException If an error occurs
*/
public void writeTo (Writer out) throws IOException
{
synchronized (lock)
{
out.write(buf, 0, count);
}
}
/**
* This private method makes the buffer bigger when we run out of room
* by allocating a larger buffer and copying the valid chars from the
* old array into it. This is obviously slow and should be avoided by
* application programmers by setting their initial buffer size big
* enough to hold everything if possible.
*/
private void resize (int len)
{
if (count + len >= buf.length)
{
int newlen = buf.length * 2;
if (count + len > newlen)
newlen = count + len;
char[] newbuf = new char[newlen];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
}
/**
* The internal buffer where the data written is stored
*/
protected char[] buf;
/**
* The number of chars that have been written to the buffer
*/
protected int count;
}
@@ -0,0 +1,73 @@
/* CharConversionException.java -- Character conversion exceptions
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown to indicate that a problem occurred with
* an attempted character conversion.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @since 1.1
* @status updated to 1.4
*/
public class CharConversionException extends IOException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -8680016352018427031L;
/**
* Create an exception without a descriptive error message.
*/
public CharConversionException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public CharConversionException(String message)
{
super(message);
}
} // class CharConversionException
+63
View File
@@ -0,0 +1,63 @@
/* Closeable.java -- Closeable object
Copyright (C) 2004, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* A <code>Closeable</code> class represents a stream of
* data, which can be closed when it is no longer needed.
* Closing a stream allows the resources it uses to be
* freed for an alternate use.
*
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public interface Closeable
{
/**
* Closes the stream represented by this class, thus freeing
* system resources. In that case that the stream is already
* in the closed state, this method has no effect.
*
* @throws IOException if an I/O error occurs in closing.
*/
void close()
throws IOException;
}
+456
View File
@@ -0,0 +1,456 @@
/* DataInput.java -- Interface for reading data from a stream
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct. */
/**
* This interface is implemented by classes that can data from streams
* into Java primitive types.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public interface DataInput
{
/**
* This method reads a Java boolean value from an input stream. It does
* so by reading a single byte of data. If that byte is zero, then the
* value returned is <code>false</code>. If the byte is non-zero, then
* the value returned is <code>true</code>.
* <p>
* This method can read a <code>boolean</code> written by an object
* implementing the <code>writeBoolean()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>boolean</code> value read
*
* @exception EOFException If end of file is reached before
* reading the boolean
* @exception IOException If any other error occurs
*
* @see DataOutput#writeBoolean
*/
boolean readBoolean() throws EOFException, IOException;
/**
* This method reads a Java byte value from an input stream. The value
* is in the range of -128 to 127.
* <p>
* This method can read a <code>byte</code> written by an object
* implementing the
* <code>writeByte()</code> method in the <code>DataOutput</code> interface.
* <p>
* @return The <code>byte</code> value read
*
* @exception EOFException If end of file is reached before reading the byte
* @exception IOException If any other error occurs
*
* @see DataOutput#writeByte
*/
byte readByte() throws EOFException, IOException;
/**
* This method reads 8 unsigned bits into a Java <code>int</code> value from
* the stream. The value returned is in the range of 0 to 255.
* <p>
* This method can read an unsigned byte written by an object
* implementing the
* <code>writeByte()</code> method in the <code>DataOutput</code>
* interface.
*
* @return The unsigned bytes value read as a Java <code>int</code>.
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeByte
*/
int readUnsignedByte() throws EOFException, IOException;
/**
* This method reads a Java <code>char</code> value from an input stream.
* It operates by reading two bytes from the stream and converting them to
* a single 16-bit Java <code>char</code>. The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> represent the
* first and second byte read from the stream respectively, they will be
* transformed to a <code>char</code> in the following manner:
* <p>
* <code>(char)((byte1 << 8) + byte2)</code>
* <p>
* This method can read a <code>char</code> written by an object implementing
* the
* <code>writeChar()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>char</code> value read
*
* @exception EOFException If end of file is reached before reading the char
* @exception IOException If any other error occurs
*
* @see DataOutput#writeChar
*/
char readChar() throws EOFException, IOException;
/**
* This method reads a signed 16-bit value into a Java in from the stream.
* It operates by reading two bytes from the stream and converting them to
* a single 16-bit Java <code>short</code>. The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> represent the
* first and second byte read from the stream respectively, they will be
* transformed to a <code>short</code> in the following manner:
* <p>
* <code>(short)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code>
* <p>
* The value returned is in the range of -32768 to 32767.
* <p>
* This method can read a <code>short</code> written by an object
* implementing
* the <code>writeShort()</code> method in the <code>DataOutput</code>
* interface.
*
* @return The <code>short</code> value read
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeShort
*/
short readShort() throws EOFException, IOException;
/**
* This method reads 16 unsigned bits into a Java int value from the stream.
* It operates by reading two bytes from the stream and converting them to
* a single Java <code>int</code>. The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> represent the
* first and second byte read from the stream respectively, they will be
* transformed to an <code>int</code> in the following manner:
* <p>
* <code>(int)(((byte1 0xFF) << 8) + (byte2 & 0xFF))</code>
* <p>
* The value returned is in the range of 0 to 65535.
* <p>
* This method can read an unsigned short written by an object implementing
* the <code>writeShort()</code> method in the
* <code>DataOutput</code>
* interface.
*
* @return The unsigned short value read as a Java <code>int</code>.
*
* @exception EOFException If end of file is reached before reading
* the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeShort
*/
int readUnsignedShort() throws EOFException, IOException;
/**
* This method reads a Java <code>int</code> value from an input stream
* It operates by reading four bytes from the stream and converting them to
* a single Java <code>int</code>. The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte4</code> represent
* the first four bytes read from the stream, they will be
* transformed to an <code>int</code> in the following manner:
* <p>
* <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) +
* ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code>
* <p>
* The value returned is in the range of -2147483648 to 2147483647.
* <p>
* This method can read an <code>int</code> written by an object
* implementing the <code>writeInt()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>int</code> value read
*
* @exception EOFException If end of file is reached before reading the int
* @exception IOException If any other error occurs
*
* @see DataOutput#writeInt
*/
int readInt() throws EOFException, IOException;
/**
* This method reads a Java <code>long</code> value from an input stream
* It operates by reading eight bytes from the stream and converting them to
* a single Java <code>long</code>. The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte8</code> represent
* the first eight bytes read from the stream, they will be
* transformed to an <code>long</code> in the following manner:
* <p>
* <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) +
* ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) +
* ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) +
* ((byte7 & 0xFF) << 8) + (byte8 & 0xFF)))
* </code>
* <p>
* The value returned is in the range of -9223372036854775808 to
* 9223372036854775807.
* <p>
* This method can read an <code>long</code> written by an object
* implementing the <code>writeLong()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>long</code> value read
*
* @exception EOFException If end of file is reached before reading the long
* @exception IOException If any other error occurs
*
* @see DataOutput#writeLong
*/
long readLong() throws EOFException, IOException;
/**
* This method reads a Java float value from an input stream. It operates
* by first reading an <code>int</code> value from the stream by calling the
* <code>readInt()</code> method in this interface, then converts that
* <code>int</code> to a <code>float</code> using the
* <code>intBitsToFloat</code> method in the class
* <code>java.lang.Float</code>.
* <p>
* This method can read a <code>float</code> written by an object
* implementing
* the <code>writeFloat()</code> method in the <code>DataOutput</code>
* interface.
*
* @return The <code>float</code> value read
*
* @exception EOFException If end of file is reached before reading the
* float
* @exception IOException If any other error occurs
*
* @see DataOutput#writeFloat
* @see java.lang.Float#intBitsToFloat
*/
float readFloat() throws EOFException, IOException;
/**
* This method reads a Java double value from an input stream. It operates
* by first reading a <code>long</code> value from the stream by calling the
* <code>readLong()</code> method in this interface, then converts that
* <code>long</code> to a <code>double</code> using the
* <code>longBitsToDouble</code> method in the class
* <code>java.lang.Double</code>.
* <p>
* This method can read a <code>double</code> written by an object
* implementing the <code>writeDouble()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>double</code> value read
*
* @exception EOFException If end of file is reached before reading the
* double
* @exception IOException If any other error occurs
*
* @see DataOutput#writeDouble
* @see java.lang.Double#longBitsToDouble
*/
double readDouble() throws EOFException, IOException;
/**
* This method reads the next line of text data from an input stream.
* It operates by reading bytes and converting those bytes to
* <code>char</code>
* values by treating the byte read as the low eight bits of the
* <code>char</code> and using 0 as the high eight bits. Because of this,
* it does not support the full 16-bit Unicode character set.
* <P>
* The reading of bytes ends when either the end of file or a line terminator
* is encountered. The bytes read are then returned as a
* <code>String</code>.
* A line terminator is a byte sequence consisting of either
* <code>\r</code>, <code>\n</code> or <code>\r\n</code>. These termination
* charaters are discarded and are not returned as part of the string.
* A line is also terminated by an end of file condition.
* <p>
*
* @return The line read as a <code>String</code>
*
* @exception IOException If an error occurs
*/
String readLine() throws IOException;
/**
* This method reads a <code>String</code> from an input stream that is
* encoded in a modified UTF-8 format. This format has a leading two byte
* sequence that contains the remaining number of bytes to read.
* This two byte
* sequence is read using the <code>readUnsignedShort()</code> method of this
* interface.
*
* After the number of remaining bytes have been determined, these bytes
* are read an transformed into <code>char</code> values. These
* <code>char</code> values are encoded in the stream using either a one,
* two, or three byte format.
* The particular format in use can be determined by examining the first
* byte read.
* <p>
* If the first byte has a high order bit of 0, then
* that character consists on only one byte. This character value consists
* of seven bits that are at positions 0 through 6 of the byte. As an
* example, if <code>byte1</code> is the byte read from the stream, it would
* be converted to a <code>char</code> like so:
* <p>
* <code>(char)byte1</code>
* <p>
* If the first byte has 110 as its high order bits, then the
* character consists of two bytes. The bits that make up the character
* value are in positions 0 through 4 of the first byte and bit positions
* 0 through 5 of the second byte. (The second byte should have
* 10 as its high order bits). These values are in most significant
* byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> are the first
* two bytes read respectively, and the high order bits of them match the
* patterns which indicate a two byte character encoding, then they would be
* converted to a Java <code>char</code> like so:
* <p>
* <code>(char)(((byte1 &amp; 0x1F) &lt;&lt; 6) + (byte2 &amp; 0x3F))</code>
* <p>
* If the first byte has a 1110 as its high order bits, then the
* character consists of three bytes. The bits that make up the character
* value are in positions 0 through 3 of the first byte and bit positions
* 0 through 5 of the other two bytes. (The second and third bytes should
* have 10 as their high order bits). These values are in most
* significant byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code>, <code>byte2</code>, and
* <code>byte3</code> are the three bytes read, and the high order bits of
* them match the patterns which indicate a three byte character encoding,
* then they would be converted to a Java <code>char</code> like so:
*
* <code>
* (char)(((byte1 &amp; 0x0F) &lt;&lt; 12) + ((byte2 &amp; 0x3F) + (byte3 &amp; 0x3F))
* </code>
*
* Note that all characters are encoded in the method that requires the
* fewest number of bytes with the exception of the character with the
* value of <code>\&lt;llll&gt;u0000</code> which is encoded as two bytes.
* This is a modification of the UTF standard used to prevent C language
* style <code>NUL</code> values from appearing in the byte stream.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeUTF()</code> method in <code>DataOutput</code>.
*
* @return The <code>String</code> read
*
* @exception EOFException If end of file is reached before reading the
* String
* @exception UTFDataFormatException If the data is not in UTF-8 format
* @exception IOException If any other error occurs
*
* @see DataOutput#writeUTF
*/
String readUTF() throws EOFException, UTFDataFormatException, IOException;
/**
* This method reads raw bytes into the passed array until the array is
* full. Note that this method blocks until the data is available and
* throws an exception if there is not enough data left in the stream to
* fill the buffer. Note also that zero length buffers are permitted.
* In this case, the method will return immediately without reading any
* bytes from the stream.
*
* @param buf The buffer into which to read the data
*
* @exception EOFException If end of file is reached before filling the
* buffer
* @exception IOException If any other error occurs
*/
void readFully(byte[] buf) throws EOFException, IOException;
/**
* This method reads raw bytes into the passed array <code>buf</code>
* starting
* <code>offset</code> bytes into the buffer. The number of bytes read
* will be
* exactly <code>len</code>. Note that this method blocks until the data is
* available and throws an exception if there is not enough data left in
* the stream to read <code>len</code> bytes. Note also that zero length
* buffers are permitted. In this case, the method will return immediately
* without reading any bytes from the stream.
*
* @param buf The buffer into which to read the data
* @param offset The offset into the buffer to start storing data
* @param len The number of bytes to read into the buffer
*
* @exception EOFException If end of file is reached before filling the
* buffer
* @exception IOException If any other error occurs
*/
void readFully(byte[] buf, int offset, int len)
throws EOFException, IOException;
/**
* This method skips and discards the specified number of bytes in an
* input stream. Note that this method may skip less than the requested
* number of bytes. The actual number of bytes skipped is returned.
* No bytes are skipped if a negative number is passed to this method.
*
* @param numBytes The number of bytes to skip
*
* @return The number of bytes actually skipped, which will always be
* <code>numBytes</code>
*
* @exception EOFException If end of file is reached before all bytes can be
* skipped
* @exception IOException If any other error occurs
*/
int skipBytes(int numBytes) throws EOFException, IOException;
} // interface DataInput
@@ -0,0 +1,739 @@
/* DataInputStream.java -- FilteredInputStream that implements DataInput
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This subclass of <code>FilteredInputStream</code> implements the
* <code>DataInput</code> interface that provides method for reading primitive
* Java data types from a stream.
*
* @see DataInput
*
* @author Warren Levy (warrenl@cygnus.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
* @date October 20, 1998.
*/
public class DataInputStream extends FilterInputStream implements DataInput
{
// Byte buffer, used to make primitive read calls more efficient.
byte[] buf = new byte [8];
/**
* This constructor initializes a new <code>DataInputStream</code>
* to read from the specified subordinate stream.
*
* @param in The subordinate <code>InputStream</code> to read from
*/
public DataInputStream (InputStream in)
{
super (in);
}
/**
* This method reads bytes from the underlying stream into the specified
* byte array buffer. It will attempt to fill the buffer completely, but
* may return a short count if there is insufficient data remaining to be
* read to fill the buffer.
*
* @param b The buffer into which bytes will be read.
*
* @return The actual number of bytes read, or -1 if end of stream reached
* before reading any bytes.
*
* @exception IOException If an error occurs.
*/
public final int read (byte[] b) throws IOException
{
return in.read (b, 0, b.length);
}
/**
* This method reads bytes from the underlying stream into the specified
* byte array buffer. It will attempt to read <code>len</code> bytes and
* will start storing them at position <code>off</code> into the buffer.
* This method can return a short count if there is insufficient data
* remaining to be read to complete the desired read length.
*
* @param b The buffer into which bytes will be read.
* @param off The offset into the buffer to start storing bytes.
* @param len The requested number of bytes to read.
*
* @return The actual number of bytes read, or -1 if end of stream reached
* before reading any bytes.
*
* @exception IOException If an error occurs.
*/
public final int read (byte[] b, int off, int len) throws IOException
{
return in.read (b, off, len);
}
/**
* This method reads a Java boolean value from an input stream. It does
* so by reading a single byte of data. If that byte is zero, then the
* value returned is <code>false</code>. If the byte is non-zero, then
* the value returned is <code>true</code>.
* <p>
* This method can read a <code>boolean</code> written by an object
* implementing the <code>writeBoolean()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>boolean</code> value read
*
* @exception EOFException If end of file is reached before reading
* the boolean
* @exception IOException If any other error occurs
*
* @see DataOutput#writeBoolean
*/
public final boolean readBoolean () throws IOException
{
return convertToBoolean (in.read ());
}
/**
* This method reads a Java byte value from an input stream. The value
* is in the range of -128 to 127.
* <p>
* This method can read a <code>byte</code> written by an object
* implementing the <code>writeByte()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>byte</code> value read
*
* @exception EOFException If end of file is reached before reading the byte
* @exception IOException If any other error occurs
*
* @see DataOutput#writeByte
*/
public final byte readByte () throws IOException
{
return convertToByte (in.read ());
}
/**
* This method reads a Java <code>char</code> value from an input stream.
* It operates by reading two bytes from the stream and converting them to
* a single 16-bit Java <code>char</code>. The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first and second byte read from the stream
* respectively, they will be transformed to a <code>char</code> in
* the following manner:
* <p>
* <code>(char)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
* <p>
* This method can read a <code>char</code> written by an object
* implementing the <code>writeChar()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>char</code> value read
*
* @exception EOFException If end of file is reached before reading the char
* @exception IOException If any other error occurs
*
* @see DataOutput#writeChar
*/
public final char readChar () throws IOException
{
readFully (buf, 0, 2);
return convertToChar (buf);
}
/**
* This method reads a Java double value from an input stream. It operates
* by first reading a <code>long</code> value from the stream by calling the
* <code>readLong()</code> method in this interface, then converts
* that <code>long</code> to a <code>double</code> using the
* <code>longBitsToDouble</code> method in the class
* <code>java.lang.Double</code>
* <p>
* This method can read a <code>double</code> written by an object
* implementing the <code>writeDouble()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>double</code> value read
*
* @exception EOFException If end of file is reached before reading
* the double
* @exception IOException If any other error occurs
*
* @see DataOutput#writeDouble
* @see java.lang.Double#longBitsToDouble
*/
public final double readDouble () throws IOException
{
return Double.longBitsToDouble (readLong ());
}
/**
* This method reads a Java float value from an input stream. It
* operates by first reading an <code>int</code> value from the
* stream by calling the <code>readInt()</code> method in this
* interface, then converts that <code>int</code> to a
* <code>float</code> using the <code>intBitsToFloat</code> method
* in the class <code>java.lang.Float</code>
* <p>
* This method can read a <code>float</code> written by an object
* implementing the <code>writeFloat()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>float</code> value read
*
* @exception EOFException If end of file is reached before reading the float
* @exception IOException If any other error occurs
*
* @see DataOutput#writeFloat
* @see java.lang.Float#intBitsToFloat
*/
public final float readFloat () throws IOException
{
return Float.intBitsToFloat (readInt ());
}
/**
* This method reads raw bytes into the passed array until the array is
* full. Note that this method blocks until the data is available and
* throws an exception if there is not enough data left in the stream to
* fill the buffer. Note also that zero length buffers are permitted.
* In this case, the method will return immediately without reading any
* bytes from the stream.
*
* @param b The buffer into which to read the data
*
* @exception EOFException If end of file is reached before filling the
* buffer
* @exception IOException If any other error occurs
*/
public final void readFully (byte[] b) throws IOException
{
readFully (b, 0, b.length);
}
/**
* This method reads raw bytes into the passed array <code>buf</code>
* starting
* <code>offset</code> bytes into the buffer. The number of bytes read
* will be
* exactly <code>len</code>. Note that this method blocks until the data is
* available and throws an exception if there is not enough data left in
* the stream to read <code>len</code> bytes. Note also that zero length
* buffers are permitted. In this case, the method will return immediately
* without reading any bytes from the stream.
*
* @param buf The buffer into which to read the data
* @param offset The offset into the buffer to start storing data
* @param len The number of bytes to read into the buffer
*
* @exception EOFException If end of file is reached before filling the
* buffer
* @exception IOException If any other error occurs
*/
public final void readFully (byte[] buf, int offset, int len) throws IOException
{
if (len < 0)
throw new IndexOutOfBoundsException("Negative length: " + len);
while (len > 0)
{
// in.read will block until some data is available.
int numread = in.read (buf, offset, len);
if (numread < 0)
throw new EOFException ();
len -= numread;
offset += numread;
}
}
/**
* This method reads a Java <code>int</code> value from an input stream
* It operates by reading four bytes from the stream and converting them to
* a single Java <code>int</code>. The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte4</code> represent
* the first four bytes read from the stream, they will be
* transformed to an <code>int</code> in the following manner:
* <p>
* <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 24) + ((byte2 &amp; 0xFF) &lt;&lt; 16) +
* ((byte3 &amp; 0xFF)&lt;&lt; 8) + (byte4 &amp; 0xFF)))</code>
* <p>
* The value returned is in the range of -2147483648 to 2147483647.
* <p>
* This method can read an <code>int</code> written by an object
* implementing the <code>writeInt()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>int</code> value read
*
* @exception EOFException If end of file is reached before reading the int
* @exception IOException If any other error occurs
*
* @see DataOutput#writeInt
*/
public final int readInt () throws IOException
{
readFully (buf, 0, 4);
return convertToInt (buf);
}
/**
* This method reads the next line of text data from an input
* stream. It operates by reading bytes and converting those bytes
* to <code>char</code> values by treating the byte read as the low
* eight bits of the <code>char</code> and using 0 as the high eight
* bits. Because of this, it does not support the full 16-bit
* Unicode character set.
* <p>
* The reading of bytes ends when either the end of file or a line
* terminator is encountered. The bytes read are then returned as a
* <code>String</code> A line terminator is a byte sequence
* consisting of either <code>\r</code>, <code>\n</code> or
* <code>\r\n</code>. These termination charaters are discarded and
* are not returned as part of the string.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeLine()</code> method in <code>DataOutput</code>.
*
* @return The line read as a <code>String</code>
*
* @exception IOException If an error occurs
*
* @see DataOutput
*
* @deprecated
*/
public final String readLine() throws IOException
{
StringBuffer strb = new StringBuffer();
while (true)
{
int c = in.read();
if (c == -1) // got an EOF
return strb.length() > 0 ? strb.toString() : null;
if (c == '\r')
{
int next_c = in.read();
if (next_c != '\n' && next_c != -1)
{
if (!(in instanceof PushbackInputStream))
in = new PushbackInputStream(in);
((PushbackInputStream) in).unread(next_c);
}
break;
}
if (c == '\n')
break;
strb.append((char) c);
}
return strb.length() > 0 ? strb.toString() : "";
}
/**
* This method reads a Java <code>long</code> value from an input stream
* It operates by reading eight bytes from the stream and converting them to
* a single Java <code>long</code>. The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte8</code> represent
* the first eight bytes read from the stream, they will be
* transformed to an <code>long</code> in the following manner:
* <p>
* <code>(long)(((byte1 &amp; 0xFF) &lt;&lt; 56) + ((byte2 &amp; 0xFF) &lt;&lt; 48) +
* ((byte3 &amp; 0xFF) &lt;&lt; 40) + ((byte4 &amp; 0xFF) &lt;&lt; 32) +
* ((byte5 &amp; 0xFF) &lt;&lt; 24) + ((byte6 &amp; 0xFF) &lt;&lt; 16) +
* ((byte7 &amp; 0xFF) &lt;&lt; 8) + (byte8 &amp; 0xFF)))
* </code>
* <p>
* The value returned is in the range of -9223372036854775808 to
* 9223372036854775807.
* <p>
* This method can read an <code>long</code> written by an object
* implementing the <code>writeLong()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>long</code> value read
*
* @exception EOFException If end of file is reached before reading the long
* @exception IOException If any other error occurs
*
* @see DataOutput#writeLong
*/
public final long readLong () throws IOException
{
readFully (buf, 0, 8);
return convertToLong (buf);
}
/**
* This method reads a signed 16-bit value into a Java in from the
* stream. It operates by reading two bytes from the stream and
* converting them to a single 16-bit Java <code>short</code>. The
* two bytes are stored most significant byte first (i.e., "big
* endian") regardless of the native host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first and second byte read from the stream
* respectively, they will be transformed to a <code>short</code>. in
* the following manner:
* <p>
* <code>(short)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF))</code>
* <p>
* The value returned is in the range of -32768 to 32767.
* <p>
* This method can read a <code>short</code> written by an object
* implementing the <code>writeShort()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The <code>short</code> value read
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeShort
*/
public final short readShort () throws IOException
{
readFully (buf, 0, 2);
return convertToShort (buf);
}
/**
* This method reads 8 unsigned bits into a Java <code>int</code>
* value from the stream. The value returned is in the range of 0 to
* 255.
* <p>
* This method can read an unsigned byte written by an object
* implementing the <code>writeUnsignedByte()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The unsigned bytes value read as a Java <code>int</code>.
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeByte
*/
public final int readUnsignedByte () throws IOException
{
return convertToUnsignedByte (in.read ());
}
/**
* This method reads 16 unsigned bits into a Java int value from the stream.
* It operates by reading two bytes from the stream and converting them to
* a single Java <code>int</code> The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first and second byte read from the stream
* respectively, they will be transformed to an <code>int</code> in
* the following manner:
* <p>
* <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 8) + (byte2 &amp; 0xFF))</code>
* <p>
* The value returned is in the range of 0 to 65535.
* <p>
* This method can read an unsigned short written by an object
* implementing the <code>writeUnsignedShort()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The unsigned short value read as a Java <code>int</code>
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput#writeShort
*/
public final int readUnsignedShort () throws IOException
{
readFully (buf, 0, 2);
return convertToUnsignedShort (buf);
}
/**
* This method reads a <code>String</code> from an input stream that
* is encoded in a modified UTF-8 format. This format has a leading
* two byte sequence that contains the remaining number of bytes to
* read. This two byte sequence is read using the
* <code>readUnsignedShort()</code> method of this interface.
* <p>
* After the number of remaining bytes have been determined, these
* bytes are read an transformed into <code>char</code> values.
* These <code>char</code> values are encoded in the stream using
* either a one, two, or three byte format. The particular format
* in use can be determined by examining the first byte read.
* <p>
* If the first byte has a high order bit of 0, then that character
* consists on only one byte. This character value consists of
* seven bits that are at positions 0 through 6 of the byte. As an
* example, if <code>byte1</code> is the byte read from the stream,
* it would be converted to a <code>char</code> like so:
* <p>
* <code>(char)byte1</code>
* <p>
* If the first byte has 110 as its high order bits, then the
* character consists of two bytes. The bits that make up the character
* value are in positions 0 through 4 of the first byte and bit positions
* 0 through 5 of the second byte. (The second byte should have
* 10 as its high order bits). These values are in most significant
* byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> are
* the first two bytes read respectively, and the high order bits of
* them match the patterns which indicate a two byte character
* encoding, then they would be converted to a Java
* <code>char</code> like so:
* <p>
* <code>(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))</code>
* <p>
* If the first byte has a 1110 as its high order bits, then the
* character consists of three bytes. The bits that make up the character
* value are in positions 0 through 3 of the first byte and bit positions
* 0 through 5 of the other two bytes. (The second and third bytes should
* have 10 as their high order bits). These values are in most
* significant byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code> <code>byte2</code> and
* <code>byte3</code> are the three bytes read, and the high order
* bits of them match the patterns which indicate a three byte
* character encoding, then they would be converted to a Java
* <code>char</code> like so:
* <p>
* <code>(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) |
* (byte3 & 0x3F))</code>
* <p>
* Note that all characters are encoded in the method that requires
* the fewest number of bytes with the exception of the character
* with the value of <code>&#92;u0000</code> which is encoded as two
* bytes. This is a modification of the UTF standard used to
* prevent C language style <code>NUL</code> values from appearing
* in the byte stream.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeUTF()</code> method in <code>DataOutput</code>
*
* @return The <code>String</code> read
*
* @exception EOFException If end of file is reached before reading
* the String
* @exception UTFDataFormatException If the data is not in UTF-8 format
* @exception IOException If any other error occurs
*
* @see DataOutput#writeUTF
*/
public final String readUTF () throws IOException
{
return readUTF (this);
}
/**
* This method reads a String encoded in UTF-8 format from the
* specified <code>DataInput</code> source.
*
* @param in The <code>DataInput</code> source to read from
*
* @return The String read from the source
*
* @exception IOException If an error occurs
*
* @see DataInput#readUTF
*/
public static final String readUTF(DataInput in) throws IOException
{
final int UTFlen = in.readUnsignedShort ();
byte[] buf = new byte [UTFlen];
// This blocks until the entire string is available rather than
// doing partial processing on the bytes that are available and then
// blocking. An advantage of the latter is that Exceptions
// could be thrown earlier. The former is a bit cleaner.
in.readFully (buf, 0, UTFlen);
return convertFromUTF (buf);
}
/**
* This method attempts to skip and discard the specified number of bytes
* in the input stream. It may actually skip fewer bytes than requested.
* This method will not skip any bytes if passed a negative number of bytes
* to skip.
*
* @param n The requested number of bytes to skip.
*
* @return The requested number of bytes to skip.
*
* @exception IOException If an error occurs.
* @specnote The JDK docs claim that this returns the number of bytes
* actually skipped. The JCL claims that this method can throw an
* EOFException. Neither of these appear to be true in the JDK 1.3's
* implementation. This tries to implement the actual JDK behaviour.
*/
public final int skipBytes (int n) throws IOException
{
if (n <= 0)
return 0;
try
{
return (int) in.skip (n);
}
catch (EOFException x)
{
// do nothing.
}
return n;
}
static boolean convertToBoolean (int b) throws EOFException
{
if (b < 0)
throw new EOFException ();
return (b != 0);
}
static byte convertToByte (int i) throws EOFException
{
if (i < 0)
throw new EOFException ();
return (byte) i;
}
static int convertToUnsignedByte (int i) throws EOFException
{
if (i < 0)
throw new EOFException ();
return (i & 0xFF);
}
static char convertToChar (byte[] buf)
{
return (char) ((buf [0] << 8)
| (buf [1] & 0xff));
}
static short convertToShort (byte[] buf)
{
return (short) ((buf [0] << 8)
| (buf [1] & 0xff));
}
static int convertToUnsignedShort (byte[] buf)
{
return (((buf [0] & 0xff) << 8)
| (buf [1] & 0xff));
}
static int convertToInt (byte[] buf)
{
return (((buf [0] & 0xff) << 24)
| ((buf [1] & 0xff) << 16)
| ((buf [2] & 0xff) << 8)
| (buf [3] & 0xff));
}
static long convertToLong (byte[] buf)
{
return (((long)(buf [0] & 0xff) << 56) |
((long)(buf [1] & 0xff) << 48) |
((long)(buf [2] & 0xff) << 40) |
((long)(buf [3] & 0xff) << 32) |
((long)(buf [4] & 0xff) << 24) |
((long)(buf [5] & 0xff) << 16) |
((long)(buf [6] & 0xff) << 8) |
((long)(buf [7] & 0xff)));
}
// FIXME: This method should be re-thought. I suspect we have multiple
// UTF-8 decoders floating around. We should use the standard charset
// converters, maybe and adding a direct call into one of the new
// NIO converters for a super-fast UTF8 decode.
static String convertFromUTF (byte[] buf)
throws EOFException, UTFDataFormatException
{
// Give StringBuffer an initial estimated size to avoid
// enlarge buffer frequently
StringBuffer strbuf = new StringBuffer (buf.length / 2 + 2);
for (int i = 0; i < buf.length; )
{
if ((buf [i] & 0x80) == 0) // bit pattern 0xxxxxxx
strbuf.append ((char) (buf [i++] & 0xFF));
else if ((buf [i] & 0xE0) == 0xC0) // bit pattern 110xxxxx
{
if (i + 1 >= buf.length
|| (buf [i + 1] & 0xC0) != 0x80)
throw new UTFDataFormatException ();
strbuf.append((char) (((buf [i++] & 0x1F) << 6)
| (buf [i++] & 0x3F)));
}
else if ((buf [i] & 0xF0) == 0xE0) // bit pattern 1110xxxx
{
if (i + 2 >= buf.length
|| (buf [i + 1] & 0xC0) != 0x80
|| (buf [i + 2] & 0xC0) != 0x80)
throw new UTFDataFormatException ();
strbuf.append ((char) (((buf [i++] & 0x0F) << 12)
| ((buf [i++] & 0x3F) << 6)
| (buf [i++] & 0x3F)));
}
else // must be ((buf [i] & 0xF0) == 0xF0 || (buf [i] & 0xC0) == 0x80)
throw new UTFDataFormatException (); // bit patterns 1111xxxx or
// 10xxxxxx
}
return strbuf.toString ();
}
}
+326
View File
@@ -0,0 +1,326 @@
/* DataOutput.java -- Interface for writing data from a stream
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This interface is implemented by classes that can wrte data to streams
* from Java primitive types. This data can subsequently be read back
* by classes implementing the <code>DataInput</code> interface.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*
* @see DataInput
*/
public interface DataOutput
{
/**
* This method writes a Java boolean value to an output stream. If
* <code>value</code> is <code>true</code>, a byte with the value of
* 1 will be written, otherwise a byte with the value of 0 will be
* written.
*
* The value written can be read using the <code>readBoolean</code>
* method in <code>DataInput</code>.
*
* @param value The boolean value to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readBoolean
*/
void writeBoolean(boolean value) throws IOException;
/**
* This method writes a Java byte value to an output stream. The
* byte to be written will be in the lowest 8 bits of the
* <code>int</code> value passed.
*
* The value written can be read using the <code>readByte</code> or
* <code>readUnsignedByte</code> methods in <code>DataInput</code>.
*
* @param value The int value to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readByte
* @see DataInput#readUnsignedByte
*/
void writeByte(int value) throws IOException;
/**
* This method writes a Java char value to an output stream. The
* char to be written will be in the lowest 16 bits of the <code>int</code>
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
* byte1 = (byte)(value & 0x00FF);</code>
* <p>
*
* The value written can be read using the <code>readChar</code>
* method in <code>DataInput</code>.
*
* @param value The char value to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readChar
*/
void writeChar(int value) throws IOException;
/**
* This method writes a Java short value to an output stream. The
* char to be written will be in the lowest 16 bits of the <code>int</code>
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
* byte1 = (byte)(value & 0x00FF);</code>
* <p>
*
* The value written can be read using the <code>readShort</code> and
* <code>readUnsignedShort</code> methods in <code>DataInput</code>.
*
* @param value The int value to write as a 16-bit value
*
* @exception IOException If an error occurs
*
* @see DataInput#readShort
* @see DataInput#readUnsignedShort
*/
void writeShort(int value) throws IOException;
/**
* This method writes a Java int value to an output stream. The 4 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF000000) >> 24);<br>
* byte1 = (byte)((value & 0x00FF0000) >> 16);<br>
* byte2 = (byte)((value & 0x0000FF00) >> 8);<br>
* byte3 = (byte)(value & 0x000000FF);</code>
* <p>
*
* The value written can be read using the <code>readInt</code>
* method in <code>DataInput</code>.
*
* @param value The int value to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readInt
*/
void writeInt(int value) throws IOException;
/**
* This method writes a Java long value to an output stream. The 8 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00000000000000L) >> 56);<br>
* byte1 = (byte)((value & 0x00FF000000000000L) >> 48);<br>
* byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);<br>
* byte3 = (byte)((value & 0x000000FF00000000L) >> 32);<br>
* byte4 = (byte)((value & 0x00000000FF000000L) >> 24);<br>
* byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);<br>
* byte6 = (byte)((value & 0x000000000000FF00L) >> 8);<br>
* byte7 = (byte)(value & 0x00000000000000FFL);</code>
* <p>
*
* The value written can be read using the <code>readLong</code>
* method in <code>DataInput</code>.
*
* @param value The long value to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readLong
*/
void writeLong(long value) throws IOException;
/**
* This method writes a Java <code>float</code> value to the stream. This
* value is written by first calling the method
* <code>Float.floatToIntBits</code>
* to retrieve an <code>int</code> representing the floating point number,
* then writing this <code>int</code> value to the stream exactly the same
* as the <code>writeInt()</code> method does.
*
* The value written can be read using the <code>readFloat</code>
* method in <code>DataInput</code>.
*
* @param value The float value to write
*
* @exception IOException If an error occurs
*
* @see #writeInt
* @see DataInput#readFloat
* @see Float#floatToIntBits
*/
void writeFloat(float value) throws IOException;
/**
* This method writes a Java <code>double</code> value to the stream. This
* value is written by first calling the method
* <code>Double.doubleToLongBits</code>
* to retrieve an <code>long</code> representing the floating point number,
* then writing this <code>long</code> value to the stream exactly the same
* as the <code>writeLong()</code> method does.
*
* The value written can be read using the <code>readDouble</code>
* method in <code>DataInput</code>.
*
* @param value The double value to write
*
* @exception IOException If any other error occurs
*
* @see #writeLong
* @see DataInput#readDouble
* @see Double#doubleToLongBits
*/
void writeDouble(double value) throws IOException;
/**
* This method writes all the bytes in a <code>String</code> out to the
* stream. One byte is written for each character in the
* <code>String</code>.
* The high eight bits of each character are discarded, thus this
* method is inappropriate for completely representing Unicode characters.
*
* @param value The <code>String</code> to write
*
* @exception IOException If an error occurs
*/
void writeBytes(String value) throws IOException;
/**
* This method writes all the characters of a <code>String</code> to an
* output stream as an array of <code>char</code>'s. Each character
* is written using the method specified in the <code>writeChar</code>
* method.
*
* @param value The String to write
*
* @exception IOException If an error occurs
*
* @see #writeChar(int)
*/
void writeChars(String value) throws IOException;
/**
* This method writes a Java <code>String</code> to the stream in a modified
* UTF-8 format. First, two bytes are written to the stream indicating the
* number of bytes to follow. This is written in the form of a Java
* <code>short</code> value in the same manner used by the
* <code>writeShort</code> method. Note that this is the number of
* bytes in the
* encoded <code>String</code> not the <code>String</code> length. Next
* come the encoded characters. Each character in the <code>String</code>
* is encoded as either one, two or three bytes. For characters in the
* range of <code>\u0001</code> to <code>\u007F</code>, one byte is used.
* The character
* value goes into bits 0-7 and bit eight is 0. For characters in the range
* of <code>\u0080</code> to <code>\u007FF</code>, two bytes are used. Bits
* 6-10 of the character value are encoded bits 0-4 of the first byte, with
* the high bytes having a value of "110". Bits 0-5 of the character value
* are stored in bits 0-5 of the second byte, with the high bits set to
* "10". This type of encoding is also done for the null character
* <code>\u0000</code>. This eliminates any C style NUL character values
* in the output. All remaining characters are stored as three bytes.
* Bits 12-15 of the character value are stored in bits 0-3 of the first
* byte. The high bits of the first bytes are set to "1110". Bits 6-11
* of the character value are stored in bits 0-5 of the second byte. The
* high bits of the second byte are set to "10". And bits 0-5 of the
* character value are stored in bits 0-5 of byte three, with the high bits
* of that byte set to "10".
*
* The value written can be read using the <code>readUTF</code>
* method in <code>DataInput</code>.
*
* @param value The <code>String</code> to write
*
* @exception IOException If an error occurs
*
* @see DataInput#readUTF
*/
void writeUTF(String value) throws IOException;
/**
* This method writes an 8-bit value (passed into the method as a Java
* <code>int</code>) to an output stream. The low 8 bits of the
* passed value are written.
*
* @param value The <code>byte</code> to write to the output stream
*
* @exception IOException If an error occurs
*/
void write(int value) throws IOException;
/**
* This method writes the raw byte array passed in to the output stream.
*
* @param buf The byte array to write
*
* @exception IOException If an error occurs
*/
void write(byte[] buf) throws IOException;
/**
* This method writes raw bytes from the passed array <code>buf</code>
* starting
* <code>offset</code> bytes into the buffer. The number of bytes
* written will be exactly <code>len</code>.
*
* @param buf The buffer from which to write the data
* @param offset The offset into the buffer to start writing data from
* @param len The number of bytes to write from the buffer to the output
* stream
*
* @exception IOException If any other error occurs
*/
void write(byte[] buf, int offset, int len) throws IOException;
} // interface DataOutput
@@ -0,0 +1,455 @@
/* DataOutputStream.java -- Writes primitive Java datatypes to streams
Copyright (C) 1998, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This class provides a mechanism for writing primitive Java datatypes
* to an <code>OutputStream</code> in a portable way. Data written to
* a stream using this class can be read back in using the
* <code>DataInputStream</code> class on any platform.
*
* @see DataInputStream
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class DataOutputStream extends FilterOutputStream implements DataOutput
{
/**
* This is the total number of bytes that have been written to the
* stream by this object instance.
*/
protected int written;
/**
* This method initializes an instance of <code>DataOutputStream</code> to
* write its data to the specified underlying <code>OutputStream</code>
*
* @param out The subordinate <code>OutputStream</code> to which this
* object will write
*/
public DataOutputStream (OutputStream out)
{
super (out);
written = 0;
}
/**
* This method flushes any unwritten bytes to the underlying stream.
*
* @exception IOException If an error occurs.
*/
public void flush () throws IOException
{
out.flush();
}
/**
* This method returns the total number of bytes that have been written to
* the underlying output stream so far. This is the value of the
* <code>written</code> instance variable
*
* @return The number of bytes written to the stream.
*/
public final int size ()
{
return written;
}
/**
* This method writes the specified byte (passed as an <code>int</code>)
* to the underlying output stream.
*
* @param value The <code>byte</code> to write, passed as an <code>int</code>.
*
* @exception IOException If an error occurs.
*/
public synchronized void write (int value) throws IOException
{
out.write (value);
++written;
}
/**
* This method writes <code>len</code> bytes from the specified byte array
* <code>buf</code> starting at position <code>offset</code> into the
* buffer to the underlying output stream.
*
* @param buf The byte array to write from.
* @param offset The index into the byte array to start writing from.
* @param len The number of bytes to write.
*
* @exception IOException If an error occurs.
*/
public synchronized void write (byte[] buf, int offset, int len)
throws IOException
{
out.write(buf, offset, len);
written += len;
}
/**
* This method writes a Java boolean value to an output stream. If
* <code>value</code> is <code>true</code>, a byte with the value of
* 1 will be written, otherwise a byte with the value of 0 will be
* written.
*
* The value written can be read using the <code>readBoolean</code>
* method in <code>DataInput</code>.
*
* @param value The <code>boolean</code> value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readBoolean
*/
public final void writeBoolean (boolean value) throws IOException
{
write (value ? 1 : 0);
}
/**
* This method writes a Java byte value to an output stream. The
* byte to be written will be in the lowest 8 bits of the
* <code>int</code> value passed.
*
* The value written can be read using the <code>readByte</code> or
* <code>readUnsignedByte</code> methods in <code>DataInput</code>.
*
* @param value The <code>byte</code> to write to the stream, passed as
* the low eight bits of an <code>int</code>.
*
* @exception IOException If an error occurs
*
* @see DataInput#readByte
* @see DataInput#readUnsignedByte
*/
public final void writeByte (int value) throws IOException
{
write (value & 0xff);
}
/**
* This method writes a Java short value to an output stream. The
* char to be written will be in the lowest 16 bits of the <code>int</code>
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
* byte1 = (byte)(value & 0x00FF);</code>
* <p>
*
* The value written can be read using the <code>readShort</code> and
* <code>readUnsignedShort</code> methods in <code>DataInput</code>.
*
* @param value The <code>short</code> value to write to the stream,
* passed as an <code>int</code>.
*
* @exception IOException If an error occurs
*
* @see DataInput#readShort
* @see DataInput#readUnsignedShort
*/
public final synchronized void writeShort (int value) throws IOException
{
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java char value to an output stream. The
* char to be written will be in the lowest 16 bits of the <code>int</code>
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
* byte1 = (byte)(value & 0x00FF);</code>
* <p>
*
* The value written can be read using the <code>readChar</code>
* method in <code>DataInput</code>.
*
* @param value The <code>char</code> value to write,
* passed as an <code>int</code>.
*
* @exception IOException If an error occurs
*
* @see DataInput#readChar
*/
public final synchronized void writeChar (int value) throws IOException
{
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java int value to an output stream. The 4 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF000000) >> 24);<br>
* byte1 = (byte)((value & 0x00FF0000) >> 16);<br>
* byte2 = (byte)((value & 0x0000FF00) >> 8);<br>
* byte3 = (byte)(value & 0x000000FF);</code>
* <p>
*
* The value written can be read using the <code>readInt</code>
* method in <code>DataInput</code>.
*
* @param value The <code>int</code> value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readInt
*/
public final synchronized void writeInt (int value) throws IOException
{
write ((byte) (0xff & (value >> 24)));
write ((byte) (0xff & (value >> 16)));
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java long value to an output stream. The 8 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
* <p>
* <code>byte0 = (byte)((value & 0xFF00000000000000L) >> 56);<br>
* byte1 = (byte)((value & 0x00FF000000000000L) >> 48);<br>
* byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);<br>
* byte3 = (byte)((value & 0x000000FF00000000L) >> 32);<br>
* byte4 = (byte)((value & 0x00000000FF000000L) >> 24);<br>
* byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);<br>
* byte6 = (byte)((value & 0x000000000000FF00L) >> 8);<br>
* byte7 = (byte)(value & 0x00000000000000FFL);</code>
* <p>
*
* The value written can be read using the <code>readLong</code>
* method in <code>DataInput</code>.
*
* @param value The <code>long</code> value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readLong
*/
public final synchronized void writeLong (long value) throws IOException
{
write ((byte) (0xff & (value >> 56)));
write ((byte) (0xff & (value>> 48)));
write ((byte) (0xff & (value>> 40)));
write ((byte) (0xff & (value>> 32)));
write ((byte) (0xff & (value>> 24)));
write ((byte) (0xff & (value>> 16)));
write ((byte) (0xff & (value>> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java <code>float</code> value to the stream. This
* value is written by first calling the method
* <code>Float.floatToIntBits</code>
* to retrieve an <code>int</code> representing the floating point number,
* then writing this <code>int</code> value to the stream exactly the same
* as the <code>writeInt()</code> method does.
*
* The value written can be read using the <code>readFloat</code>
* method in <code>DataInput</code>.
*
* @param value The <code>float</code> value to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeInt
* @see DataInput#readFloat
* @see Float#floatToIntBits
*/
public final void writeFloat (float value) throws IOException
{
writeInt (Float.floatToIntBits (value));
}
/**
* This method writes a Java <code>double</code> value to the stream. This
* value is written by first calling the method
* <code>Double.doubleToLongBits</code>
* to retrieve an <code>long</code> representing the floating point number,
* then writing this <code>long</code> value to the stream exactly the same
* as the <code>writeLong()</code> method does.
*
* The value written can be read using the <code>readDouble</code>
* method in <code>DataInput</code>.
*
* @param value The <code>double</code> value to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeLong
* @see DataInput#readDouble
* @see Double#doubleToLongBits
*/
public final void writeDouble (double value) throws IOException
{
writeLong (Double.doubleToLongBits (value));
}
/**
* This method writes all the bytes in a <code>String</code> out to the
* stream. One byte is written for each character in the
* <code>String</code>.
* The high eight bits of each character are discarded, thus this
* method is inappropriate for completely representing Unicode characters.
*
* @param value The <code>String</code> to write to the stream
*
* @exception IOException If an error occurs
*/
public final void writeBytes (String value) throws IOException
{
int len = value.length();
for (int i = 0; i < len; ++i)
writeByte (value.charAt(i));
}
/**
* This method writes all the characters of a <code>String</code> to an
* output stream as an array of <code>char</code>'s. Each character
* is written using the method specified in the <code>writeChar</code>
* method.
*
* @param value The <code>String</code> to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeChar
*/
public final void writeChars (String value) throws IOException
{
int len = value.length();
for (int i = 0; i < len; ++i)
writeChar (value.charAt(i));
}
/**
* This method writes a Java <code>String</code> to the stream in a modified
* UTF-8 format. First, two bytes are written to the stream indicating the
* number of bytes to follow. Note that this is the number of bytes in the
* encoded <code>String</code> not the <code>String</code> length. Next
* come the encoded characters. Each character in the <code>String</code>
* is encoded as either one, two or three bytes. For characters in the
* range of <code>\u0001</code> to <\u007F>, one byte is used. The character
* value goes into bits 0-7 and bit eight is 0. For characters in the range
* of <code>\u0080</code> to <code>\u007FF</code>, two bytes are used. Bits
* 6-10 of the character value are encoded bits 0-4 of the first byte, with
* the high bytes having a value of "110". Bits 0-5 of the character value
* are stored in bits 0-5 of the second byte, with the high bits set to
* "10". This type of encoding is also done for the null character
* <code>\u0000</code>. This eliminates any C style NUL character values
* in the output. All remaining characters are stored as three bytes.
* Bits 12-15 of the character value are stored in bits 0-3 of the first
* byte. The high bits of the first bytes are set to "1110". Bits 6-11
* of the character value are stored in bits 0-5 of the second byte. The
* high bits of the second byte are set to "10". And bits 0-5 of the
* character value are stored in bits 0-5 of byte three, with the high bits
* of that byte set to "10".
*
* The value written can be read using the <code>readUTF</code>
* method in <code>DataInput</code>.
*
* @param value The <code>String</code> to write to the output in UTF format
*
* @exception IOException If an error occurs
*
* @see DataInput#readUTF
*/
public final synchronized void writeUTF(String value) throws IOException
{
int len = value.length();
int sum = 0;
for (int i = 0; i < len && sum <= 65535; ++i)
{
char c = value.charAt(i);
if (c >= '\u0001' && c <= '\u007f')
sum += 1;
else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
sum += 2;
else
sum += 3;
}
if (sum > 65535)
throw new UTFDataFormatException ();
int pos = 0;
byte[] buf = new byte[sum];
for (int i = 0; i < len; ++i)
{
char c = value.charAt(i);
if (c >= '\u0001' && c <= '\u007f')
buf[pos++] = (byte) c;
else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
{
buf[pos++] = (byte) (0xc0 | (0x1f & (c >> 6)));
buf[pos++] = (byte) (0x80 | (0x3f & c));
}
else
{
// JSL says the first byte should be or'd with 0xc0, but
// that is a typo. Unicode says 0xe0, and that is what is
// consistent with DataInputStream.
buf[pos++] = (byte) (0xe0 | (0x0f & (c >> 12)));
buf[pos++] = (byte) (0x80 | (0x3f & (c >> 6)));
buf[pos++] = (byte) (0x80 | (0x3f & c));
}
}
writeShort (sum);
write(buf, 0, sum);
}
} // class DataOutputStream
@@ -0,0 +1,109 @@
/* DeleteFileHelper.java -- Helper class to delete files on VM exit
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @author Jeroen Frijters (jeroen@sumatra.nl)
* @author Michael Koch (konqueror@gmx.de)
*/
final class DeleteFileHelper extends Thread
{
private static ArrayList filesToDelete;
static synchronized void add(File file)
{
if (filesToDelete == null)
{
filesToDelete = new ArrayList();
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
try
{
Runtime.getRuntime().addShutdownHook(new DeleteFileHelper());
}
catch (IllegalStateException e)
{
// Shutdown is already in progress, so we can't
// register ours.
}
return null;
}
});
}
filesToDelete.add(file);
}
private static synchronized void deleteFiles()
{
Iterator it = filesToDelete.iterator();
while (it.hasNext())
{
try
{
File file = (File) it.next();
file.delete();
}
catch (Exception e)
{
// Do nothing here.
}
}
}
// Package-private to avoid a trampoline constructor.
DeleteFileHelper()
{
}
public void run()
{
deleteFiles();
}
}
@@ -0,0 +1,76 @@
/* EOFException.java -- unexpected end of file exception
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when the end of the file or stream was
* encountered unexpectedly. This is not the normal way that an EOF
* condition is reported; such as a special value like -1 being returned.
* However, certain types of streams expecting certain data in a certain
* format might reach EOF before reading their expected data pattern and
* thus throw this exception.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @status updated to 1.4
*/
public class EOFException extends IOException
{
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = 6433858223774886977L;
/**
* Create an exception without a descriptive error message.
*/
public EOFException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public EOFException(String message)
{
super(message);
}
} // class EOFException
@@ -0,0 +1,107 @@
/* Externalizable.java -- Interface for saving and restoring object data
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This interface provides a way that classes can completely control how
* the data of their object instances are written and read to and from
* streams. It has two methods which are used to write the data to a stream
* and to read the data from a stream. The read method must read the data
* in exactly the way it was written by the write method.
* <p>
* Note that classes which implement this interface must take into account
* that all superclass data must also be written to the stream as well.
* The class implementing this interface must figure out how to make that
* happen.
* <p>
* This interface can be used to provide object persistence. When an
* object is to be stored externally, the <code>writeExternal</code> method is
* called to save state. When the object is restored, an instance is
* created using the default no-argument constructor and the
* <code>readExternal</code> method is used to restore the state.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public interface Externalizable extends Serializable
{
/**
* This method restores an object's state by reading in the instance data
* for the object from the passed in stream. Note that this stream is not
* a subclass of <code>InputStream</code>, but rather is a class that
* implements
* the <code>ObjectInput</code> interface. That interface provides a
* mechanism for
* reading in Java data types from a stream.
* <p>
* Note that this method must be compatible with <code>writeExternal</code>.
* It must read back the exact same types that were written by that
* method in the exact order they were written.
* <p>
* If this method needs to read back an object instance, then the class
* for that object must be found and loaded. If that operation fails,
* then this method throws a <code>ClassNotFoundException</code>
*
* @param in An <code>ObjectInput</code> instance for reading in the object
* state
*
* @exception ClassNotFoundException If the class of an object being
* restored cannot be found
* @exception IOException If any other error occurs
*/
void readExternal(ObjectInput in)
throws ClassNotFoundException, IOException;
/**
* This method is responsible for writing the instance data of an object
* to the passed in stream. Note that this stream is not a subclass of
* <code>OutputStream</code>, but rather is a class that implements the
* <code>ObjectOutput</code> interface. That interface provides a
* number of methods
* for writing Java data values to a stream.
* <p>
* Not that the implementation of this method must be coordinated with
* the implementation of <code>readExternal</code>.
*
* @param out An <code>ObjectOutput</code> instance for writing the
* object state
*
* @exception IOException If an error occurs
*/
void writeExternal(ObjectOutput out) throws IOException;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,139 @@
/* FileDescriptor.java -- Opaque file handle class
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import java.nio.channels.ByteChannel;
import java.nio.channels.FileChannel;
/**
* This class represents an opaque file handle as a Java class. It should
* be used only to pass to other methods that expect an object of this
* type. No system specific information can be obtained from this object.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @date September 24, 1998
*/
public final class FileDescriptor
{
/**
* A <code>FileDescriptor</code> representing the system standard input
* stream. This will usually be accessed through the
* <code>System.in</code>variable.
*/
public static final FileDescriptor in
= new FileDescriptor (FileChannelImpl.in);
/**
* A <code>FileDescriptor</code> representing the system standard output
* stream. This will usually be accessed through the
* <code>System.out</code>variable.
*/
public static final FileDescriptor out
= new FileDescriptor (FileChannelImpl.out);
/**
* A <code>FileDescriptor</code> representing the system standard error
* stream. This will usually be accessed through the
* <code>System.err</code>variable.
*/
public static final FileDescriptor err
= new FileDescriptor (FileChannelImpl.err);
final ByteChannel channel;
/**
* This method is used to initialize an invalid FileDescriptor object.
*/
public FileDescriptor()
{
channel = null;
}
/**
* This method is used to initialize a FileDescriptor object.
*/
FileDescriptor(ByteChannel channel)
{
this.channel = channel;
}
/**
* This method forces all data that has not yet been physically written to
* the underlying storage medium associated with this
* <code>FileDescriptor</code>
* to be written out. This method will not return until all data has
* been fully written to the underlying device. If the device does not
* support this functionality or if an error occurs, then an exception
* will be thrown.
*/
public void sync () throws SyncFailedException
{
if (channel instanceof FileChannel)
{
try
{
((FileChannel) channel).force(true);
}
catch (IOException ex)
{
if (ex instanceof SyncFailedException)
throw (SyncFailedException) ex;
else
throw new SyncFailedException(ex.toString());
}
}
}
/**
* This methods tests whether or not this object represents a valid open
* native file handle.
*
* @return <code>true</code> if this object represents a valid
* native file handle, <code>false</code> otherwise
*/
public boolean valid ()
{
return channel != null && channel.isOpen();
}
}
+65
View File
@@ -0,0 +1,65 @@
/* FileFilter.java -- Filter a list of pathnames
Copyright (C) 1998,2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This interface has one method which is used for filtering pathnames
* returned in a pathname listing. It is currently used by the
* <code>File.listFiles(FileFilter)</code> method.
* <p>
* The method in this interface determines if a particular pathname should
* or should not be included in the pathname listing.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*
* @see File#listFiles(java.io.FileFilter)
*/
public interface FileFilter
{
/**
* This method determines whether or not a given pathname should be included
* in a pathname listing.
*
* @param pathname The pathname to test
*
* @return <code>true</code> if the path should be included in the list,
* <code>false</code> otherwise.
*/
boolean accept(File pathname);
}
@@ -0,0 +1,309 @@
/* FileInputStream.java -- An input stream that reads from disk files.
Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import java.nio.channels.FileChannel;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This class is a stream that reads its bytes from a file.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class FileInputStream extends InputStream
{
/**
* This is the native file handle for the file this stream is reading from
*/
private FileDescriptor fd;
private FileChannelImpl ch;
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified named file. A security check is first made to determine
* whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the
* <code>SecurityManager</code>
* (if one exists) with the name of this file. An exception is thrown
* if reading is not allowed. If the file does not exist, an exception
* is also thrown.
*
* @param name The name of the file this stream should read from
*
* @exception SecurityException If read access to the file is not allowed
* @exception FileNotFoundException If the file does not exist
* or if it is a directory
*/
public FileInputStream(String name) throws FileNotFoundException
{
this(new File(name));
}
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified <code>File</code> object. A security check is first
* made to determine
* whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the
* <code>SecurityManager</code>
* (if one exists) with the name of this file. An exception is thrown
* if reading is not allowed. If the file does not exist, an exception
* is also thrown.
*
* @param file The <code>File</code> object this stream should read from
*
* @exception SecurityException If read access to the file is not allowed
* @exception FileNotFoundException If the file does not exist
* or if it is a directory.
*/
public FileInputStream(File file) throws FileNotFoundException
{
SecurityManager s = System.getSecurityManager();
if (s != null)
s.checkRead(file.getPath());
ch = FileChannelImpl.create(file, FileChannelImpl.READ);
}
/**
* This method initializes a <code>FileInputStream</code> to read from the
* specified <code>FileDescriptor</code> object. A security
* check is first made to
* determine whether or not access to this file is allowed. This is done by
* calling the <code>checkRead()</code> method of the
* <code>SecurityManager</code>
* (if one exists) with the specified <code>FileDescriptor</code>
* An exception is
* thrown if reading is not allowed.
*
* @param fdObj The <code>FileDescriptor</code> object this stream
* should read from
*
* @exception SecurityException If read access to the file is not allowed
*/
public FileInputStream(FileDescriptor fdObj)
{
SecurityManager s = System.getSecurityManager();
if (s != null)
s.checkRead(fdObj);
fd = fdObj;
ch = (FileChannelImpl) fdObj.channel;
}
FileInputStream(FileChannelImpl ch)
{
this.ch = ch;
}
/**
* This method returns the number of bytes that can be read from this
* stream before a read can block. A return of 0 indicates that blocking
* might (or might not) occur on the very next read attempt.
* <p>
* This method returns the number of unread bytes remaining in the file if
* the descriptor being read from is an actual file. If this method is
* reading from a ''special'' file such a the standard input, this method
* will return the appropriate value for the stream being read.
* <p>
* Be aware that reads on plain files that do not reside locally might
* possibly block even if this method says they should not. For example,
* a remote server might crash, preventing an NFS mounted file from being
* read.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
return ch.available();
}
/**
* This method closes the stream. Any futher attempts to read from the
* stream will likely generate an IOException since the underlying file
* will be closed.
*
* @exception IOException If an error occurs.
*/
public void close() throws IOException
{
ch.close();
}
protected void finalize() throws IOException
{
// We don't actually need this, but we include it because it is
// mentioned in the JCL.
}
/**
* This method returns a <code>FileDescriptor</code> object representing the
* underlying native file handle of the file this stream is reading
* from
*
* @return A <code>FileDescriptor</code> for this stream
*
* @exception IOException If an error occurs
*/
public final FileDescriptor getFD() throws IOException
{
synchronized (this)
{
if (fd == null)
fd = new FileDescriptor (ch);
return fd;
}
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
return ch.read();
}
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. This method attempts to completely fill the buffer,
* but can return before doing so. The actual number of bytes read is
* returned as an int. A -1 is returned to indicate the end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling an overloaded read method like so:
* <code>read(buf, 0, buf.length)</code>
*
* @param buf The buffer into which the bytes read will be stored.
*
* @return The number of bytes read or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(byte[] buf) throws IOException
{
return read(buf, 0, buf.length);
}
/**
* This method read bytes from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index
* <code>offset</code> into
* the buffer and attempts to read <code>len</code> bytes. This method can
* return before reading the number of bytes requested. The actual number
* of bytes read is returned as an int. A -1 is returned to indicate the
* end of the stream.
* <p>
* This method will block until some data can be read.
*
* @param buf The array into which the bytes read should be stored
* @param offset The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(byte[] buf, int offset, int len) throws IOException
{
if (offset < 0
|| len < 0
|| offset + len > buf.length)
throw new ArrayIndexOutOfBoundsException();
return ch.read(buf, offset, len);
}
/**
* This method skips the specified number of bytes in the stream. It
* returns the actual number of bytes skipped, which may be less than the
* requested amount.
* <p>
* @param numBytes The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs
*/
public synchronized long skip (long numBytes) throws IOException
{
if (numBytes < 0)
throw new IllegalArgumentException ("Can't skip negative bytes: " +
numBytes);
if (numBytes == 0)
return 0;
long oldPos = ch.position ();
ch.position(oldPos + numBytes);
return ch.position() - oldPos;
}
/**
* This method creates a java.nio.channels.FileChannel.
* Nio does not allow one to create a file channel directly.
* A file channel must be created by first creating an instance of
* Input/Output/RandomAccessFile and invoking the getChannel() method on it.
*/
public synchronized FileChannel getChannel ()
{
return ch;
}
} // class FileInputStream
@@ -0,0 +1,73 @@
/* FileNotFoundException.java -- the requested file could not be found
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when an attempt is made to access a file that
* does not exist, or is inaccessible for some other reason (such as writing
* a read-only file).
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @status updated to 1.4
*/
public class FileNotFoundException extends IOException
{
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = -897856973823710492L;
/**
* Create an exception without a descriptive error message.
*/
public FileNotFoundException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public FileNotFoundException(String message)
{
super(message);
}
} // class FileNotFoundException
@@ -0,0 +1,296 @@
/* FileOutputStream.java -- Writes to a file on disk.
Copyright (C) 1998, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import java.nio.channels.FileChannel;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This classes allows a stream of data to be written to a disk file or
* any open <code>FileDescriptor</code>.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class FileOutputStream extends OutputStream
{
private FileDescriptor fd;
private FileChannelImpl ch;
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the named file. The file is created if it does not exist, and
* the bytes written are written starting at the beginning of the file if
* the <code>append</code> argument is <code>false</code> or at the end
* of the file if the <code>append</code> argument is true.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param path The name of the file this stream should write to
* @param append <code>true</code> to append bytes to the end of the file,
* or <code>false</code> to write bytes to the beginning
*
* @exception SecurityException If write access to the file is not allowed
* @exception FileNotFoundException If a non-security error occurs
*/
public FileOutputStream (String path, boolean append)
throws SecurityException, FileNotFoundException
{
this (new File(path), append);
}
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the named file. The file is created if it does not exist, and
* the bytes written are written starting at the beginning of the file.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param path The name of the file this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
* @exception FileNotFoundException If a non-security error occurs
*/
public FileOutputStream (String path)
throws SecurityException, FileNotFoundException
{
this (path, false);
}
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the specified <code>File</code> object. The file is created if it
* does not exist, and the bytes written are written starting at the
* beginning of the file.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param file The <code>File</code> object this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
* @exception FileNotFoundException If a non-security error occurs
*/
public FileOutputStream (File file)
throws SecurityException, FileNotFoundException
{
this (file, false);
}
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the specified <code>File</code> object. The file is created if it
* does not exist, and the bytes written are written starting at the
* beginning of the file if the <code>append</code> parameter is
* <code>false</code>. Otherwise bytes are written at the end of the
* file.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the name of the file to be opened. An exception is
* thrown if writing is not allowed.
*
* @param file The <code>File</code> object this stream should write to
* @param append <code>true</code> to append bytes to the end of the file,
* or <code>false</code> to write bytes to the beginning
*
* @exception SecurityException If write access to the file is not allowed
* @exception FileNotFoundException If a non-security error occurs
*/
public FileOutputStream (File file, boolean append)
throws FileNotFoundException
{
SecurityManager s = System.getSecurityManager();
if (s != null)
s.checkWrite(file.getPath());
ch = FileChannelImpl.create(file, (append
? FileChannelImpl.WRITE
| FileChannelImpl.APPEND
: FileChannelImpl.WRITE));
}
/**
* This method initializes a <code>FileOutputStream</code> object to write
* to the file represented by the specified <code>FileDescriptor</code>
* object. This method does not create any underlying disk file or
* reposition the file pointer of the given descriptor. It assumes that
* this descriptor is ready for writing as is.
* <p>
* Before opening a file, a security check is performed by calling the
* <code>checkWrite</code> method of the <code>SecurityManager</code> (if
* one exists) with the specified <code>FileDescriptor</code> as an argument.
* An exception is thrown if writing is not allowed.
*
* @param fdObj The <code>FileDescriptor</code> this stream should write to
*
* @exception SecurityException If write access to the file is not allowed
*/
public FileOutputStream (FileDescriptor fdObj)
throws SecurityException
{
// Hmm, no other exception but this one to throw, but if the descriptor
// isn't valid, we surely don't have "permission" to write to it.
if (!fdObj.valid())
throw new SecurityException("Invalid FileDescriptor");
SecurityManager s = System.getSecurityManager();
if (s != null)
s.checkWrite(fdObj);
fd = fdObj;
ch = (FileChannelImpl) fdObj.channel;
}
FileOutputStream(FileChannelImpl ch)
{
this.ch = ch;
}
protected void finalize () throws IOException
{
// We don't actually need this, but we include it because it is
// mentioned in the JCL.
}
/**
* This method returns a <code>FileDescriptor</code> object representing
* the file that is currently being written to
*
* @return A <code>FileDescriptor</code> object for this stream
*
* @exception IOException If an error occurs
*/
public final FileDescriptor getFD () throws IOException
{
synchronized (this)
{
if (fd == null)
fd = new FileDescriptor (ch);
return fd;
}
}
/**
* This method writes a single byte of data to the file.
*
* @param b The byte of data to write, passed as an <code>int</code>
*
* @exception IOException If an error occurs
*/
public void write (int b) throws IOException
{
ch.write (b);
}
/**
* This method writes all the bytes in the specified array to the
* file.
*
* @param buf The array of bytes to write to the file
*
* @exception IOException If an error occurs
*/
public void write (byte[] buf)
throws IOException
{
write (buf, 0, buf.length);
}
/**
* This method writes <code>len</code> bytes from the byte array
* <code>buf</code> to the file starting at index <code>offset</code>.
*
* @param buf The array of bytes to write to the file
* @param offset The offset into the array to start writing bytes from
* @param len The number of bytes to write to the file
*
* @exception IOException If an error occurs
*/
public void write (byte[] buf, int offset, int len)
throws IOException
{
if (offset < 0
|| len < 0
|| offset + len > buf.length)
throw new ArrayIndexOutOfBoundsException ();
ch.write (buf, offset, len);
}
/**
* This method closes the underlying file. Any further attempts to
* write to this stream will likely generate an exception since the
* file is closed.
*
* @exception IOException If an error occurs
*/
public void close () throws IOException
{
ch.close();
}
/**
* This method creates a java.nio.channels.FileChannel.
* Nio does not allow one to create a file channel directly.
* A file channel must be created by first creating an instance of
* Input/Output/RandomAccessFile and invoking the getChannel() method on it.
*/
public synchronized FileChannel getChannel()
{
return ch;
}
} // class FileOutputStream
@@ -0,0 +1,292 @@
/* FilePermission.java --
Copyright (C) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.security.Permission;
public final class FilePermission extends Permission implements Serializable
{
private static final long serialVersionUID = 7930732926638008763L;
private static final String CURRENT_DIRECTORY =
System.getProperty("user.dir");
private static final String ALL_FILES = "<<ALL FILES>>";
private boolean readPerm = false;
private boolean writePerm = false;
private boolean executePerm = false;
private boolean deletePerm = false;
private final String actionsString;
// Checks and caches the actions
private void checkPerms() throws IllegalArgumentException
{
String action;
int i = actionsString.indexOf(',');
int startI = 0;
while (i != -1)
{
action = actionsString.substring(startI, i).trim().toLowerCase();
if (action.equals("read"))
readPerm = true;
else if (action.equals("write"))
writePerm = true;
else if (action.equals("execute"))
executePerm = true;
else if (action.equals("delete"))
deletePerm = true;
else
throw new IllegalArgumentException("Unknown action: " + action);
startI = i + 1;
i = actionsString.indexOf(',', startI);
}
action = actionsString.substring(startI).trim().toLowerCase();
if (action.equals("read"))
readPerm = true;
else if (action.equals("write"))
writePerm = true;
else if (action.equals("execute"))
executePerm = true;
else if (action.equals("delete"))
deletePerm = true;
else
throw new IllegalArgumentException("Unknown action: " + action);
}
/**
* Create a new FilePermission.
*
* @param pathExpression an expression specifying the paths this
* permission represents.
* @param actionsString a comma-separated list of the actions this
* permission represents. The actions must be "read", "write",
* "execute" and/or "delete".
*/
public FilePermission(String pathExpression, String actionsString)
{
// FIXME: what to do when the file string is malformed?
super(pathExpression);
if (pathExpression == null)
throw new NullPointerException("pathExpression");
if (actionsString == null)
throw new IllegalArgumentException("actionsString");
this.actionsString = actionsString;
checkPerms();
}
/**
* Get the actions this FilePermission supports.
* @return the String representing the actions this FilePermission supports.
*/
public String getActions()
{
return actionsString;
}
/**
* Get the hash code for this Object.<P>
* FilePermission's hash code is calculated as the exclusive or of the
* target
* String's hash code and the action String's hash code.
* @specnote Sun did not specify how to calculate the hash code;
* I made this up.
* @return the hash code for this Object.
*/
public int hashCode()
{
return getName().hashCode() ^ actionsString.hashCode();
}
/**
* Check two FilePermissions for semantic equality.
* Two FilePermissions are exactly equivalent if they have identical path
* expressions and have exactly the same access permissions.
* @param o the Object to compare to.
* @return whether the Objects are semantically equivalent.
*/
public boolean equals(Object o)
{
if (! (o instanceof FilePermission))
return false;
FilePermission p = (FilePermission) o;
String f1 = getName();
String f2 = p.getName();
// Compare names, taking into account if they refer to a directory
// and one has a separator and the other does not.
if (f1.length() > 0 && f1.charAt(f1.length() - 1) == File.separatorChar)
{
if (f2.length() > 0
&& f2.charAt(f2.length() - 1) == File.separatorChar)
{
if (! f2.equals(f1))
return false;
}
else
{
if (! f2.equals(f1.substring(0, f1.length() - 1)))
return false;
}
}
else
{
if (f2.length() > 0
&& f2.charAt(f2.length() - 1) == File.separatorChar)
{
if (! f1.equals(f2.substring(0, f2.length() - 1)))
return false;
}
else
{
if (! f1.equals(f2))
return false;
}
}
return (readPerm == p.readPerm
&& writePerm == p.writePerm
&& executePerm == p.executePerm
&& deletePerm == p.deletePerm);
}
/**
* Check to see if this permission implies another.
* Permission A implies permission B if these things are all true:
* <OL>
* <LI>A and B are both FilePermissions.</LI>
* <LI>All possible files in B are included in A
* (possibly more are in A).</LI>
* <LI>All actions B supports, A also supports.</LI>
* </OL>
* @param p the Permission to compare against.
* @return whether this Permission implies p
*/
public boolean implies(Permission p)
{
if (! (p instanceof FilePermission))
return false;
String f1 = getName();
if (f1.equals(ALL_FILES))
return true;
FilePermission fp = (FilePermission) p;
String f2 = fp.getName();
if (f1.charAt(0) != File.separatorChar)
f1 = CURRENT_DIRECTORY + f1;
if (f2.charAt(0) != File.separatorChar)
f2 = CURRENT_DIRECTORY + f2;
String sub1;
switch (f1.charAt(f1.length() - 1))
{
case '*':
sub1 = f1.substring(0, f1.length() - 1); // chop off "*"
if (f2.length() <= sub1.length())
{
// If it's smaller, there is no way it could be part of
// this directory. If it's the same (or length - 1), it
// could be the same directory but specifies access to
// the directory rather than the files in it.
return false;
}
else if (f2.charAt(sub1.length() - 1) == File.separatorChar)
{
// Make sure the part before the "/" is the same.
if (! f2.substring(0, sub1.length()).equals(sub1))
return false;
// Make sure there are no subdirectories specified
// underneath this one.
if (f2.substring(sub1.length() + 1).indexOf(File.separatorChar)
!= -1)
return false;
}
else
{
// Obviously not equal: f2 is either not a directory or
// is not the same directory (its name continues further
// than we want).
return false;
}
break;
case '-':
// Chop off "/-".
sub1 = f1.substring(0, f1.length() - 2);
if (f2.length() < sub1.length())
{
// If it's smaller, there is no way it could be part of
// this directory.
return false;
}
else if (f2.length() > sub1.length()
&& f2.charAt(sub1.length()) != File.separatorChar)
return false;
else if (! f2.substring(0, sub1.length()).equals(sub1))
return false;
break;
default:
if (f2.charAt(f2.length() - 1) == File.separatorChar)
{
if (! f1.equals(f2.substring(0, f2.length() - 1)))
return false;
}
else if (!f1.equals(f2))
return false;
break;
}
if (readPerm && ! fp.readPerm)
return false;
if (writePerm && ! fp.writePerm)
return false;
if (executePerm && ! fp.executePerm)
return false;
if (deletePerm && ! fp.deletePerm)
return false;
return true;
}
}
+92
View File
@@ -0,0 +1,92 @@
/* FileReader.java -- Convenience class for reading characters from a file
Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class provides a convenient way to set up a <code>Reader</code>
* to read from a file. It opens the specified file for reading and creates
* the <code>InputStreamReader</code> to read from the
* resulting <code>FileInputStream</code>. This class can only be used
* to read from files using the default character encoding. Use
* <code>InputStreamReader</code> directly to use a non-default encoding.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class FileReader extends InputStreamReader
{
/**
* This method initializes a <code>FileReader</code> instance to read from
* the specified <code>File</code> object.
*
* @param file The <code>File</code> object representing the file to read from
*
* @exception FileNotFoundException If the file is not found or some other
* error occurs
*/
public FileReader(File file) throws FileNotFoundException
{
super(new FileInputStream(file));
}
/**
* This method initializes a <code>FileReader</code> instance to read from
* this specified <code>FileDescriptor</code> object.
*
* @param fd The <code>FileDescriptor</code> to read from.
*/
public FileReader(FileDescriptor fd)
{
super(new FileInputStream(fd));
}
/**
* This method initializes a <code>FileReader</code> instance to read from
* the specified named file.
*
* @param name The name of the file to read from
*
* @exception FileNotFoundException If the file is not found or some other
* error occurs
*/
public FileReader(String name) throws FileNotFoundException
{
super(new FileInputStream(name));
}
} // class FileReader
+137
View File
@@ -0,0 +1,137 @@
/* FileWriter.java -- Convenience class for writing to files.
Copyright (C) 1998, 1999, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This is a convenience class for writing to files. It creates an
* <code>FileOutputStream</code> and initializes an
* <code>OutputStreamWriter</code> to write to it.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class FileWriter extends OutputStreamWriter
{
/**
* This method initializes a new <code>FileWriter</code> object to write
* to the specified <code>File</code> object.
*
* @param file The <code>File</code> object to write to.
*
* @throws SecurityException If writing to this file is forbidden by the
* <code>SecurityManager</code>.
* @throws IOException If any other error occurs
*/
public FileWriter(File file) throws SecurityException, IOException
{
super(new FileOutputStream(file));
}
/**
* This method initializes a new <code>FileWriter</code> object to write
* to the specified <code>File</code> object.
*
* @param file The <code>File</code> object to write to.
* @param append <code>true</code> to start adding data at the end of the
* file, <code>false</code> otherwise.
*
* @throws SecurityException If writing to this file is forbidden by the
* <code>SecurityManager</code>.
* @throws IOException If any other error occurs
*/
public FileWriter(File file, boolean append) throws IOException
{
super(new FileOutputStream(file, append));
}
/**
* This method initializes a new <code>FileWriter</code> object to write
* to the specified <code>FileDescriptor</code> object.
*
* @param fd The <code>FileDescriptor</code> object to write to
*
* @throws SecurityException If writing to this file is forbidden by the
* <code>SecurityManager</code>.
*/
public FileWriter(FileDescriptor fd) throws SecurityException
{
super(new FileOutputStream(fd));
}
/**
* This method intializes a new <code>FileWriter</code> object to
* write to the
* specified named file.
*
* @param name The name of the file to write to
*
* @throws SecurityException If writing to this file is forbidden by the
* <code>SecurityManager</code>.
* @throws IOException If any other error occurs
*/
public FileWriter(String name) throws IOException
{
super(new FileOutputStream(name));
}
/**
* This method intializes a new <code>FileWriter</code> object to
* write to the
* specified named file. This form of the constructor allows the caller
* to determin whether data should be written starting at the beginning or
* the end of the file.
*
* @param name The name of the file to write to
* @param append <code>true</code> to start adding data at the end of the
* file, <code>false</code> otherwise.
*
* @throws SecurityException If writing to this file is forbidden by the
* <code>SecurityManager</code>.
* @throws IOException If any other error occurs
*/
public FileWriter(String name, boolean append) throws IOException
{
super(new FileOutputStream(name, append));
}
}
@@ -0,0 +1,76 @@
/* FilenameFilter.java -- Filter a list of filenames
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to 1.1.
*/
/**
* This interface has one method which is used for filtering filenames
* returned in a directory listing. It is currently used by the
* <code>File.list(FilenameFilter)</code> method and by the filename
* dialog in AWT.
* <p>
* The method in this interface determines if a particular file should
* or should not be included in the file listing.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*
* @see File#listFiles(java.io.FilenameFilter)
* @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
*/
public interface FilenameFilter
{
/**
* This method determines whether or not a given file should be included
* in a directory listing.
*
* @param dir The <code>File</code> instance for the directory being read
* @param name The name of the file to test
*
* @return <code>true</code> if the file should be included in the list,
* <code>false</code> otherwise.
*/
boolean accept(File dir, String name);
} // interface FilenameFilter
@@ -0,0 +1,203 @@
/* FilterInputStream.java -- Base class for classes that filter input
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This is the common superclass of all standard classes that filter
* input. It acts as a layer on top of an underlying <code>InputStream</code>
* and simply redirects calls made to it to the subordinate InputStream
* instead. Subclasses of this class perform additional filtering
* functions in addition to simply redirecting the call.
* <p>
* This class is not abstract. However, since it only redirects calls
* to a subordinate <code>InputStream</code> without adding any functionality
* on top of it, this class should not be used directly. Instead, various
* subclasses of this class should be used. This is enforced with a
* protected constructor. Do not try to hack around it.
* <p>
* When creating a subclass of <code>FilterInputStream</code>, override the
* appropriate methods to implement the desired filtering. However, note
* that the <code>read(byte[])</code> method does not need to be overridden
* as this class redirects calls to that method to
* <code>read(byte[], int, int)</code> instead of to the subordinate
* <code>InputStream read(byte[])</code> method.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class FilterInputStream extends InputStream
{
/**
* This is the subordinate <code>InputStream</code> to which method calls
* are redirected
*/
protected InputStream in;
/**
* Create a <code>FilterInputStream</code> with the specified subordinate
* <code>InputStream</code>.
*
* @param in The subordinate <code>InputStream</code>
*/
protected FilterInputStream(InputStream in)
{
this.in = in;
}
/**
* Calls the <code>in.mark(int)</code> method.
*
* @param readlimit The parameter passed to <code>in.mark(int)</code>
*/
public void mark(int readlimit)
{
in.mark(readlimit);
}
/**
* Calls the <code>in.markSupported()</code> method.
*
* @return <code>true</code> if mark/reset is supported, <code>false</code>
* otherwise
*/
public boolean markSupported()
{
return in.markSupported();
}
/**
* Calls the <code>in.reset()</code> method.
*
* @exception IOException If an error occurs
*/
public void reset() throws IOException
{
in.reset();
}
/**
* Calls the <code>in.available()</code> method.
*
* @return The value returned from <code>in.available()</code>
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
return in.available();
}
/**
* Calls the <code>in.skip(long)</code> method
*
* @param numBytes The requested number of bytes to skip.
*
* @return The value returned from <code>in.skip(long)</code>
*
* @exception IOException If an error occurs
*/
public long skip(long numBytes) throws IOException
{
return in.skip(numBytes);
}
/**
* Calls the <code>in.read()</code> method
*
* @return The value returned from <code>in.read()</code>
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
return in.read();
}
/**
* Calls the <code>read(byte[], int, int)</code> overloaded method.
* Note that
* this method does not redirect its call directly to a corresponding
* method in <code>in</code>. This allows subclasses to override only the
* three argument version of <code>read</code>.
*
* @param buf The buffer to read bytes into
*
* @return The value retured from <code>in.read(byte[], int, int)</code>
*
* @exception IOException If an error occurs
*/
public int read(byte[] buf) throws IOException
{
return read(buf, 0, buf.length);
}
/**
* Calls the <code>in.read(byte[], int, int)</code> method.
*
* @param buf The buffer to read bytes into
* @param offset The index into the buffer to start storing bytes
* @param len The maximum number of bytes to read.
*
* @return The value retured from <code>in.read(byte[], int, int)</code>
*
* @exception IOException If an error occurs
*/
public int read(byte[] buf, int offset, int len) throws IOException
{
return in.read(buf, offset, len);
}
/**
* This method closes the input stream by closing the input stream that
* this object is filtering. Future attempts to access this stream may
* throw an exception.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
in.close();
}
}
@@ -0,0 +1,150 @@
/* FilterOutputStream.java -- Parent class for output streams that filter
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This class is the common superclass of output stream classes that
* filter the output they write. These classes typically transform the
* data in some way prior to writing it out to another underlying
* <code>OutputStream</code>. This class simply overrides all the
* methods in <code>OutputStream</code> to redirect them to the
* underlying stream. Subclasses provide actual filtering.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class FilterOutputStream extends OutputStream
{
/**
* This is the subordinate <code>OutputStream</code> that this class
* redirects its method calls to.
*/
protected OutputStream out;
/**
* This method initializes an instance of <code>FilterOutputStream</code>
* to write to the specified subordinate <code>OutputStream</code>.
*
* @param out The <code>OutputStream</code> to write to
*/
public FilterOutputStream(OutputStream out)
{
this.out = out;
}
/**
* This method closes the underlying <code>OutputStream</code>. Any
* further attempts to write to this stream may throw an exception.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
flush();
out.close();
}
/**
* This method attempt to flush all buffered output to be written to the
* underlying output sink.
*
* @exception IOException If an error occurs
*/
public void flush() throws IOException
{
out.flush();
}
/**
* This method writes a single byte of output to the underlying
* <code>OutputStream</code>.
*
* @param b The byte to write, passed as an int.
*
* @exception IOException If an error occurs
*/
public void write(int b) throws IOException
{
out.write(b);
}
/**
* This method writes all the bytes in the specified array to the underlying
* <code>OutputStream</code>. It does this by calling the three parameter
* version of this method - <code>write(byte[], int, int)</code> in this
* class instead of writing to the underlying <code>OutputStream</code>
* directly. This allows most subclasses to avoid overriding this method.
*
* @param buf The byte array to write bytes from
*
* @exception IOException If an error occurs
*/
public void write(byte[] buf) throws IOException
{
// Don't do checking here, per Java Lang Spec.
write(buf, 0, buf.length);
}
/**
* This method calls the <code>write(int)</code> method <code>len</code>
* times for all bytes from the array <code>buf</code> starting at index
* <code>offset</code>. Subclasses should overwrite this method to get a
* more efficient implementation.
*
* @param buf The byte array to write bytes from
* @param offset The index into the array to start writing bytes from
* @param len The number of bytes to write
*
* @exception IOException If an error occurs
*/
public void write(byte[] buf, int offset, int len) throws IOException
{
// Don't do checking here, per Java Lang Spec.
for (int i=0; i < len; i++)
write(buf[offset + i]);
}
} // class FilterOutputStream
+185
View File
@@ -0,0 +1,185 @@
/* FilterReader.java -- Base class for char stream classes that filter input
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This is the common superclass of all standard classes that filter
* input. It acts as a layer on top of an underlying <code>Reader</code>
* and simply redirects calls made to it to the subordinate Reader
* instead. Subclasses of this class perform additional filtering
* functions in addition to simply redirecting the call.
* <p>
* When creating a subclass of <code>FilterReader</code>, override the
* appropriate methods to implement the desired filtering. However, note
* that the <code>read(char[])</code> method does not need to be overridden
* as this class redirects calls to that method to
* <code>read(yte[], int, int)</code> instead of to the subordinate
* <code>Reader} read(yte[])</code> method.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public abstract class FilterReader extends Reader
{
/**
* This is the subordinate <code>Reader</code> to which method calls
* are redirected
*/
protected Reader in;
/**
* Create a <code>FilterReader</code> with the specified subordinate
* <code>Reader</code>.
* The <code>lock</code> of the new <code>FilterReader</code> will be set
* to <code>in.lock</code>.
*
* @param in The subordinate <code>Reader</code>
*/
protected FilterReader(Reader in)
{
super(in.lock);
this.in = in;
}
/**
* Calls the <code>in.mark(int)</code> method.
*
* @param readlimit The parameter passed to <code>in.mark(int)</code>
*
* @exception IOException If an error occurs
*/
public void mark(int readlimit) throws IOException
{
in.mark(readlimit);
}
/**
* Calls the <code>in.markSupported()</code> method.
*
* @return <code>true</code> if mark/reset is supported,
* <code>false</code> otherwise
*/
public boolean markSupported()
{
return(in.markSupported());
}
/**
* Calls the <code>in.reset()</code> method.
*
* @exception IOException If an error occurs
*/
public void reset() throws IOException
{
in.reset();
}
/**
* Calls the <code>in.read()</code> method.
*
* @return The value returned from <code>in.available()</code>
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException
{
return(in.ready());
}
/**
* Calls the <code>in.skip(long)</code> method
*
* @param numBytes The requested number of chars to skip.
*
* @return The value returned from <code>in.skip(long)</code>
*
* @exception IOException If an error occurs
*/
public long skip(long num_chars) throws IOException
{
return(in.skip(num_chars));
}
/**
* Calls the <code>in.read()</code> method
*
* @return The value returned from <code>in.read()</code>
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
return(in.read());
}
/**
* Calls the <code>in.read(char[], int, int)</code> method.
*
* @param buf The buffer to read chars into
* @param offset The index into the buffer to start storing chars
* @param len The maximum number of chars to read.
*
* @return The value retured from <code>in.read(char[], int, int)</code>
*
* @exception IOException If an error occurs
*/
public int read(char[] buf, int offset, int len) throws IOException
{
return(in.read(buf, offset, len));
}
/**
* This method closes the stream by calling the <code>close()</code> method
* of the underlying stream.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
in.close();
}
} // class FilterReader
+147
View File
@@ -0,0 +1,147 @@
/* FilterWriter.java -- Parent class for output streams that filter
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Complete to version 1.1.
*/
/**
* This class is the common superclass of output character stream classes
* that filter the output they write. These classes typically transform the
* data in some way prior to writing it out to another underlying
* <code>Writer</code>. This class simply overrides all the
* methods in <code>Writer</code> to redirect them to the
* underlying stream. Subclasses provide actual filtering.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public abstract class FilterWriter extends Writer
{
/**
* This is the subordinate <code>Writer</code> that this class
* redirects its method calls to.
*/
protected Writer out;
/**
* This method initializes an instance of <code>FilterWriter</code>
* to write to the specified subordinate <code>Writer</code>.
* The given <code>Writer</code> will be used as <code>lock</code> for
* the newly created <code>FilterWriter</code>.
*
* @param out The <code>Writer</code> to write to
*/
protected FilterWriter(Writer out)
{
super(out.lock);
this.out = out;
}
/**
* This method closes the underlying <code>Writer</code>. Any
* further attempts to write to this stream may throw an exception.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
out.close();
}
/**
* This method attempt to flush all buffered output to be written to the
* underlying output sink.
*
* @exception IOException If an error occurs
*/
public void flush() throws IOException
{
out.flush();
}
/**
* This method writes a single char of output to the underlying
* <code>Writer</code>.
*
* @param b The char to write, passed as an int.
*
* @exception IOException If an error occurs
*/
public void write(int b) throws IOException
{
out.write(b);
}
/**
* This method writes <code>len</code> chars from the array <code>buf</code>
* starting at index <code>offset</code> to the underlying
* <code>Writer</code>.
*
* @param buf The char array to write chars from
* @param offset The index into the array to start writing chars from
* @param len The number of chars to write
*
* @exception IOException If an error occurs
*/
public void write(char[] buf, int offset, int len) throws IOException
{
out.write(buf, offset, len);
}
/**
* This method writes <code>len</code> chars from the <code>String</code>
* starting at position <code>offset</code>.
*
* @param str The <code>String</code> that is to be written
* @param offset The character offset into the <code>String</code>
* to start writing from
* @param len The number of chars to write
*
* @exception IOException If an error occurs
*/
public void write(String str, int offset, int len) throws IOException
{
out.write(str, offset, len);
}
} // class FilterWriter
+62
View File
@@ -0,0 +1,62 @@
/* Flushable.java -- Flushable object
Copyright (C) 2004, 2005 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* A <code>Flushable</code> class represents a stream of
* data, for which internally buffered data can be `flushed'.
* Flushing such a stream causes the buffered data to be
* written to the stream.
*
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public interface Flushable
{
/**
* Flushes the stream represented by this class,
* so that any buffered data is written to the stream.
*
* @throws IOException if an I/O error occurs in flushing.
*/
void flush()
throws IOException;
}
@@ -0,0 +1,74 @@
/* IOException.java -- Generic input/output exception
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown to indicate an I/O problem of some sort
* occurred. Since this is a fairly generic exception, often a subclass
* of IOException will actually be thrown in order to provide a more
* detailed indication of what happened.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @status updated to 1.4
*/
public class IOException extends Exception
{
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = 7818375828146090155L;
/**
* Create an exception without a descriptive error message.
*/
public IOException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public IOException(String message)
{
super(message);
}
} // class IOException
+272
View File
@@ -0,0 +1,272 @@
/* InputStream.java -- Base class for input
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This abstract class forms the base of the hierarchy of classes that read
* input as a stream of bytes. It provides a common set of methods for
* reading bytes from streams. Subclasses implement and extend these
* methods to read bytes from a particular input source such as a file
* or network connection.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public abstract class InputStream
{
/**
* Default, no-arg, public constructor
*/
public InputStream()
{
}
/**
* This method returns the number of bytes that can be read from this
* stream before a read can block. A return of 0 indicates that blocking
* might (or might not) occur on the very next read attempt.
* <p>
* This method always returns 0 in this class
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
return 0;
}
/**
* This method closes the stream. Any futher attempts to read from the
* stream may generate an <code>IOException</code>
* <p>
* This method does nothing in this class, but subclasses may override
* this method in order to provide additional functionality.
*
* @exception IOException If an error occurs, which can only happen
* in a subclass
*/
public void close() throws IOException
{
// Do nothing
}
/**
* This method marks a position in the input to which the stream can
* be "reset" by calling the <code>reset()</code> method. The
* parameter @code{readlimit} is the number of bytes that can be read
* from the stream after setting the mark before the mark becomes
* invalid. For example, if <code>mark()</code> is called with a
* read limit of 10, then when 11 bytes of data are read from the
* stream before the <code>reset()</code> method is called, then the
* mark is invalid and the stream object instance is not required to
* remember the mark.
* <p>
* This method does nothing in this class, but subclasses may override it
* to provide mark/reset functionality.
*
* @param readLimit The number of bytes that can be read before the
* mark becomes invalid
*/
public void mark(int readLimit)
{
// Do nothing
}
/**
* This method returns a boolean that indicates whether the mark/reset
* methods are supported in this class. Those methods can be used to
* remember a specific point in the stream and reset the stream to that
* point.
* <p>
* This method always returns <code>false</code> in this class, but
* subclasses can override this method to return <code>true</code>
* if they support mark/reset functionality.
*
* @return <code>true</code> if mark/reset functionality is
* supported, <code>false</code> otherwise
*/
public boolean markSupported()
{
return false;
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public abstract int read() throws IOException;
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. This method attempts to completely fill the buffer,
* but can return before doing so. The actual number of bytes read is
* returned as an int. A -1 is returned to indicate the end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling an overloaded read method like so:
* <code>read(b, 0, b.length)</code>
*
* @param b The buffer into which the bytes read will be stored.
*
* @return The number of bytes read or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(byte[] b) throws IOException
{
return read(b, 0, b.length);
}
/**
* This method read bytes from a stream and stores them into a
* caller supplied buffer. It starts storing the data at index
* <code>off</code> into the buffer and attempts to read
* <code>len</code> bytes. This method can return before reading the
* number of bytes requested. The actual number of bytes read is
* returned as an int. A -1 is returned to indicate the end of the
* stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling the single byte <code>read()</code> method
* in a loop until the desired number of bytes are read. The read loop
* stops short if the end of the stream is encountered or if an IOException
* is encountered on any read operation except the first. If the first
* attempt to read a bytes fails, the IOException is allowed to propagate
* upward. And subsequent IOException is caught and treated identically
* to an end of stream condition. Subclasses can (and should if possible)
* override this method to provide a more efficient implementation.
*
* @param b The array into which the bytes read should be stored
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(byte[] b, int off, int len) throws IOException
{
if (off < 0 || len < 0 || off + len > b.length)
throw new IndexOutOfBoundsException();
if (b.length == 0)
return 0;
int i, ch;
for (i = 0; i < len; ++i)
try
{
if ((ch = read()) < 0)
return i == 0 ? -1 : i; // EOF
b[off + i] = (byte) ch;
}
catch (IOException ex)
{
// Only reading the first byte should cause an IOException.
if (i == 0)
throw ex;
return i;
}
return i;
}
/**
* This method resets a stream to the point where the
* <code>mark()</code> method was called. Any bytes that were read
* after the mark point was set will be re-read during subsequent
* reads.
* <p>
* This method always throws an IOException in this class, but subclasses
* can override this method if they provide mark/reset functionality.
*
* @exception IOException Always thrown for this class
*/
public void reset() throws IOException
{
throw new IOException("mark/reset not supported");
}
/**
* This method skips the specified number of bytes in the stream. It
* returns the actual number of bytes skipped, which may be less than the
* requested amount.
* <p>
* This method reads and discards bytes into a byte array until the
* specified number of bytes were skipped or until either the end of stream
* is reached or a read attempt returns a short count. Subclasses can
* override this metho to provide a more efficient implementation where
* one exists.
*
* @param n The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs
*/
public long skip(long n) throws IOException
{
// Throw away n bytes by reading them into a temp byte[].
// Limit the temp array to 2Kb so we don't grab too much memory.
final int buflen = n > 2048 ? 2048 : (int) n;
byte[] tmpbuf = new byte[buflen];
final long origN = n;
while (n > 0L)
{
int numread = read(tmpbuf, 0, n > buflen ? buflen : (int) n);
if (numread <= 0)
break;
n -= numread;
}
return origN - n;
}
}
@@ -0,0 +1,438 @@
/* InputStreamReader.java -- Reader than transforms bytes to chars
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.nio.charset.UnsupportedCharsetException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import gnu.java.nio.charset.EncodingHelper;
/**
* This class reads characters from a byte input stream. The characters
* read are converted from bytes in the underlying stream by a
* decoding layer. The decoding layer transforms bytes to chars according
* to an encoding standard. There are many available encodings to choose
* from. The desired encoding can either be specified by name, or if no
* encoding is selected, the system default encoding will be used. The
* system default encoding name is determined from the system property
* <code>file.encoding</code>. The only encodings that are guaranteed to
* be availalbe are "8859_1" (the Latin-1 character set) and "UTF8".
* Unforunately, Java does not provide a mechanism for listing the
* ecodings that are supported in a given implementation.
* <p>
* Here is a list of standard encoding names that may be available:
* <p>
* <ul>
* <li>8859_1 (ISO-8859-1/Latin-1)</li>
* <li>8859_2 (ISO-8859-2/Latin-2)</li>
* <li>8859_3 (ISO-8859-3/Latin-3)</li>
* <li>8859_4 (ISO-8859-4/Latin-4)</li>
* <li>8859_5 (ISO-8859-5/Latin-5)</li>
* <li>8859_6 (ISO-8859-6/Latin-6)</li>
* <li>8859_7 (ISO-8859-7/Latin-7)</li>
* <li>8859_8 (ISO-8859-8/Latin-8)</li>
* <li>8859_9 (ISO-8859-9/Latin-9)</li>
* <li>ASCII (7-bit ASCII)</li>
* <li>UTF8 (UCS Transformation Format-8)</li>
* <li>More later</li>
* </ul>
* <p>
* It is recommended that applications do not use
* <code>InputStreamReader</code>'s
* directly. Rather, for efficiency purposes, an object of this class
* should be wrapped by a <code>BufferedReader</code>.
* <p>
* Due to a deficiency the Java class library design, there is no standard
* way for an application to install its own byte-character encoding.
*
* @see BufferedReader
* @see InputStream
*
* @author Robert Schuster
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner (bothner@cygnus.com)
* @date April 22, 1998.
*/
public class InputStreamReader extends Reader
{
/**
* The input stream.
*/
private InputStream in;
/**
* The charset decoder.
*/
private CharsetDecoder decoder;
/**
* End of stream reached.
*/
private boolean isDone = false;
/**
* Need this.
*/
private float maxBytesPerChar;
/**
* Buffer holding surplus loaded bytes (if any)
*/
private ByteBuffer byteBuffer;
/**
* java.io canonical name of the encoding.
*/
private String encoding;
/**
* We might decode to a 2-char UTF-16 surrogate, which won't fit in the
* output buffer. In this case we need to save the surrogate char.
*/
private char savedSurrogate;
private boolean hasSavedSurrogate = false;
/**
* This method initializes a new instance of <code>InputStreamReader</code>
* to read from the specified stream using the default encoding.
*
* @param in The <code>InputStream</code> to read from
*/
public InputStreamReader(InputStream in)
{
if (in == null)
throw new NullPointerException();
this.in = in;
try
{
encoding = System.getProperty("file.encoding");
// Don't use NIO if avoidable
if(EncodingHelper.isISOLatin1(encoding))
{
encoding = "ISO8859_1";
maxBytesPerChar = 1f;
decoder = null;
return;
}
Charset cs = EncodingHelper.getCharset(encoding);
decoder = cs.newDecoder();
encoding = EncodingHelper.getOldCanonical(cs.name());
try {
maxBytesPerChar = cs.newEncoder().maxBytesPerChar();
} catch(UnsupportedOperationException _){
maxBytesPerChar = 1f;
}
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
decoder.reset();
} catch(RuntimeException e) {
encoding = "ISO8859_1";
maxBytesPerChar = 1f;
decoder = null;
} catch(UnsupportedEncodingException e) {
encoding = "ISO8859_1";
maxBytesPerChar = 1f;
decoder = null;
}
}
/**
* This method initializes a new instance of <code>InputStreamReader</code>
* to read from the specified stream using a caller supplied character
* encoding scheme. Note that due to a deficiency in the Java language
* design, there is no way to determine which encodings are supported.
*
* @param in The <code>InputStream</code> to read from
* @param encoding_name The name of the encoding scheme to use
*
* @exception UnsupportedEncodingException If the encoding scheme
* requested is not available.
*/
public InputStreamReader(InputStream in, String encoding_name)
throws UnsupportedEncodingException
{
if (in == null
|| encoding_name == null)
throw new NullPointerException();
this.in = in;
// Don't use NIO if avoidable
if(EncodingHelper.isISOLatin1(encoding_name))
{
encoding = "ISO8859_1";
maxBytesPerChar = 1f;
decoder = null;
return;
}
try {
Charset cs = EncodingHelper.getCharset(encoding_name);
try {
maxBytesPerChar = cs.newEncoder().maxBytesPerChar();
} catch(UnsupportedOperationException _){
maxBytesPerChar = 1f;
}
decoder = cs.newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
decoder.reset();
// The encoding should be the old name, if such exists.
encoding = EncodingHelper.getOldCanonical(cs.name());
} catch(RuntimeException e) {
encoding = "ISO8859_1";
maxBytesPerChar = 1f;
decoder = null;
}
}
/**
* Creates an InputStreamReader that uses a decoder of the given
* charset to decode the bytes in the InputStream into
* characters.
*/
public InputStreamReader(InputStream in, Charset charset) {
this.in = in;
decoder = charset.newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
decoder.reset();
encoding = EncodingHelper.getOldCanonical(charset.name());
}
/**
* Creates an InputStreamReader that uses the given charset decoder
* to decode the bytes in the InputStream into characters.
*/
public InputStreamReader(InputStream in, CharsetDecoder decoder) {
this.in = in;
this.decoder = decoder;
try {
maxBytesPerChar = decoder.charset().newEncoder().maxBytesPerChar();
} catch(UnsupportedOperationException _){
maxBytesPerChar = 1f;
}
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
decoder.reset();
encoding = EncodingHelper.getOldCanonical(decoder.charset().name());
}
/**
* This method closes this stream, as well as the underlying
* <code>InputStream</code>.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
synchronized (lock)
{
// Makes sure all intermediate data is released by the decoder.
if (decoder != null)
decoder.reset();
if (in != null)
in.close();
in = null;
isDone = true;
decoder = null;
}
}
/**
* This method returns the name of the encoding that is currently in use
* by this object. If the stream has been closed, this method is allowed
* to return <code>null</code>.
*
* @return The current encoding name
*/
public String getEncoding()
{
return in != null ? encoding : null;
}
/**
* This method checks to see if the stream is ready to be read. It
* will return <code>true</code> if is, or <code>false</code> if it is not.
* If the stream is not ready to be read, it could (although is not required
* to) block on the next read attempt.
*
* @return <code>true</code> if the stream is ready to be read,
* <code>false</code> otherwise
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException
{
if (in == null)
throw new IOException("Reader has been closed");
return in.available() != 0;
}
/**
* This method reads up to <code>length</code> characters from the stream into
* the specified array starting at index <code>offset</code> into the
* array.
*
* @param buf The character array to recieve the data read
* @param offset The offset into the array to start storing characters
* @param length The requested number of characters to read.
*
* @return The actual number of characters read, or -1 if end of stream.
*
* @exception IOException If an error occurs
*/
public int read(char[] buf, int offset, int length) throws IOException
{
if (in == null)
throw new IOException("Reader has been closed");
if (isDone)
return -1;
if(decoder != null){
int totalBytes = (int)((double)length * maxBytesPerChar);
byte[] bytes = new byte[totalBytes];
int remaining = 0;
if(byteBuffer != null)
{
remaining = byteBuffer.remaining();
byteBuffer.get(bytes, 0, remaining);
}
int read;
if(totalBytes - remaining > 0)
{
read = in.read(bytes, remaining, totalBytes - remaining);
if(read == -1){
read = remaining;
isDone = true;
} else
read += remaining;
} else
read = remaining;
byteBuffer = ByteBuffer.wrap(bytes, 0, read);
CharBuffer cb = CharBuffer.wrap(buf, offset, length);
int startPos = cb.position();
if(hasSavedSurrogate){
hasSavedSurrogate = false;
cb.put(savedSurrogate);
read++;
}
CoderResult cr = decoder.decode(byteBuffer, cb, isDone);
decoder.reset();
// 1 char remains which is the first half of a surrogate pair.
if(cr.isOverflow() && cb.hasRemaining()){
CharBuffer overflowbuf = CharBuffer.allocate(2);
cr = decoder.decode(byteBuffer, overflowbuf, isDone);
overflowbuf.flip();
if(overflowbuf.hasRemaining())
{
cb.put(overflowbuf.get());
savedSurrogate = overflowbuf.get();
hasSavedSurrogate = true;
isDone = false;
}
}
if(byteBuffer.hasRemaining()) {
byteBuffer.compact();
byteBuffer.flip();
isDone = false;
} else
byteBuffer = null;
read = cb.position() - startPos;
return (read <= 0) ? -1 : read;
} else {
byte[] bytes = new byte[length];
int read = in.read(bytes);
for(int i=0;i<read;i++)
buf[offset+i] = (char)(bytes[i]&0xFF);
return read;
}
}
/**
* Reads an char from the input stream and returns it
* as an int in the range of 0-65535. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the char can be read.
*
* @return The char read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
char[] buf = new char[1];
int count = read(buf, 0, 1);
return count > 0 ? buf[0] : -1;
}
/**
* Skips the specified number of chars in the stream. It
* returns the actual number of chars skipped, which may be less than the
* requested amount.
*
* @param count The requested number of chars to skip
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs
*/
public long skip(long count) throws IOException
{
if (in == null)
throw new IOException("Reader has been closed");
return super.skip(count);
}
}
@@ -0,0 +1,94 @@
/* InterruptedIOException.java -- an I/O operation was interrupted
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when a in process I/O operation is interrupted
* for some reason. The field bytesTransferred will contain the number of
* bytes that were read/written prior to the interruption.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @see Thread#interrupt()
* @status updated to 1.4
*/
public class InterruptedIOException extends IOException
{
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = 4020568460727500567L;
/**
* The number of bytes read/written prior to the interruption.
*
* @serial count of bytes successfully transferred
*/
public int bytesTransferred;
/**
* Create an extends without a descriptive error message.
*/
public InterruptedIOException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public InterruptedIOException(String message)
{
super(message);
}
/**
* Create an exception with a descriptive error message and count of
* bytes transferred.
*
* @param message the descriptive error message
* @param bytesTransferred number of bytes tranferred before interruption
*/
InterruptedIOException(String message, int bytesTransferred)
{
super(message);
this.bytesTransferred = bytesTransferred;
}
} // class InterruptedIOException
@@ -0,0 +1,111 @@
/* InvalidClassException.java -- deserializing a class failed
Copyright (C) 1998, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when there is some sort of problem with a
* class during a serialization operation. This could be:<br><ul>
* <li>the serial version of the class doesn't match</li>
* <li>the class contains unknown datatypes</li>
* <li>the class does not have an accessible no-arg constructor</li>
* </ul>.
*
* <p>The field <code>classname</code> will contain the name of the
* class that caused the problem if known. The getMessage() method
* for this exception will always include the name of that class
* if known.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.1
* @status updated to 1.4
*/
public class InvalidClassException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -4333316296251054416L;
/**
* The name of the class which encountered the error.
*
* @serial the classname causing the error
*/
public String classname;
/**
* Create an exception with a descriptive error message, but a null
* classname.
*
* @param message the descriptive error message
*/
public InvalidClassException(String message)
{
super(message);
}
/**
* Create an exception with a descriptive error message, and the name of
* the class that caused the problem.
*
* @param classname the name of the faulty class
* @param message the descriptive error message
*/
public InvalidClassException(String classname, String message)
{
super(message);
this.classname = classname;
}
/**
* Returns the descriptive error message for this exception. It will
* include the class name that caused the problem if known, in the format:
* <code>[classname][; ][super.getMessage()]</code>.
*
* @return A descriptive error message, may be null
*/
public String getMessage()
{
String msg = super.getMessage();
if (msg == null)
return classname;
return (classname == null ? "" : classname + "; ") + msg;
}
}
@@ -0,0 +1,66 @@
/* InvalidObjectException.java -- deserialization failed verification
Copyright (C) 1998, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when an object fails a validation test
* during serialization.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.1
* @status updated to 1.4
*/
public class InvalidObjectException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = 3233174318281839583L;
/**
* Create an exception with a descriptive error message String. This should
* be the cause of the verification failure.
*
* @param message the descriptive error message
*/
public InvalidObjectException(String message)
{
super(message);
}
} // class InvalidObjectException
@@ -0,0 +1,315 @@
/* LineNumberInputStream.java -- An input stream which counts line numbers
Copyright (C) 1998, 1999, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class functions like a standard <code>InputStream</code>
* except that it counts line numbers, and canonicalizes newline
* characters. As data is read, whenever the byte sequences "\r",
* "\n", or "\r\n" are encountered, the running line count is
* incremeted by one. Additionally, the whatever line termination
* sequence was encountered will be converted to a "\n" byte. Note
* that this class numbers lines from 0. When the first line
* terminator is encountered, the line number is incremented to 1, and
* so on.
* <p>
* This class counts only line termination characters. If the last line
* read from the stream does not end in a line termination sequence, it
* will not be counted as a line.
* <p>
* Note that since this class operates as a filter on an underlying
* stream, it has the same mark/reset functionality as the underlying
* stream. The <code>mark()</code> and <code>reset()</code> methods
* in this class handle line numbers correctly. Calling
* <code>reset()</code> resets the line number to the point at which
* <code>mark()</code> was called if the subordinate stream supports
* that functionality.
* <p>
* @deprecated This class is deprecated in favor if
* <code>LineNumberReader</code> because it operates on ASCII bytes
* instead of an encoded character stream. This class is for backward
* compatibility only and should not be used in new applications.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class LineNumberInputStream extends FilterInputStream
{
/** The current line number. */
private int lineNumber = 0;
/** The line number when the stream was marked. */
private int markLineNumber = 0;
/** Flag to indicate a '\r' was just read so that an immediately
* subsequent '\n' can be ignored. */
private boolean justReadReturnChar = false;
/**
* Create a new <code>LineNumberInputStream</code> that reads from the
* specified subordinate <code>InputStream</code>
*
* @param in The subordinate <code>InputStream</code> to read from
*/
public LineNumberInputStream(InputStream in)
{
super(in);
}
/**
* This method returns the number of bytes that can be read from the
* stream before the stream can block. This method is tricky
* because the subordinate <code>InputStream</code> might return
* only "\r\n" characters, which are replaced by a single "\n"
* character by the <code>read()</code> method of this class. So
* this method can only guarantee that <code>in.available() /
* 2</code> bytes can actually be read before blocking. In
* practice, considerably more bytes might be read before blocking
* <p>
* Note that the stream may not block if additional bytes beyond the count
* returned by this method are read.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
// We can only guarantee half the characters that might be available
// without blocking because "\r\n" is treated as a single character.
return in.available() / 2;
}
/**
* This method returns the current line number
*
* @return The current line number
*/
public int getLineNumber()
{
return lineNumber;
}
/**
* This method marks a position in the input to which the stream can
* be "reset" byte calling the <code>reset()</code> method. The
* parameter <code>readlimit</code> is the number of bytes that can
* be read from the stream after setting the mark before the mark
* becomes invalid. For example, if <code>mark()</code> is called
* with a read limit of 10, then when 11 bytes of data are read from
* the stream before the <code>reset()</code> method is called, then
* the mark is invalid and the stream object instance is not
* required to remember the mark.
* <p>
* In this class, this method will remember the current line number
* as well as the current position in the stream. When the
* <code>reset()</code> method is called, the line number will be
* restored to the saved line number in addition to the stream
* position.
* <p>
* This method only works if the subordinate stream supports mark/reset
* functionality.
*
* @param readlimit The number of bytes that can be read before the
* mark becomes invalid
*/
public void mark(int readlimit)
{
in.mark(readlimit);
markLineNumber = lineNumber;
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method will return -1 if the
* end of the stream has been reached.
* <p>
* Note that if a line termination sequence is encountered (ie, "\r",
* "\n", or "\r\n") then that line termination sequence is converted to
* a single "\n" value which is returned from this method. This means
* that it is possible this method reads two bytes from the subordinate
* stream instead of just one.
* <p>
* Note that this method will block until a byte of data is available
* to be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
// Treat "\r\n" as a single character. A '\r' may have been read by
// a previous call to read so we keep an internal flag to avoid having
// to read ahead.
int ch = in.read();
if (ch == '\n')
if (justReadReturnChar)
{
ch = in.read();
justReadReturnChar = false;
}
else
lineNumber++;
else if (ch == '\r')
{
ch = '\n';
justReadReturnChar = true;
lineNumber++;
}
else
justReadReturnChar = false;
return ch;
}
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. It starts storing data at index <code>offset</code> into
* the buffer and attemps to read <code>len</code> bytes. This method can
* return before reading the number of bytes requested. The actual number
* of bytes read is returned as an int. A -1 is returned to indicated the
* end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* Note that if a line termination sequence is encountered (ie, "\r",
* "\n", or "\r\n") then that line termination sequence is converted to
* a single "\n" value which is stored in the buffer. Only a single
* byte is counted towards the number of bytes read in this case.
*
* @param b The array into which the bytes read should be stored
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream
*
* @exception IOException If an error occurs.
*/
public int read(byte[] b, int off, int len) throws IOException
{
if (off < 0 || len < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
// This case always succeeds.
if (len == 0)
return 0;
// The simplest, though not necessarily the most time efficient thing
// to do is simply call read(void) len times. Since this is a deprecated
// class, that should be ok.
final int origOff = off;
while (len-- > 0)
{
int ch = read();
if (ch < 0)
break;
b[off++] = (byte) ch;
}
// This is safe since we already know that some bytes were
// actually requested.
return off == origOff ? -1 : off - origOff;
}
/**
* This method resets a stream to the point where the
* <code>mark()</code> method was called. Any bytes that were read
* after the mark point was set will be re-read during subsequent
* reads.
* <p>
* In this class, this method will also restore the line number that was
* current when the <code>mark()</code> method was called.
* <p>
* This method only works if the subordinate stream supports mark/reset
* functionality.
*
* @exception IOException If an error occurs
*/
public void reset() throws IOException
{
in.reset();
lineNumber = markLineNumber;
justReadReturnChar = false;
}
/**
* This method sets the current line number to the specified value.
*
* @param lineNumber The new line number
*/
public void setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
}
/**
* This method skips up to the requested number of bytes in the
* input stream. The actual number of bytes skipped is returned. If the
* desired number of bytes to skip is negative, no bytes are skipped.
*
* @param n requested number of bytes to skip.
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs.
*/
public long skip(long n) throws IOException
{
if (n <= 0)
return 0L;
final long origN = n;
do
{
int ch = read();
if (ch < 0)
break;
if (ch == '\n' || ch == '\r')
lineNumber++;
}
while (--n > 0);
return origN - n;
}
}
@@ -0,0 +1,417 @@
/* LineNumberReader.java -- A character input stream which counts line numbers
Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class functions like a standard <code>Reader</code> except that it
* counts line numbers, and canonicalizes newline characters. As data
* is read, whenever the char sequences "\r", "\n", or "\r\n" are encountered,
* the running line count is incremeted by one. Additionally, the whatever
* line termination sequence was encountered will be converted to a "\n"
* char. Note that this class numbers lines from 0. When the first
* line terminator is encountered, the line number is incremented to 1, and
* so on. Also note that actual "\r" and "\n" characters are looked for.
* The system dependent line separator sequence is ignored.
* <p>
* This class counts only line termination characters. If the last line
* read from the stream does not end in a line termination sequence, it
* will not be counted as a line.
*
* @author Per Bothner (bothner@cygnus.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Guilhem Lavaux (guilhem@kaffe.org)
* @date December 28, 2003.
*/
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*
* This implementation has the feature that if '\r' is read, it
* does not look for a '\n', but immediately returns '\n'.
* On the next read(), if a '\n' is read, it is skipped.
* This has the advantage that we do not read (and hang) unnecessarily.
*
* This implementation is also minimal in the number of fields it uses.
*/
public class LineNumberReader extends BufferedReader
{
/** The current line number. */
private int lineNumber;
/** Whether we already found a new line in the former call. */
private boolean matchedNewLine;
/** The saved line number when calling mark() */
private int savedLineNumber;
/**
* Create a new <code>LineNumberReader</code> that reads from the
* specified subordinate <code>Reader</code>. A default 8K char sized
* buffer will be used for reads.
*
* @param in The subordinate <code>Reader</code> to read from
*/
public LineNumberReader(Reader in)
{
super(in, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>LineNumberReader</code> to read
* from the specified subordinate <code>Reader</code> using the specified
* read buffer size.
*
* @param in The subordinate <code>Reader</code> to read from
* @param size The buffer size to use for reading
*/
public LineNumberReader(Reader in, int size)
{
super(in, size);
}
/**
* This method returns the current line number
*
* @return The current line number
*/
public int getLineNumber()
{
return lineNumber;
}
/**
* This method sets the current line number to the specified value.
*
* @param line_number The new line number
*/
public void setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
}
/**
* This method marks a position in the input to which the stream can be
* "reset" char calling the <code>reset()</code> method. The parameter
* <code>readlimit</code> is the number of chars that can be read from the
* stream after setting the mark before the mark becomes invalid. For
* example, if <code>mark()</code> is called with a read limit of 10,
* then when
* 11 chars of data are read from the stream before the <code>reset()</code>
* method is called, then the mark is invalid and the stream object
* instance is not required to remember the mark.
* <p>
* In this class, this method will remember the current line number as well
* as the current position in the stream. When the <code>reset()</code>
* method
* is called, the line number will be restored to the saved line number in
* addition to the stream position.
*
* @param readlimit The number of chars that can be read before the
* mark becomes invalid
*
* @exception IOException If an error occurs
*/
public void mark(int readLimit) throws IOException
{
if (readLimit < 0)
throw new IllegalArgumentException("Read-ahead limit is negative");
synchronized (lock)
{
// This is basically the same as BufferedReader.mark.
// However, if the previous character was a '\r', we need to
// save that 'r', in case the next character is a '\n'.
if (pos + readLimit > limit)
{
int saveCR = matchedNewLine ? 1 : 0;
char[] old_buffer = buffer;
if (readLimit > limit)
buffer = new char[saveCR + readLimit];
int copy_start = pos - saveCR;
savedLineNumber = lineNumber;
limit -= copy_start;
System.arraycopy(old_buffer, copy_start, buffer, 0, limit);
pos = saveCR;
}
markPos = pos;
}
}
/**
* This method resets a stream to the point where the <code>mark()</code>
* method
* was called. Any chars that were read after the mark point was set will
* be re-read during subsequent reads.
* <p>
* In this class, this method will also restore the line number that was
* current when the <code>mark()</code> method was called.
*
* @exception IOException If an error occurs
*/
public void reset() throws IOException
{
synchronized (lock)
{
if (markPos < 0)
throw new IOException("mark never set or invalidated");
lineNumber = savedLineNumber;
pos = markPos;
matchedNewLine = (markPos > 0 && buffer[markPos-1] == '\r');
}
}
/**
* This private method fills the input buffer whatever pos is.
* Consequently pos should be checked before calling this method.
*
* @return the number of bytes actually read from the input stream or
* -1 if end of stream.
* @exception IOException If an error occurs.
*/
private int fill() throws IOException
{
if (markPos >= 0 && limit == buffer.length)
markPos = -1;
if (markPos < 0)
pos = limit = 0;
int count = in.read(buffer, limit, buffer.length - limit);
if (count <= 0)
return -1;
limit += count;
return count;
}
/**
* This method reads an unsigned char from the input stream and returns it
* as an int in the range of 0-65535. This method will return -1 if the
* end of the stream has been reached.
* <p>
* Note that if a line termination sequence is encountered (ie, "\r",
* "\n", or "\r\n") then that line termination sequence is converted to
* a single "\n" value which is returned from this method. This means
* that it is possible this method reads two chars from the subordinate
* stream instead of just one.
* <p>
* Note that this method will block until a char of data is available
* to be read.
*
* @return The char read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
synchronized (lock)
{
skipRedundantLF();
if (pos >= limit && fill() < 0)
return -1;
char ch = buffer[pos++];
if ((matchedNewLine = (ch == '\r')) || ch == '\n')
{
lineNumber++;
return '\n';
}
matchedNewLine = false;
return (int) ch;
}
}
/**
* This method reads chars from a stream and stores them into a caller
* supplied buffer. It starts storing data at index <code>offset</code> into
* the buffer and attemps to read <code>len</code> chars. This method can
* return before reading the number of chars requested. The actual number
* of chars read is returned as an int. A -1 is returned to indicated the
* end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* Note that if a line termination sequence is encountered (ie, "\r",
* "\n", or "\r\n") then that line termination sequence is converted to
* a single "\n" value which is stored in the buffer. Only a single
* char is counted towards the number of chars read in this case.
*
* @param buf The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
* @param len The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream
*
* @exception IOException If an error occurs.
* @exception NullPointerException If buf is null (in any case).
* @exception IndexOutOfBoundsException If buffer parameters (offset and
* count) lies outside of the buffer capacity.
*/
public int read(char[] buf, int offset, int count) throws IOException
{
if (buf == null)
throw new NullPointerException();
if (offset + count > buf.length || offset < 0)
throw new IndexOutOfBoundsException();
if (count <= 0)
{
if (count < 0)
throw new IndexOutOfBoundsException();
return 0;
}
synchronized (lock)
{
if (pos >= limit && fill() < 0)
return -1;
int start_offset = offset;
boolean matched = matchedNewLine;
while (count-- > 0 && pos < limit)
{
char ch = buffer[pos++];
if (ch == '\r')
{
lineNumber++;
matched = true;
}
else if (ch == '\n' && !matched)
lineNumber++;
else
matched = false;
buf[offset++] = ch;
}
matchedNewLine = matched;
return offset - start_offset;
}
}
private void skipRedundantLF() throws IOException
{
if (pos > 0 && matchedNewLine)
{
if (pos < limit)
{ // fast case
if (buffer[pos] == '\n')
pos++;
}
else
{ // check whether the next buffer begins with '\n'.
// in that case kill the '\n'.
if (fill() <= 0)
return;
if (buffer[pos] == '\n')
pos++;
}
matchedNewLine = true;
}
}
/**
* This method reads a line of text from the input stream and returns
* it as a <code>String</code>. A line is considered to be terminated
* by a "\r", "\n", or "\r\n" sequence, not by the system dependent line
* separator.
*
* @return The line read as a <code>String</code> or <code>null</code>
* if end of stream.
*
* @exception IOException If an error occurs
*/
public String readLine() throws IOException
{
// BufferedReader.readLine already does this. Shouldn't need to keep
// track of newlines (since the read method deals with this for us).
// But if the buffer is large, we may not call the read method at all
// and super.readLine can't increment lineNumber itself.
// Though it may seem kludgy, the safest thing to do is to save off
// lineNumber and increment it explicitly when we're done (iff we
// ended with a '\n' or '\r' as opposed to EOF).
//
// Also, we need to undo the special casing done by BufferedReader.readLine
// when a '\r' is the last char in the buffer. That situation is marked
// by 'pos > limit'.
int tmpLineNumber = lineNumber;
skipRedundantLF();
String str = super.readLine();
if (pos > limit)
--pos;
// The only case where you mustn't increment the line number is you are
// at the EOS.
if (str != null)
lineNumber = tmpLineNumber + 1;
return str;
}
/**
* This method skips over characters in the stream. This method will
* skip the specified number of characters if possible, but is not required
* to skip them all. The actual number of characters skipped is returned.
* This method returns 0 if the specified number of chars is less than 1.
*
* @param count The specified number of chars to skip.
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs
*/
public long skip (long count) throws IOException
{
if (count < 0)
throw new IllegalArgumentException("skip() value is negative");
if (count == 0)
return 0;
int skipped;
char[] buf = new char[1];
for (skipped = 0; skipped < count; skipped++)
{
int ch = read(buf, 0, 1);
if (ch < 0)
break;
}
return skipped;
}
}
@@ -0,0 +1,72 @@
/* NotActiveException.java -- thrown when serialization is not active
Copyright (C) 1998, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when a problem occurs due to the fact that
* serialization is not active.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.1
* @status updated to 1.4
*/
public class NotActiveException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -3893467273049808895L;
/**
* Create an exception without a descriptive error message.
*/
public NotActiveException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public NotActiveException(String message)
{
super(message);
}
} // class NotActiveException
@@ -0,0 +1,74 @@
/* NotSerializableException.java -- a Serializable class that isn't
Copyright (C) 1998, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when a class implements Serializable because
* of a superclass, but should not be serialized. The descriptive message
* will consist of the name of the class in question.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.1
* @status updated to 1.4
*/
public class NotSerializableException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = 2906642554793891381L;
/**
* Create an exception without a descriptive error message.
*/
public NotSerializableException()
{
}
/**
* Create an exception with a descriptive error message, which should
* be the name of the class.
*
* @param message the descriptive error message
*/
public NotSerializableException(String message)
{
super(message);
}
} // class NotSerializableException
+140
View File
@@ -0,0 +1,140 @@
/* ObjectInput.java -- Read object data from a stream
Copyright (C) 1998,2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This interface extends the <code>DataInput</code> interface to provide a
* facility to read objects as well as primitive types from a stream. It
* also has methods that allow input to be done in a manner similar to
* <code>InputStream</code>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*
* @see DataInput
*/
public interface ObjectInput extends DataInput
{
/**
* This method returns the number of bytes that can be read without
* blocking.
*
* @return The number of bytes available before blocking
*
* @exception IOException If an error occurs
*/
int available() throws IOException;
/**
* This method reading a byte of data from a stream. It returns that byte
* as an <code>int</code>. This method blocks if no data is available
* to be read.
*
* @return The byte of data read
*
* @exception IOException If an error occurs
*/
int read() throws IOException;
/**
* This method reads raw bytes and stores them them a byte array buffer.
* Note that this method will block if no data is available. However,
* it will not necessarily block until it fills the entire buffer. That is,
* a "short count" is possible.
*
* @param buf The byte array to receive the data read
*
* @return The actual number of bytes read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
int read(byte[] buf) throws IOException;
/**
* This method reads raw bytes and stores them in a byte array buffer
* <code>buf</code> starting at position <code>offset</code> into the
* buffer. A
* maximum of <code>len</code> bytes will be read. Note that this method
* blocks if no data is available, but will not necessarily block until
* it can read <code>len</code> bytes of data. That is, a "short count" is
* possible.
*
* @param buf The byte array to receive the data read
* @param offset The offset into <code>buf</code> to start storing data
* @param len The maximum number of bytes to read
*
* @return The actual number of bytes read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
int read(byte[] buf, int offset, int len) throws IOException;
/**
* Reads an object instance and returns it. If the class for the object
* being read cannot be found, then a <code>ClassNotFoundException</code>
* will be thrown.
*
* @return The object instance that was read
*
* @exception ClassNotFoundException If a class for the object cannot be
* found
* @exception IOException If any other error occurs
*/
Object readObject()
throws ClassNotFoundException, IOException;
/**
* This method causes the specified number of bytes to be read and
* discarded. It is possible that fewer than the requested number of bytes
* will actually be skipped.
*
* @param numBytes The number of bytes to skip
*
* @return The actual number of bytes skipped
*
* @exception IOException If an error occurs
*/
long skip(long numBytes) throws IOException;
/**
* This method closes the input source
*
* @exception IOException If an error occurs
*/
void close() throws IOException;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,67 @@
/* ObjectInputValidation.java -- Validate an object
Copyright (C) 1998, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class allows an object to validate that it is valid after
* deserialization has run completely for it and all dependent objects.
* This allows an object to determine if it is invalid even if all
* state data was correctly deserialized from the stream. It can also
* be used to perform re-initialization type activities on an object
* after it has been completely deserialized.
*
* Since this method functions as a type of callback, it must be
* registered through <code>ObjectInputStream.registerValidation</code>
* in order to be invoked. This is typically done in the
* <code>readObject</code> method.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*
* @see ObjectInputStream#registerValidation
*/
public interface ObjectInputValidation
{
/**
* This method is called to validate an object after serialization
* is complete. If the object is invalid an exception is thrown.
*
* @exception InvalidObjectException If the object is invalid
*/
void validateObject() throws InvalidObjectException;
}
+111
View File
@@ -0,0 +1,111 @@
/* ObjectOutput.java -- Interface for writing objects to a stream
Copyright (C) 1998, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This interface extends <code>DataOutput</code> to provide the additional
* facility of writing object instances to a stream. It also adds some
* additional methods to make the interface more
* <code>OutputStream</code> like.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*
* @see DataOutput
*/
public interface ObjectOutput extends DataOutput
{
/**
* This method writes the specified byte to the output stream.
*
* @param b The byte to write.
*
* @exception IOException If an error occurs.
*/
void write(int b) throws IOException;
/**
* This method writes all the bytes in the specified byte array to the
* output stream.
*
* @param buf The array of bytes to write.
*
* @exception IOException If an error occurs.
*/
void write(byte[] buf) throws IOException;
/**
* This method writes <code>len</code> bytes from the specified array
* starting at index <code>offset</code> into that array.
*
* @param buf The byte array to write from.
* @param offset The index into the byte array to start writing from.
* @param len The number of bytes to write.
*
* @exception IOException If an error occurs.
*/
void write(byte[] buf, int offset, int len)
throws IOException;
/**
* This method writes a object instance to a stream. The format of the
* data written is determined by the actual implementation of this method
*
* @param obj The object to write
*
* @exception IOException If an error occurs
*/
void writeObject(Object obj) throws IOException;
/**
* This method causes any buffered data to be flushed out to the underlying
* stream
*
* @exception IOException If an error occurs
*/
void flush() throws IOException;
/**
* This method closes the underlying stream.
*
* @exception IOException If an error occurs
*/
void close() throws IOException;
} // interface ObjectOutput
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,976 @@
/* ObjectStreamClass.java -- Class used to write class information
about serialized objects.
Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.io.NullOutputStream;
import gnu.java.lang.reflect.TypeSignature;
import gnu.java.security.action.SetAccessibleAction;
import gnu.java.security.provider.Gnu;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Vector;
public class ObjectStreamClass implements Serializable
{
/**
* Returns the <code>ObjectStreamClass</code> for <code>cl</code>.
* If <code>cl</code> is null, or is not <code>Serializable</code>,
* null is returned. <code>ObjectStreamClass</code>'s are memorized;
* later calls to this method with the same class will return the
* same <code>ObjectStreamClass</code> object and no recalculation
* will be done.
*
* @see java.io.Serializable
*/
public static ObjectStreamClass lookup(Class cl)
{
if (cl == null)
return null;
if (! (Serializable.class).isAssignableFrom(cl))
return null;
return lookupForClassObject(cl);
}
/**
* This lookup for internal use by ObjectOutputStream. Suppose
* we have a java.lang.Class object C for class A, though A is not
* serializable, but it's okay to serialize C.
*/
static ObjectStreamClass lookupForClassObject(Class cl)
{
if (cl == null)
return null;
ObjectStreamClass osc = (ObjectStreamClass) classLookupTable.get(cl);
if (osc != null)
return osc;
else
{
osc = new ObjectStreamClass(cl);
classLookupTable.put(cl, osc);
return osc;
}
}
/**
* Returns the name of the class that this
* <code>ObjectStreamClass</code> represents.
*
* @return the name of the class.
*/
public String getName()
{
return name;
}
/**
* Returns the class that this <code>ObjectStreamClass</code>
* represents. Null could be returned if this
* <code>ObjectStreamClass</code> was read from an
* <code>ObjectInputStream</code> and the class it represents cannot
* be found or loaded.
*
* @see java.io.ObjectInputStream
*/
public Class forClass()
{
return clazz;
}
/**
* Returns the serial version stream-unique identifier for the class
* represented by this <code>ObjectStreamClass</code>. This SUID is
* either defined by the class as <code>static final long
* serialVersionUID</code> or is calculated as specified in
* Javasoft's "Object Serialization Specification" XXX: add reference
*
* @return the serial version UID.
*/
public long getSerialVersionUID()
{
return uid;
}
/**
* Returns the serializable (non-static and non-transient) Fields
* of the class represented by this ObjectStreamClass. The Fields
* are sorted by name.
*
* @return the fields.
*/
public ObjectStreamField[] getFields()
{
ObjectStreamField[] copy = new ObjectStreamField[ fields.length ];
System.arraycopy(fields, 0, copy, 0, fields.length);
return copy;
}
// XXX doc
// Can't do binary search since fields is sorted by name and
// primitiveness.
public ObjectStreamField getField (String name)
{
for (int i = 0; i < fields.length; i++)
if (fields[i].getName().equals(name))
return fields[i];
return null;
}
/**
* Returns a textual representation of this
* <code>ObjectStreamClass</code> object including the name of the
* class it represents as well as that class's serial version
* stream-unique identifier.
*
* @see #getSerialVersionUID()
* @see #getName()
*/
public String toString()
{
return "java.io.ObjectStreamClass< " + name + ", " + uid + " >";
}
// Returns true iff the class that this ObjectStreamClass represents
// has the following method:
//
// private void writeObject (ObjectOutputStream)
//
// This method is used by the class to override default
// serialization behavior.
boolean hasWriteMethod()
{
return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0;
}
// Returns true iff the class that this ObjectStreamClass represents
// implements Serializable but does *not* implement Externalizable.
boolean isSerializable()
{
return (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0;
}
// Returns true iff the class that this ObjectStreamClass represents
// implements Externalizable.
boolean isExternalizable()
{
return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
}
// Returns the <code>ObjectStreamClass</code> that represents the
// class that is the superclass of the class this
// <code>ObjectStreamClass</code> represents. If the superclass is
// not Serializable, null is returned.
ObjectStreamClass getSuper()
{
return superClass;
}
// returns an array of ObjectStreamClasses that represent the super
// classes of CLAZZ and CLAZZ itself in order from most super to
// CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ
// that is serializable.
static ObjectStreamClass[] getObjectStreamClasses(Class clazz)
{
ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
if (osc == null)
return new ObjectStreamClass[0];
else
{
Vector oscs = new Vector();
while (osc != null)
{
oscs.addElement (osc);
osc = osc.getSuper();
}
int count = oscs.size();
ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
for (int i = count - 1; i >= 0; i--)
sorted_oscs[ count - i - 1 ] = (ObjectStreamClass) oscs.elementAt(i);
return sorted_oscs;
}
}
// Returns an integer that consists of bit-flags that indicate
// properties of the class represented by this ObjectStreamClass.
// The bit-flags that could be present are those defined in
// ObjectStreamConstants that begin with `SC_'
int getFlags()
{
return flags;
}
ObjectStreamClass(String name, long uid, byte flags,
ObjectStreamField[] fields)
{
this.name = name;
this.uid = uid;
this.flags = flags;
this.fields = fields;
}
/**
* This method builds the internal description corresponding to a Java Class.
* As the constructor only assign a name to the current ObjectStreamClass instance,
* that method sets the serial UID, chose the fields which will be serialized,
* and compute the position of the fields in the serialized stream.
*
* @param cl The Java class which is used as a reference for building the descriptor.
* @param superClass The descriptor of the super class for this class descriptor.
* @throws InvalidClassException if an incompatibility between computed UID and
* already set UID is found.
*/
void setClass(Class cl, ObjectStreamClass superClass) throws InvalidClassException
{
this.clazz = cl;
cacheMethods();
long class_uid = getClassUID(cl);
if (uid == 0)
uid = class_uid;
else
{
// Check that the actual UID of the resolved class matches the UID from
// the stream.
if (uid != class_uid)
{
String msg = cl +
": Local class not compatible: stream serialVersionUID="
+ uid + ", local serialVersionUID=" + class_uid;
throw new InvalidClassException (msg);
}
}
isProxyClass = clazz != null && Proxy.isProxyClass(clazz);
this.superClass = superClass;
calculateOffsets();
try
{
ObjectStreamField[] exportedFields = getSerialPersistentFields (clazz);
if (exportedFields == null)
return;
ObjectStreamField[] newFieldList = new ObjectStreamField[exportedFields.length + fields.length];
int i, j, k;
/* We now check the import fields against the exported fields.
* There should not be contradiction (e.g. int x and String x)
* but extra virtual fields can be added to the class.
*/
Arrays.sort(exportedFields);
i = 0; j = 0; k = 0;
while (i < fields.length && j < exportedFields.length)
{
int comp = fields[i].compareTo(exportedFields[j]);
if (comp < 0)
{
newFieldList[k] = fields[i];
fields[i].setPersistent(false);
fields[i].setToSet(false);
i++;
}
else if (comp > 0)
{
/* field not found in imported fields. We add it
* in the list of supported fields.
*/
newFieldList[k] = exportedFields[j];
newFieldList[k].setPersistent(true);
newFieldList[k].setToSet(false);
try
{
newFieldList[k].lookupField(clazz);
newFieldList[k].checkFieldType();
}
catch (NoSuchFieldException _)
{
}
j++;
}
else
{
try
{
exportedFields[j].lookupField(clazz);
exportedFields[j].checkFieldType();
}
catch (NoSuchFieldException _)
{
}
if (!fields[i].getType().equals(exportedFields[j].getType()))
throw new InvalidClassException
("serialPersistentFields must be compatible with" +
" imported fields (about " + fields[i].getName() + ")");
newFieldList[k] = fields[i];
fields[i].setPersistent(true);
i++;
j++;
}
k++;
}
if (i < fields.length)
for (;i<fields.length;i++,k++)
{
fields[i].setPersistent(false);
fields[i].setToSet(false);
newFieldList[k] = fields[i];
}
else
if (j < exportedFields.length)
for (;j<exportedFields.length;j++,k++)
{
exportedFields[j].setPersistent(true);
exportedFields[j].setToSet(false);
newFieldList[k] = exportedFields[j];
}
fields = new ObjectStreamField[k];
System.arraycopy(newFieldList, 0, fields, 0, k);
}
catch (NoSuchFieldException ignore)
{
return;
}
catch (IllegalAccessException ignore)
{
return;
}
}
void setSuperclass (ObjectStreamClass osc)
{
superClass = osc;
}
void calculateOffsets()
{
int i;
ObjectStreamField field;
primFieldSize = 0;
int fcount = fields.length;
for (i = 0; i < fcount; ++ i)
{
field = fields[i];
if (! field.isPrimitive())
break;
field.setOffset(primFieldSize);
switch (field.getTypeCode())
{
case 'B':
case 'Z':
++ primFieldSize;
break;
case 'C':
case 'S':
primFieldSize += 2;
break;
case 'I':
case 'F':
primFieldSize += 4;
break;
case 'D':
case 'J':
primFieldSize += 8;
break;
}
}
for (objectFieldCount = 0; i < fcount; ++ i)
fields[i].setOffset(objectFieldCount++);
}
private Method findMethod(Method[] methods, String name, Class[] params,
Class returnType, boolean mustBePrivate)
{
outer:
for (int i = 0; i < methods.length; i++)
{
final Method m = methods[i];
int mods = m.getModifiers();
if (Modifier.isStatic(mods)
|| (mustBePrivate && !Modifier.isPrivate(mods)))
{
continue;
}
if (m.getName().equals(name)
&& m.getReturnType() == returnType)
{
Class[] mp = m.getParameterTypes();
if (mp.length == params.length)
{
for (int j = 0; j < mp.length; j++)
{
if (mp[j] != params[j])
{
continue outer;
}
}
AccessController.doPrivileged(new SetAccessibleAction(m));
return m;
}
}
}
return null;
}
private static boolean inSamePackage(Class c1, Class c2)
{
String name1 = c1.getName();
String name2 = c2.getName();
int id1 = name1.lastIndexOf('.');
int id2 = name2.lastIndexOf('.');
// Handle the default package
if (id1 == -1 || id2 == -1)
return id1 == id2;
String package1 = name1.substring(0, id1);
String package2 = name2.substring(0, id2);
return package1.equals(package2);
}
final static Class[] noArgs = new Class[0];
private static Method findAccessibleMethod(String name, Class from)
{
for (Class c = from; c != null; c = c.getSuperclass())
{
try
{
Method res = c.getDeclaredMethod(name, noArgs);
int mods = res.getModifiers();
if (c != from
&& (Modifier.isPrivate(mods)
|| ! Modifier.isPublic(mods) && ! inSamePackage(c, from)))
continue;
AccessController.doPrivileged(new SetAccessibleAction(res));
return res;
}
catch (NoSuchMethodException e)
{
}
}
return null;
}
private void cacheMethods()
{
Method[] methods = forClass().getDeclaredMethods();
readObjectMethod = findMethod(methods, "readObject",
new Class[] { ObjectInputStream.class },
Void.TYPE, true);
writeObjectMethod = findMethod(methods, "writeObject",
new Class[] { ObjectOutputStream.class },
Void.TYPE, true);
// readResolve and writeReplace can be in parent classes, as long as they
// are accessible from this class.
readResolveMethod = findAccessibleMethod("readResolve", forClass());
writeReplaceMethod = findAccessibleMethod("writeReplace", forClass());
}
private ObjectStreamClass(Class cl)
{
uid = 0;
flags = 0;
isProxyClass = Proxy.isProxyClass(cl);
clazz = cl;
cacheMethods();
name = cl.getName();
setFlags(cl);
setFields(cl);
// to those class nonserializable, its uid field is 0
if ( (Serializable.class).isAssignableFrom(cl) && !isProxyClass)
uid = getClassUID(cl);
superClass = lookup(cl.getSuperclass());
}
// Sets bits in flags according to features of CL.
private void setFlags(Class cl)
{
if ((java.io.Externalizable.class).isAssignableFrom(cl))
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
else if ((java.io.Serializable.class).isAssignableFrom(cl))
// only set this bit if CL is NOT Externalizable
flags |= ObjectStreamConstants.SC_SERIALIZABLE;
if (writeObjectMethod != null)
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
}
// Sets fields to be a sorted array of the serializable fields of
// clazz.
private void setFields(Class cl)
{
SetAccessibleAction setAccessible = new SetAccessibleAction();
if (!isSerializable() || isExternalizable())
{
fields = NO_FIELDS;
return;
}
try
{
final Field f =
cl.getDeclaredField("serialPersistentFields");
setAccessible.setMember(f);
AccessController.doPrivileged(setAccessible);
int modifiers = f.getModifiers();
if (Modifier.isStatic(modifiers)
&& Modifier.isFinal(modifiers)
&& Modifier.isPrivate(modifiers))
{
fields = getSerialPersistentFields(cl);
if (fields != null)
{
Arrays.sort (fields);
// Retrieve field reference.
for (int i=0; i < fields.length; i++)
{
try
{
fields[i].lookupField(cl);
}
catch (NoSuchFieldException _)
{
fields[i].setToSet(false);
}
}
calculateOffsets();
return;
}
}
}
catch (NoSuchFieldException ignore)
{
}
catch (IllegalAccessException ignore)
{
}
int num_good_fields = 0;
Field[] all_fields = cl.getDeclaredFields();
int modifiers;
// set non-serializable fields to null in all_fields
for (int i = 0; i < all_fields.length; i++)
{
modifiers = all_fields[i].getModifiers();
if (Modifier.isTransient(modifiers)
|| Modifier.isStatic(modifiers))
all_fields[i] = null;
else
num_good_fields++;
}
// make a copy of serializable (non-null) fields
fields = new ObjectStreamField[ num_good_fields ];
for (int from = 0, to = 0; from < all_fields.length; from++)
if (all_fields[from] != null)
{
final Field f = all_fields[from];
setAccessible.setMember(f);
AccessController.doPrivileged(setAccessible);
fields[to] = new ObjectStreamField(all_fields[from]);
to++;
}
Arrays.sort(fields);
// Make sure we don't have any duplicate field names
// (Sun JDK 1.4.1. throws an Internal Error as well)
for (int i = 1; i < fields.length; i++)
{
if(fields[i - 1].getName().equals(fields[i].getName()))
throw new InternalError("Duplicate field " +
fields[i].getName() + " in class " + cl.getName());
}
calculateOffsets();
}
// Returns the serial version UID defined by class, or if that
// isn't present, calculates value of serial version UID.
private long getClassUID(Class cl)
{
try
{
// Use getDeclaredField rather than getField, since serialVersionUID
// may not be public AND we only want the serialVersionUID of this
// class, not a superclass or interface.
final Field suid = cl.getDeclaredField("serialVersionUID");
SetAccessibleAction setAccessible = new SetAccessibleAction(suid);
AccessController.doPrivileged(setAccessible);
int modifiers = suid.getModifiers();
if (Modifier.isStatic(modifiers)
&& Modifier.isFinal(modifiers)
&& suid.getType() == Long.TYPE)
return suid.getLong(null);
}
catch (NoSuchFieldException ignore)
{
}
catch (IllegalAccessException ignore)
{
}
// cl didn't define serialVersionUID, so we have to compute it
try
{
MessageDigest md;
try
{
md = MessageDigest.getInstance("SHA");
}
catch (NoSuchAlgorithmException e)
{
// If a provider already provides SHA, use it; otherwise, use this.
Gnu gnuProvider = new Gnu();
Security.addProvider(gnuProvider);
md = MessageDigest.getInstance("SHA");
}
DigestOutputStream digest_out =
new DigestOutputStream(nullOutputStream, md);
DataOutputStream data_out = new DataOutputStream(digest_out);
data_out.writeUTF(cl.getName());
int modifiers = cl.getModifiers();
// just look at interesting bits
modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
| Modifier.INTERFACE | Modifier.PUBLIC);
data_out.writeInt(modifiers);
// Pretend that an array has no interfaces, because when array
// serialization was defined (JDK 1.1), arrays didn't have it.
if (! cl.isArray())
{
Class[] interfaces = cl.getInterfaces();
Arrays.sort(interfaces, interfaceComparator);
for (int i = 0; i < interfaces.length; i++)
data_out.writeUTF(interfaces[i].getName());
}
Field field;
Field[] fields = cl.getDeclaredFields();
Arrays.sort(fields, memberComparator);
for (int i = 0; i < fields.length; i++)
{
field = fields[i];
modifiers = field.getModifiers();
if (Modifier.isPrivate(modifiers)
&& (Modifier.isStatic(modifiers)
|| Modifier.isTransient(modifiers)))
continue;
data_out.writeUTF(field.getName());
data_out.writeInt(modifiers);
data_out.writeUTF(TypeSignature.getEncodingOfClass (field.getType()));
}
// write class initializer method if present
if (VMObjectStreamClass.hasClassInitializer(cl))
{
data_out.writeUTF("<clinit>");
data_out.writeInt(Modifier.STATIC);
data_out.writeUTF("()V");
}
Constructor constructor;
Constructor[] constructors = cl.getDeclaredConstructors();
Arrays.sort (constructors, memberComparator);
for (int i = 0; i < constructors.length; i++)
{
constructor = constructors[i];
modifiers = constructor.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF("<init>");
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfConstructor(constructor).replace('/','.'));
}
Method method;
Method[] methods = cl.getDeclaredMethods();
Arrays.sort(methods, memberComparator);
for (int i = 0; i < methods.length; i++)
{
method = methods[i];
modifiers = method.getModifiers();
if (Modifier.isPrivate(modifiers))
continue;
data_out.writeUTF(method.getName());
data_out.writeInt(modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF
(TypeSignature.getEncodingOfMethod(method).replace('/', '.'));
}
data_out.close();
byte[] sha = md.digest();
long result = 0;
int len = sha.length < 8 ? sha.length : 8;
for (int i = 0; i < len; i++)
result += (long) (sha[i] & 0xFF) << (8 * i);
return result;
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException
("The SHA algorithm was not found to use in computing the Serial Version UID for class "
+ cl.getName(), e);
}
catch (IOException ioe)
{
throw new RuntimeException(ioe);
}
}
/**
* Returns the value of CLAZZ's private static final field named
* `serialPersistentFields'. It performs some sanity checks before
* returning the real array. Besides, the returned array is a clean
* copy of the original. So it can be modified.
*
* @param clazz Class to retrieve 'serialPersistentFields' from.
* @return The content of 'serialPersistentFields'.
*/
private ObjectStreamField[] getSerialPersistentFields(Class clazz)
throws NoSuchFieldException, IllegalAccessException
{
ObjectStreamField[] fieldsArray = null;
ObjectStreamField[] o;
// Use getDeclaredField rather than getField for the same reason
// as above in getDefinedSUID.
Field f = clazz.getDeclaredField("serialPersistentFields");
f.setAccessible(true);
int modifiers = f.getModifiers();
if (!(Modifier.isStatic(modifiers) &&
Modifier.isFinal(modifiers) &&
Modifier.isPrivate(modifiers)))
return null;
o = (ObjectStreamField[]) f.get(null);
if (o == null)
return null;
fieldsArray = new ObjectStreamField[ o.length ];
System.arraycopy(o, 0, fieldsArray, 0, o.length);
return fieldsArray;
}
/**
* Returns a new instance of the Class this ObjectStreamClass corresponds
* to.
* Note that this should only be used for Externalizable classes.
*
* @return A new instance.
*/
Externalizable newInstance() throws InvalidClassException
{
synchronized(this)
{
if (constructor == null)
{
try
{
final Constructor c = clazz.getConstructor(new Class[0]);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
c.setAccessible(true);
return null;
}
});
constructor = c;
}
catch(NoSuchMethodException x)
{
throw new InvalidClassException(clazz.getName(),
"No public zero-argument constructor");
}
}
}
try
{
return (Externalizable)constructor.newInstance(null);
}
catch(Exception x)
{
throw (InvalidClassException)
new InvalidClassException(clazz.getName(),
"Unable to instantiate").initCause(x);
}
}
public static final ObjectStreamField[] NO_FIELDS = {};
private static Hashtable classLookupTable = new Hashtable();
private static final NullOutputStream nullOutputStream = new NullOutputStream();
private static final Comparator interfaceComparator = new InterfaceComparator();
private static final Comparator memberComparator = new MemberComparator();
private static final
Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
private ObjectStreamClass superClass;
private Class clazz;
private String name;
private long uid;
private byte flags;
// this field is package protected so that ObjectInputStream and
// ObjectOutputStream can access it directly
ObjectStreamField[] fields;
// these are accessed by ObjectIn/OutputStream
int primFieldSize = -1; // -1 if not yet calculated
int objectFieldCount;
Method readObjectMethod;
Method readResolveMethod;
Method writeReplaceMethod;
Method writeObjectMethod;
boolean realClassIsSerializable;
boolean realClassIsExternalizable;
ObjectStreamField[] fieldMapping;
Constructor firstNonSerializableParentConstructor;
private Constructor constructor; // default constructor for Externalizable
boolean isProxyClass = false;
// This is probably not necessary because this class is special cased already
// but it will avoid showing up as a discrepancy when comparing SUIDs.
private static final long serialVersionUID = -6120832682080437368L;
// interfaces are compared only by name
private static final class InterfaceComparator implements Comparator
{
public int compare(Object o1, Object o2)
{
return ((Class) o1).getName().compareTo(((Class) o2).getName());
}
}
// Members (Methods and Constructors) are compared first by name,
// conflicts are resolved by comparing type signatures
private static final class MemberComparator implements Comparator
{
public int compare(Object o1, Object o2)
{
Member m1 = (Member) o1;
Member m2 = (Member) o2;
int comp = m1.getName().compareTo(m2.getName());
if (comp == 0)
return TypeSignature.getEncodingOfMember(m1).
compareTo(TypeSignature.getEncodingOfMember(m2));
else
return comp;
}
}
}
@@ -0,0 +1,89 @@
/* ObjectStreamConstants.java -- Interface containing constant values
used in reading and writing serialized objects
Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This interface contains constants that are used in object
* serialization. This interface is used by <code>ObjectOutputStream</code>,
* <code>ObjectInputStream</code>, and <code>ObjectStreamClass</code>.
* The values for these constants are specified by the Java library
* specification.
*/
public interface ObjectStreamConstants
{
// FIXME: Javadoc comment these values.
int PROTOCOL_VERSION_1 = 1;
int PROTOCOL_VERSION_2 = 2;
short STREAM_MAGIC = (short)0xaced;
short STREAM_VERSION = 5;
byte TC_NULL = (byte)112; //0x70
byte TC_REFERENCE = (byte)113; //0x71
byte TC_CLASSDESC = (byte)114; //0x72
byte TC_OBJECT = (byte)115; //0x73
byte TC_STRING = (byte)116; //0x74
byte TC_ARRAY = (byte)117; //0x75
byte TC_CLASS = (byte)118; //0x76
byte TC_BLOCKDATA = (byte)119; //0x77
byte TC_ENDBLOCKDATA = (byte)120; //0x78
byte TC_RESET = (byte)121; //0x79
byte TC_BLOCKDATALONG = (byte)122; //0x7A
byte TC_EXCEPTION = (byte)123; //0x7B
byte TC_LONGSTRING = (byte)124; //0x7C
byte TC_PROXYCLASSDESC = (byte)125; //0x7D
byte TC_BASE = TC_NULL;
byte TC_MAX = TC_PROXYCLASSDESC;
int baseWireHandle = 0x7e0000;
byte SC_WRITE_METHOD = 0x01;
byte SC_SERIALIZABLE = 0x02;
byte SC_EXTERNALIZABLE = 0x04;
byte SC_BLOCK_DATA = 0x08;
SerializablePermission SUBSTITUTION_PERMISSION
= new SerializablePermission("enableSubstitution");
SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION
= new SerializablePermission("enableSubclassImplementation");
}
@@ -0,0 +1,74 @@
/* ObjectStreamException.java -- Superclass of all serialization exceptions
Copyright (C) 1998, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when a problem occurs during serialization.
* There are more specific subclasses that give more fine grained
* indications of the precise failure.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @since 1.1
* @status updated to 1.4
*/
public abstract class ObjectStreamException extends IOException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = 7260898174833392607L;
/**
* Create an exception without a descriptive error message.
*/
protected ObjectStreamException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
protected ObjectStreamException(String message)
{
super(message);
}
} // class ObjectStreamException
@@ -0,0 +1,412 @@
/* ObjectStreamField.java -- Class used to store name and class of fields
Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.lang.reflect.TypeSignature;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* This class intends to describe the field of a class for the serialization
* subsystem. Serializable fields in a serializable class can be explicitly
* exported using an array of ObjectStreamFields.
*/
public class ObjectStreamField implements Comparable
{
private String name;
private Class type;
private String typename;
private int offset = -1; // XXX make sure this is correct
private boolean unshared;
private boolean persistent = false;
private boolean toset = true;
private Field field;
ObjectStreamField (Field field)
{
this (field.getName(), field.getType());
this.field = field;
}
/**
* This constructor creates an ObjectStreamField instance
* which represents a field named <code>name</code> and is
* of the type <code>type</code>.
*
* @param name Name of the field to export.
* @param type Type of the field in the concerned class.
*/
public ObjectStreamField (String name, Class type)
{
this (name, type, false);
}
/**
* This constructor creates an ObjectStreamField instance
* which represents a field named <code>name</code> and is
* of the type <code>type</code>.
*
* @param name Name of the field to export.
* @param type Type of the field in the concerned class.
* @param unshared true if field will be unshared, false otherwise.
*/
public ObjectStreamField (String name, Class type, boolean unshared)
{
if (name == null)
throw new NullPointerException();
this.name = name;
this.type = type;
this.typename = TypeSignature.getEncodingOfClass(type);
this.unshared = unshared;
}
/**
* There are many cases you can not get java.lang.Class from typename
* if your context class loader cannot load it, then use typename to
* construct the field.
*
* @param name Name of the field to export.
* @param typename The coded name of the type for this field.
*/
ObjectStreamField (String name, String typename)
{
this.name = name;
this.typename = typename;
try
{
type = TypeSignature.getClassForEncoding(typename);
}
catch(ClassNotFoundException e)
{
}
}
/**
* There are many cases you can not get java.lang.Class from typename
* if your context class loader cann not load it, then use typename to
* construct the field.
*
* @param name Name of the field to export.
* @param typename The coded name of the type for this field.
* @param loader The class loader to use to resolve class names.
*/
ObjectStreamField (String name, String typename, ClassLoader loader)
{
this.name = name;
this.typename = typename;
try
{
type = TypeSignature.getClassForEncoding(typename, true, loader);
}
catch(ClassNotFoundException e)
{
}
}
/**
* This method returns the name of the field represented by the
* ObjectStreamField instance.
*
* @return A string containing the name of the field.
*/
public String getName ()
{
return name;
}
/**
* This method returns the class representing the type of the
* field which is represented by this instance of ObjectStreamField.
*
* @return A class representing the type of the field.
*/
public Class getType ()
{
return type;
}
/**
* This method returns the char encoded type of the field which
* is represented by this instance of ObjectStreamField.
*
* @return A char representing the type of the field.
*/
public char getTypeCode ()
{
return typename.charAt (0);
}
/**
* This method returns a more explicit type name than
* {@link #getTypeCode()} in the case the type is a real
* class (and not a primitive).
*
* @return The name of the type (class name) if it is not a
* primitive, in the other case null is returned.
*/
public String getTypeString ()
{
// use intern()
if (isPrimitive())
return null;
return typename.intern();
}
/**
* This method returns the current offset of the field in
* the serialization stream relatively to the other fields.
* The offset is expressed in bytes.
*
* @return The offset of the field in bytes.
* @see #setOffset(int)
*/
public int getOffset ()
{
return offset;
}
/**
* This method sets the current offset of the field.
*
* @param off The offset of the field in bytes.
* @see getOffset()
*/
protected void setOffset (int off)
{
offset = off;
}
/**
* This method returns whether the field represented by this object is
* unshared or not.
*
* @return Tells if this field is unshared or not.
*/
public boolean isUnshared ()
{
return unshared;
}
/**
* This method returns true if the type of the field
* represented by this instance is a primitive.
*
* @return true if the type is a primitive, false
* in the other case.
*/
public boolean isPrimitive ()
{
return typename.length() == 1;
}
/**
* Compares this object to the given object.
*
* @param obj the object to compare to.
*
* @return -1, 0 or 1.
*/
public int compareTo (Object obj)
{
ObjectStreamField f = (ObjectStreamField) obj;
boolean this_is_primitive = isPrimitive ();
boolean f_is_primitive = f.isPrimitive ();
if (this_is_primitive && !f_is_primitive)
return -1;
if (!this_is_primitive && f_is_primitive)
return 1;
return getName ().compareTo (f.getName ());
}
/**
* This method is specific to classpath's implementation and so has the default
* access. It changes the state of this field to "persistent". It means that
* the field should not be changed when the stream is read (if it is not
* explicitly specified using serialPersistentFields).
*
* @param persistent True if the field is persistent, false in the
* other cases.
* @see #isPersistent()
*/
void setPersistent(boolean persistent)
{
this.persistent = persistent;
}
/**
* This method returns true if the field is marked as persistent.
*
* @return True if persistent, false in the other cases.
* @see #setPersistent(boolean)
*/
boolean isPersistent()
{
return persistent;
}
/**
* This method is specific to classpath's implementation and so
* has the default access. It changes the state of this field as
* to be set by ObjectInputStream.
*
* @param toset True if this field should be set, false in the other
* cases.
* @see #isToSet()
*/
void setToSet(boolean toset)
{
this.toset = toset;
}
/**
* This method returns true if the field is marked as to be
* set.
*
* @return True if it is to be set, false in the other cases.
* @see #setToSet(boolean)
*/
boolean isToSet()
{
return toset;
}
/**
* This method searches for its field reference in the specified class
* object. It requests privileges. If an error occurs the internal field
* reference is not modified.
*
* @throws NoSuchFieldException if the field name does not exist in this class.
* @throws SecurityException if there was an error requesting the privileges.
*/
void lookupField(Class clazz) throws NoSuchFieldException, SecurityException
{
final Field f = clazz.getDeclaredField(name);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
f.setAccessible(true);
return null;
}
});
this.field = f;
}
/**
* This method check whether the field described by this
* instance of ObjectStreamField is compatible with the
* actual implementation of this field.
*
* @throws NullPointerException if this field does not exist
* in the real class.
* @throws InvalidClassException if the types are incompatible.
*/
void checkFieldType() throws InvalidClassException
{
Class ftype = field.getType();
if (!ftype.isAssignableFrom(type))
throw new InvalidClassException
("invalid field type for " + name +
" in class " + field.getDeclaringClass());
}
/**
* Returns a string representing this object.
*
* @return the string.
*/
public String toString ()
{
return "ObjectStreamField< " + type + " " + name + " >";
}
final void setBooleanField(Object obj, boolean val)
{
VMObjectStreamClass.setBooleanNative(field, obj, val);
}
final void setByteField(Object obj, byte val)
{
VMObjectStreamClass.setByteNative(field, obj, val);
}
final void setCharField(Object obj, char val)
{
VMObjectStreamClass.setCharNative(field, obj, val);
}
final void setShortField(Object obj, short val)
{
VMObjectStreamClass.setShortNative(field, obj, val);
}
final void setIntField(Object obj, int val)
{
VMObjectStreamClass.setIntNative(field, obj, val);
}
final void setLongField(Object obj, long val)
{
VMObjectStreamClass.setLongNative(field, obj, val);
}
final void setFloatField(Object obj, float val)
{
VMObjectStreamClass.setFloatNative(field, obj, val);
}
final void setDoubleField(Object obj, double val)
{
VMObjectStreamClass.setDoubleNative(field, obj, val);
}
final void setObjectField(Object obj, Object val)
{
VMObjectStreamClass.setObjectNative(field, obj, val);
}
}
@@ -0,0 +1,91 @@
/* OptionalDataException.java -- indicates unexpected data in serialized stream
Copyright (C) 1998, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when unexpected data appears in the input
* stream from which a serialized object is being read. There are two
* cases:<br><ul>
* <li>The next stream element is primitive data. <code>eof</code> will
* be false, and <code>count</code> is the number of bytes of primitive
* data available.</li>
* <li>The data consumable by readObject or readExternal has been exhausted.
* <code>eof</code> is true, and <code>count</code> is 0.</li>
* </ul>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @since 1.1
* @status updated to 1.4
*/
public class OptionalDataException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -8011121865681257820L;
/**
* Whether or not the end of the stream has been reached.
*
* @serial the end of the buffer was reached
*/
public boolean eof;
/**
* The number of valid bytes that can be read.
*
* @serial the bytes of the buffer remaining
*/
public int length;
/**
* Create a new OptionalDataException with an eof parameter indicating
* whether or not the end of stream is reached and the number of valid
* bytes that may be read.
*
* @param eof 'true' if end of stream reached, 'false' otherwise
* @param count The number of valid bytes to be read
*/
OptionalDataException(boolean eof, int count)
{
this.eof = eof;
this.length = count;
}
} // class OptionalDataException
+140
View File
@@ -0,0 +1,140 @@
/* OutputStream.java -- Base class for byte output streams
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This abstract class forms the base of the hierarchy of classes that
* write output as a stream of bytes. It provides a common set of methods
* for writing bytes to stream. Subclasses implement and/or extend these
* methods to write bytes in a particular manner or to a particular
* destination such as a file on disk or network connection.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public abstract class OutputStream
{
/**
* This is the default no-argument constructor for this class. This method
* does nothing in this class.
*/
public OutputStream ()
{
}
/**
* This method writes a single byte to the output stream. The byte written
* is the low eight bits of the <code>int</code> passed and a argument.
* <p>
* Subclasses must provide an implementation of this abstract method
*
* @param b The byte to be written to the output stream, passed as
* the low eight bits of an <code>int</code>
*
* @exception IOException If an error occurs
*/
public abstract void write (int b) throws IOException;
/**
* This method all the writes bytes from the passed array to the
* output stream. This method is equivalent to <code>write(b, 0,
* buf.length)</code> which is exactly how it is implemented in this
* class.
*
* @param b The array of bytes to write
*
* @exception IOException If an error occurs
*/
public void write (byte[] b) throws IOException, NullPointerException
{
write (b, 0, b.length);
}
/**
* This method writes <code>len</code> bytes from the specified array
* <code>b</code> starting at index <code>off</code> into the array.
* <p>
* This method in this class calls the single byte <code>write()</code>
* method in a loop until all bytes have been written. Subclasses should
* override this method if possible in order to provide a more efficent
* implementation.
*
* @param b The array of bytes to write from
* @param off The index into the array to start writing from
* @param len The number of bytes to write
*
* @exception IOException If an error occurs
*/
public void write (byte[] b, int off, int len)
throws IOException, NullPointerException, IndexOutOfBoundsException
{
if (off < 0 || len < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException ();
for (int i = 0; i < len; ++i)
write (b[off + i]);
}
/**
* This method forces any data that may have been buffered to be written
* to the underlying output device. Please note that the host environment
* might perform its own buffering unbeknowst to Java. In that case, a
* write made (for example, to a disk drive) might be cached in OS
* buffers instead of actually being written to disk.
* <p>
* This method in this class does nothing.
*
* @exception IOException If an error occurs
*/
public void flush () throws IOException
{
}
/**
* This method closes the stream. Any internal or native resources
* associated with this stream are freed. Any subsequent attempt to
* access the stream might throw an exception.
* <p>
* This method in this class does nothing.
*
* @exception IOException If an error occurs
*/
public void close () throws IOException
{
}
}
@@ -0,0 +1,356 @@
/* OutputStreamWriter.java -- Writer that converts chars to bytes
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.nio.charset.EncodingHelper;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnsupportedCharsetException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
/**
* This class writes characters to an output stream that is byte oriented
* It converts the chars that are written to bytes using an encoding layer,
* which is specific to a particular encoding standard. The desired
* encoding can either be specified by name, or if no encoding is specified,
* the system default encoding will be used. The system default encoding
* name is determined from the system property <code>file.encoding</code>.
* The only encodings that are guaranteed to be available are "8859_1"
* (the Latin-1 character set) and "UTF8". Unfortunately, Java does not
* provide a mechanism for listing the encodings that are supported in
* a given implementation.
* <p>
* Here is a list of standard encoding names that may be available:
* <p>
* <ul>
* <li>8859_1 (ISO-8859-1/Latin-1)
* <li>8859_2 (ISO-8859-2/Latin-2)
* <li>8859_3 (ISO-8859-3/Latin-3)
* <li>8859_4 (ISO-8859-4/Latin-4)
* <li>8859_5 (ISO-8859-5/Latin-5)
* <li>8859_6 (ISO-8859-6/Latin-6)
* <li>8859_7 (ISO-8859-7/Latin-7)
* <li>8859_8 (ISO-8859-8/Latin-8)
* <li>8859_9 (ISO-8859-9/Latin-9)
* <li>ASCII (7-bit ASCII)
* <li>UTF8 (UCS Transformation Format-8)
* <li>More Later
* </ul>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner (bothner@cygnus.com)
* @date April 17, 1998.
*/
public class OutputStreamWriter extends Writer
{
/**
* The output stream.
*/
private OutputStream out;
/**
* The charset encoder.
*/
private CharsetEncoder encoder;
/**
* java.io canonical name of the encoding.
*/
private String encodingName;
/**
* Buffer output before character conversion as it has costly overhead.
*/
private CharBuffer outputBuffer;
private final static int BUFFER_SIZE = 1024;
/**
* This method initializes a new instance of <code>OutputStreamWriter</code>
* to write to the specified stream using a caller supplied character
* encoding scheme. Note that due to a deficiency in the Java language
* design, there is no way to determine which encodings are supported.
*
* @param out The <code>OutputStream</code> to write to
* @param encoding_scheme The name of the encoding scheme to use for
* character to byte translation
*
* @exception UnsupportedEncodingException If the named encoding is
* not available.
*/
public OutputStreamWriter (OutputStream out, String encoding_scheme)
throws UnsupportedEncodingException
{
this.out = out;
try
{
// Don't use NIO if avoidable
if(EncodingHelper.isISOLatin1(encoding_scheme))
{
encodingName = "ISO8859_1";
encoder = null;
return;
}
/*
* Workraround for encodings with a byte-order-mark.
* We only want to write it once per stream.
*/
try {
if(encoding_scheme.equalsIgnoreCase("UnicodeBig") ||
encoding_scheme.equalsIgnoreCase("UTF-16") ||
encoding_scheme.equalsIgnoreCase("UTF16"))
{
encoding_scheme = "UTF-16BE";
out.write((byte)0xFE);
out.write((byte)0xFF);
} else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle")){
encoding_scheme = "UTF-16LE";
out.write((byte)0xFF);
out.write((byte)0xFE);
}
} catch(IOException ioe){
}
outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
Charset cs = EncodingHelper.getCharset(encoding_scheme);
if(cs == null)
throw new UnsupportedEncodingException("Encoding "+encoding_scheme+
" unknown");
encoder = cs.newEncoder();
encodingName = EncodingHelper.getOldCanonical(cs.name());
encoder.onMalformedInput(CodingErrorAction.REPLACE);
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
} catch(RuntimeException e) {
// Default to ISO Latin-1, will happen if this is called, for instance,
// before the NIO provider is loadable.
encoder = null;
encodingName = "ISO8859_1";
}
}
/**
* This method initializes a new instance of <code>OutputStreamWriter</code>
* to write to the specified stream using the default encoding.
*
* @param out The <code>OutputStream</code> to write to
*/
public OutputStreamWriter (OutputStream out)
{
this.out = out;
outputBuffer = null;
try
{
String encoding = System.getProperty("file.encoding");
Charset cs = Charset.forName(encoding);
encoder = cs.newEncoder();
encodingName = EncodingHelper.getOldCanonical(cs.name());
} catch(RuntimeException e) {
encoder = null;
encodingName = "ISO8859_1";
}
if(encoder != null)
{
encoder.onMalformedInput(CodingErrorAction.REPLACE);
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
}
}
/**
* This method closes this stream, and the underlying
* <code>OutputStream</code>
*
* @exception IOException If an error occurs
*/
public void close () throws IOException
{
if(out == null)
return;
flush();
out.close ();
out = null;
}
/**
* This method returns the name of the character encoding scheme currently
* in use by this stream. If the stream has been closed, then this method
* may return <code>null</code>.
*
* @return The encoding scheme name
*/
public String getEncoding ()
{
return out != null ? encodingName : null;
}
/**
* This method flushes any buffered bytes to the underlying output sink.
*
* @exception IOException If an error occurs
*/
public void flush () throws IOException
{
if(out != null){
if(outputBuffer != null){
char[] buf = new char[outputBuffer.position()];
if(buf.length > 0){
outputBuffer.flip();
outputBuffer.get(buf);
writeConvert(buf, 0, buf.length);
outputBuffer.clear();
}
}
out.flush ();
}
}
/**
* This method writes <code>count</code> characters from the specified
* array to the output stream starting at position <code>offset</code>
* into the array.
*
* @param buf The array of character to write from
* @param offset The offset into the array to start writing chars from
* @param count The number of chars to write.
*
* @exception IOException If an error occurs
*/
public void write (char[] buf, int offset, int count) throws IOException
{
if(out == null)
throw new IOException("Stream is closed.");
if(buf == null)
throw new IOException("Buffer is null.");
if(outputBuffer != null)
{
if(count >= outputBuffer.remaining())
{
int r = outputBuffer.remaining();
outputBuffer.put(buf, offset, r);
writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
outputBuffer.clear();
offset += r;
count -= r;
// if the remaining bytes is larger than the whole buffer,
// just don't buffer.
if(count >= outputBuffer.remaining()){
writeConvert(buf, offset, count);
return;
}
}
outputBuffer.put(buf, offset, count);
} else writeConvert(buf, offset, count);
}
/**
* Converts and writes characters.
*/
private void writeConvert (char[] buf, int offset, int count)
throws IOException
{
if(encoder == null)
{
byte[] b = new byte[count];
for(int i=0;i<count;i++)
b[i] = (byte)((buf[offset+i] <= 0xFF)?buf[offset+i]:'?');
out.write(b);
} else {
try {
ByteBuffer output = encoder.encode(CharBuffer.wrap(buf,offset,count));
encoder.reset();
if(output.hasArray())
out.write(output.array());
else
{
byte[] outbytes = new byte[output.remaining()];
output.get(outbytes);
out.write(outbytes);
}
} catch(IllegalStateException e) {
throw new IOException("Internal error.");
} catch(MalformedInputException e) {
throw new IOException("Invalid character sequence.");
} catch(CharacterCodingException e) {
throw new IOException("Unmappable character.");
}
}
}
/**
* This method writes <code>count</code> bytes from the specified
* <code>String</code> starting at position <code>offset</code> into the
* <code>String</code>.
*
* @param str The <code>String</code> to write chars from
* @param offset The position in the <code>String</code> to start
* writing chars from
* @param count The number of chars to write
*
* @exception IOException If an error occurs
*/
public void write (String str, int offset, int count) throws IOException
{
if(str == null)
throw new IOException("String is null.");
write(str.toCharArray(), offset, count);
}
/**
* This method writes a single character to the output stream.
*
* @param ch The char to write, passed as an int.
*
* @exception IOException If an error occurs
*/
public void write (int ch) throws IOException
{
write(new char[]{ (char)ch }, 0, 1);
}
} // class OutputStreamWriter
@@ -0,0 +1,374 @@
/* PipedInputStream.java -- Read portion of piped streams.
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
// NOTE: This implementation is very similar to that of PipedReader. If you
// fix a bug in here, chances are you should make a similar change to the
// PipedReader code.
/**
* An input stream that reads its bytes from an output stream
* to which it is connected.
* <p>
* Data is read and written to an internal buffer. It is highly recommended
* that the <code>PipedInputStream</code> and connected
* <code>PipedOutputStream</code>
* be part of different threads. If they are not, the read and write
* operations could deadlock their thread.
*
* @specnote The JDK implementation appears to have some undocumented
* functionality where it keeps track of what thread is writing
* to pipe and throws an IOException if that thread susequently
* dies. This behaviour seems dubious and unreliable - we don't
* implement it.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class PipedInputStream extends InputStream
{
/** PipedOutputStream to which this is connected. Null only if this
* InputStream hasn't been connected yet. */
PipedOutputStream source;
/** Set to true if close() has been called on this InputStream. */
boolean closed;
/**
* The size of the internal buffer used for input/output.
*/
/* The "Constant Field Values" Javadoc of the Sun J2SE 1.4
* specifies 1024.
*/
protected static final int PIPE_SIZE = 1024;
/**
* This is the internal circular buffer used for storing bytes written
* to the pipe and from which bytes are read by this stream
*/
protected byte[] buffer = new byte[PIPE_SIZE];
/**
* The index into buffer where the next byte from the connected
* <code>PipedOutputStream</code> will be written. If this variable is
* equal to <code>out</code>, then the buffer is full. If set to < 0,
* the buffer is empty.
*/
protected int in = -1;
/**
* This index into the buffer where bytes will be read from.
*/
protected int out = 0;
/** Buffer used to implement single-argument read/receive */
private byte[] read_buf = new byte[1];
/**
* Creates a new <code>PipedInputStream</code> that is not connected to a
* <code>PipedOutputStream</code>. It must be connected before bytes can
* be read from this stream.
*/
public PipedInputStream()
{
}
/**
* This constructor creates a new <code>PipedInputStream</code> and connects
* it to the passed in <code>PipedOutputStream</code>. The stream is then
* ready for reading.
*
* @param source The <code>PipedOutputStream</code> to connect this
* stream to
*
* @exception IOException If <code>source</code> is already connected.
*/
public PipedInputStream(PipedOutputStream source) throws IOException
{
connect(source);
}
/**
* This method connects this stream to the passed in
* <code>PipedOutputStream</code>.
* This stream is then ready for reading. If this stream is already
* connected or has been previously closed, then an exception is thrown
*
* @param src The <code>PipedOutputStream</code> to connect this stream to
*
* @exception IOException If this PipedInputStream or <code>source</code>
* has been connected already.
*/
public void connect(PipedOutputStream source) throws IOException
{
// The JDK (1.3) does not appear to check for a previously closed
// connection here.
if (this.source != null || source.sink != null)
throw new IOException ("Already connected");
source.sink = this;
this.source = source;
}
/**
* This method receives a byte of input from the source PipedOutputStream.
* If the internal circular buffer is full, this method blocks.
*
* @param val The byte to write to this stream
*
* @exception IOException if error occurs
* @specnote Weird. This method must be some sort of accident.
*/
protected synchronized void receive(int val) throws IOException
{
read_buf[0] = (byte) (val & 0xff);
receive (read_buf, 0, 1);
}
/**
* This method is used by the connected <code>PipedOutputStream</code> to
* write bytes into the buffer.
*
* @param buf The array containing bytes to write to this stream
* @param offset The offset into the array to start writing from
* @param len The number of bytes to write.
*
* @exception IOException If an error occurs
* @specnote This code should be in PipedOutputStream.write, but we
* put it here in order to support that bizarre recieve(int)
* method.
*/
synchronized void receive(byte[] buf, int offset, int len)
throws IOException
{
if (closed)
throw new IOException ("Pipe closed");
int bufpos = offset;
int copylen;
while (len > 0)
{
try
{
while (in == out)
{
// The pipe is full. Wake up any readers and wait for them.
notifyAll();
wait();
// The pipe could have been closed while we were waiting.
if (closed)
throw new IOException ("Pipe closed");
}
}
catch (InterruptedException ix)
{
throw new InterruptedIOException ();
}
if (in < 0) // The pipe is empty.
in = 0;
// Figure out how many bytes from buf can be copied without
// overrunning out or going past the length of the buffer.
if (in < out)
copylen = Math.min (len, out - in);
else
copylen = Math.min (len, buffer.length - in);
// Copy bytes until the pipe is filled, wrapping if necessary.
System.arraycopy(buf, bufpos, buffer, in, copylen);
len -= copylen;
bufpos += copylen;
in += copylen;
if (in == buffer.length)
in = 0;
}
// Notify readers that new data is in the pipe.
notifyAll();
}
/**
* This method reads one byte from the stream.
* -1 is returned to indicated that no bytes can be read
* because the end of the stream was reached. If the stream is already
* closed, a -1 will again be returned to indicate the end of the stream.
*
* <p>This method will block if no byte is available to be read.</p>
*
* @return the value of the read byte value, or -1 of the end of the stream
* was reached
*
* @throws IOException if an error occured
*/
public int read() throws IOException
{
// Method operates by calling the multibyte overloaded read method
// Note that read_buf is an internal instance variable. I allocate it
// there to avoid constant reallocation overhead for applications that
// call this method in a loop at the cost of some unneeded overhead
// if this method is never called.
int r = read(read_buf, 0, 1);
return r != -1 ? (read_buf[0] & 0xff) : -1;
}
/**
* This method reads bytes from the stream into a caller supplied buffer.
* It starts storing bytes at position <code>offset</code> into the
* buffer and
* reads a maximum of <code>len</code> bytes. Note that this method
* can actually
* read fewer than <code>len</code> bytes. The actual number of bytes
* read is
* returned. A -1 is returned to indicated that no bytes can be read
* because the end of the stream was reached - ie close() was called on the
* connected PipedOutputStream.
* <p>
* This method will block if no bytes are available to be read.
*
* @param buf The buffer into which bytes will be stored
* @param offset The index into the buffer at which to start writing.
* @param len The maximum number of bytes to read.
*
* @exception IOException If <code>close()</code> was called on this Piped
* InputStream.
*/
public synchronized int read(byte[] buf, int offset, int len)
throws IOException
{
if (source == null)
throw new IOException ("Not connected");
if (closed)
throw new IOException ("Pipe closed");
// If the buffer is empty, wait until there is something in the pipe
// to read.
try
{
while (in < 0)
{
if (source.closed)
return -1;
wait();
}
}
catch (InterruptedException ix)
{
throw new InterruptedIOException();
}
int total = 0;
int copylen;
while (true)
{
// Figure out how many bytes from the pipe can be copied without
// overrunning in or going past the length of buf.
if (out < in)
copylen = Math.min (len, in - out);
else
copylen = Math.min (len, buffer.length - out);
System.arraycopy (buffer, out, buf, offset, copylen);
offset += copylen;
len -= copylen;
out += copylen;
total += copylen;
if (out == buffer.length)
out = 0;
if (out == in)
{
// Pipe is now empty.
in = -1;
out = 0;
}
// If output buffer is filled or the pipe is empty, we're done.
if (len == 0 || in == -1)
{
// Notify any waiting outputstream that there is now space
// to write.
notifyAll();
return total;
}
}
}
/**
* This method returns the number of bytes that can be read from this stream
* before blocking could occur. This is the number of bytes that are
* currently unread in the internal circular buffer. Note that once this
* many additional bytes are read, the stream may block on a subsequent
* read, but it not guaranteed to block.
*
* @return The number of bytes that can be read before blocking might occur
*
* @exception IOException If an error occurs
*/
public synchronized int available() throws IOException
{
// The JDK 1.3 implementation does not appear to check for the closed or
// unconnected stream conditions here.
if (in < 0)
return 0;
else if (out < in)
return in - out;
else
return (buffer.length - out) + in;
}
/**
* This methods closes the stream so that no more data can be read
* from it.
*
* @exception IOException If an error occurs
*/
public synchronized void close() throws IOException
{
closed = true;
// Wake any thread which may be in receive() waiting to write data.
notifyAll();
}
}
@@ -0,0 +1,181 @@
/* PipedOutputStream.java -- Write portion of piped streams.
Copyright (C) 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
// NOTE: This implementation is very similar to that of PipedWriter. If you
// fix a bug in here, chances are you should make a similar change to the
// PipedWriter code.
/**
* This class writes its bytes to a <code>PipedInputStream</code> to
* which it is connected.
* <p>
* It is highly recommended that a <code>PipedOutputStream</code> and its
* connected <code>PipedInputStream</code> be in different threads. If
* they are in the same thread, read and write operations could deadlock
* the thread.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class PipedOutputStream extends OutputStream
{
/** Target PipedInputStream to which this is connected. Null only if this
* OutputStream hasn't been connected yet. */
PipedInputStream sink;
/** Set to true if close() has been called on this OutputStream. */
boolean closed;
/**
* Create an unconnected PipedOutputStream. It must be connected
* to a <code>PipedInputStream</code> using the <code>connect</code>
* method prior to writing any data or an exception will be thrown.
*/
public PipedOutputStream()
{
}
/**
* Create a new <code>PipedOutputStream</code> instance
* to write to the specified <code>PipedInputStream</code>. This stream
* is then ready for writing.
*
* @param sink The <code>PipedInputStream</code> to connect this stream to.
*
* @exception IOException If <code>sink</code> has already been connected
* to a different PipedOutputStream.
*/
public PipedOutputStream(PipedInputStream sink) throws IOException
{
sink.connect(this);
}
/**
* Connects this object to the specified <code>PipedInputStream</code>
* object. This stream will then be ready for writing.
*
* @param sink The <code>PipedInputStream</code> to connect this stream to
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void connect(PipedInputStream sink) throws IOException
{
if (this.sink != null || sink.source != null)
throw new IOException ("Already connected");
sink.connect(this);
}
/**
* Write a single byte of date to the stream. Note that this method will
* block if the <code>PipedInputStream</code> to which this object is
* connected has a full buffer.
*
* @param b The byte of data to be written, passed as an <code>int</code>.
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void write(int b) throws IOException
{
if (sink == null)
throw new IOException ("Not connected");
if (closed)
throw new IOException ("Pipe closed");
sink.receive (b);
}
/**
* This method writes <code>len</code> bytes of data from the byte array
* <code>buf</code> starting at index <code>offset</code> in the array
* to the stream. Note that this method will block if the
* <code>PipedInputStream</code> to which this object is connected has
* a buffer that cannot hold all of the bytes to be written.
*
* @param buffer The array containing bytes to write to the stream.
* @param offset The index into the array to start writing bytes from.
* @param len The number of bytes to write.
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void write(byte[] buffer, int offset, int len) throws IOException
{
if (sink == null)
throw new IOException ("Not connected");
if (closed)
throw new IOException ("Pipe closed");
sink.receive(buffer, offset, len);
}
/**
* This method does nothing.
*
* @exception IOException If the stream is closed.
* @specnote You'd think that this method would block until the sink
* had read all available data. Thats not the case - this method
* appears to be a no-op?
*/
public void flush() throws IOException
{
}
/**
* This method closes this stream so that no more data can be written
* to it. Any further attempts to write to this stream may throw an
* exception
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
// A close call on an unconnected PipedOutputStream has no effect.
if (sink != null)
{
closed = true;
// Notify any waiting readers that the stream is now closed.
synchronized (sink)
{
sink.notifyAll();
}
}
}
}
+361
View File
@@ -0,0 +1,361 @@
/* PipedReader.java -- Read portion of piped character streams.
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
// NOTE: This implementation is very similar to that of PipedInputStream.
// If you fix a bug in here, chances are you should make a similar change to
// the PipedInputStream code.
/**
* An input stream that reads characters from a piped writer to which it is
* connected.
* <p>
* Data is read and written to an internal buffer. It is highly recommended
* that the <code>PipedReader</code> and connected <code>PipedWriter</code>
* be part of different threads. If they are not, there is a possibility
* that the read and write operations could deadlock their thread.
*
* @specnote The JDK implementation appears to have some undocumented
* functionality where it keeps track of what thread is writing
* to pipe and throws an IOException if that thread susequently
* dies. This behaviour seems dubious and unreliable - we don't
* implement it.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class PipedReader extends Reader
{
/** PipedWriter to which this is connected. Null only if this
* Reader hasn't been connected yet. */
PipedWriter source;
/** Set to true if close() has been called on this Reader. */
boolean closed;
/**
* The size of the internal buffer used for input/output.
*/
static final int PIPE_SIZE = 2048;
/**
* This is the internal circular buffer used for storing chars written
* to the pipe and from which chars are read by this stream
*/
char[] buffer = new char[PIPE_SIZE];
/**
* The index into buffer where the next char from the connected
* <code>PipedWriter</code> will be written. If this variable is
* equal to <code>out</code>, then the buffer is full. If set to < 0,
* the buffer is empty.
*/
int in = -1;
/**
* This index into the buffer where chars will be read from.
*/
int out = 0;
/** Buffer used to implement single-argument read/receive */
char[] read_buf = new char[1];
/**
* Creates a new <code>PipedReader</code> that is not connected to a
* <code>PipedWriter</code>. It must be connected before chars can
* be read from this stream.
*/
public PipedReader()
{
}
/**
* This constructor creates a new <code>PipedReader</code> and connects
* it to the passed in <code>PipedWriter</code>. The stream is then
* ready for reading.
*
* @param source The <code>PipedWriter</code> to connect this stream to
*
* @exception IOException If <code>source</code> is already connected.
*/
public PipedReader(PipedWriter source) throws IOException
{
connect(source);
}
/**
* This method connects this stream to the passed in
* <code>PipedWriter</code>.
* This stream is then ready for reading. If this stream is already
* connected or has been previously closed, then an exception is thrown
*
* @param source The <code>PipedWriter</code> to connect this stream to
*
* @exception IOException If this PipedReader or <code>source</code>
* has been connected already.
*/
public void connect(PipedWriter source) throws IOException
{
// The JDK (1.3) does not appear to check for a previously closed
// connection here.
if (this.source != null || source.sink != null)
throw new IOException ("Already connected");
source.sink = this;
this.source = source;
}
/**
* This method is used by the connected <code>PipedWriter</code> to
* write chars into the buffer.
*
* @param buf The array containing chars to write to this stream
* @param offset The offset into the array to start writing from
* @param len The number of chars to write.
*
* @exception IOException If an error occurs
* @specnote This code should be in PipedWriter.write, but we
* put it here in order to support that bizarre recieve(int)
* method.
*/
void receive(char[] buf, int offset, int len)
throws IOException
{
synchronized (lock)
{
if (closed)
throw new IOException ("Pipe closed");
int bufpos = offset;
int copylen;
while (len > 0)
{
try
{
while (in == out)
{
// The pipe is full. Wake up any readers and wait for them.
lock.notifyAll();
lock.wait();
// The pipe could have been closed while we were waiting.
if (closed)
throw new IOException ("Pipe closed");
}
}
catch (InterruptedException ix)
{
throw new InterruptedIOException ();
}
if (in < 0) // The pipe is empty.
in = 0;
// Figure out how many chars from buf can be copied without
// overrunning out or going past the length of the buffer.
if (in < out)
copylen = Math.min (len, out - in);
else
copylen = Math.min (len, buffer.length - in);
// Copy chars until the pipe is filled, wrapping if necessary.
System.arraycopy(buf, bufpos, buffer, in, copylen);
len -= copylen;
bufpos += copylen;
in += copylen;
if (in == buffer.length)
in = 0;
}
// Notify readers that new data is in the pipe.
lock.notifyAll();
}
}
/**
* This method reads chars from the stream into a caller supplied buffer.
* It starts storing chars at position <code>offset</code> into the
* buffer and
* reads a maximum of <code>len</code> chars. Note that this method
* can actually
* read fewer than <code>len</code> chars. The actual number of chars
* read is
* returned. A -1 is returned to indicated that no chars can be read
* because the end of the stream was reached. If the stream is already
* closed, a -1 will again be returned to indicate the end of the stream.
* <p>
* This method will block if no char is available to be read.
*/
public int read() throws IOException
{
// Method operates by calling the multichar overloaded read method
// Note that read_buf is an internal instance variable. I allocate it
// there to avoid constant reallocation overhead for applications that
// call this method in a loop at the cost of some unneeded overhead
// if this method is never called.
int r = read(read_buf, 0, 1);
return r != -1 ? read_buf[0] : -1;
}
/**
* This method reads characters from the stream into a caller supplied
* buffer. It starts storing chars at position <code>offset</code> into
* the buffer and reads a maximum of <code>len</code> chars. Note that
* this method can actually read fewer than <code>len</code> chars.
* The actual number of chars read is
* returned. A -1 is returned to indicated that no chars can be read
* because the end of the stream was reached - ie close() was called on the
* connected PipedWriter.
* <p>
* This method will block if no chars are available to be read.
*
* @param buf The buffer into which chars will be stored
* @param offset The index into the buffer at which to start writing.
* @param len The maximum number of chars to read.
*
* @exception IOException If <code>close()</code> was called on this Piped
* Reader.
*/
public int read(char[] buf, int offset, int len)
throws IOException
{
synchronized (lock)
{
if (source == null)
throw new IOException ("Not connected");
if (closed)
throw new IOException ("Pipe closed");
// If the buffer is empty, wait until there is something in the pipe
// to read.
try
{
while (in < 0)
{
if (source.closed)
return -1;
lock.wait();
}
}
catch (InterruptedException ix)
{
throw new InterruptedIOException();
}
int total = 0;
int copylen;
while (true)
{
// Figure out how many chars from the pipe can be copied without
// overrunning in or going past the length of buf.
if (out < in)
copylen = Math.min (len, in - out);
else
copylen = Math.min (len, buffer.length - out);
System.arraycopy (buffer, out, buf, offset, copylen);
offset += copylen;
len -= copylen;
out += copylen;
total += copylen;
if (out == buffer.length)
out = 0;
if (out == in)
{
// Pipe is now empty.
in = -1;
out = 0;
}
// If output buffer is filled or the pipe is empty, we're done.
if (len == 0 || in == -1)
{
// Notify any waiting Writer that there is now space
// to write.
lock.notifyAll();
return total;
}
}
}
}
public boolean ready() throws IOException
{
// The JDK 1.3 implementation does not appear to check for the closed or
// unconnected stream conditions here. However, checking for a
// closed stream is explicitly required by the JDK 1.2 and 1.3
// documentation (for Reader.close()), so we do it.
synchronized (lock)
{
if (closed)
throw new IOException("Pipe closed");
if (in < 0)
return false;
int count;
if (out < in)
count = in - out;
else
count = (buffer.length - out) - in;
return (count > 0);
}
}
/**
* This methods closes the stream so that no more data can be read
* from it.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
synchronized (lock)
{
closed = true;
// Wake any thread which may be in receive() waiting to write data.
lock.notifyAll();
}
}
}
+182
View File
@@ -0,0 +1,182 @@
/* PipedWriter.java -- Write portion of piped character streams.
Copyright (C) 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
// NOTE: This implementation is very similar to that of PipedOutputStream.
// If you fix a bug in here, chances are you should make a similar change to
// the PipedOutputStream code.
/**
* This class writes its chars to a <code>PipedReader</code> to
* which it is connected.
* <p>
* It is highly recommended that a <code>PipedWriter</code> and its
* connected <code>PipedReader</code> be in different threads. If
* they are in the same thread, read and write operations could deadlock
* the thread.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class PipedWriter extends Writer
{
/** Target PipedReader to which this is connected. Null only if this
* Writer hasn't been connected yet. */
PipedReader sink;
/** Set to true if close() has been called on this Writer. */
boolean closed;
/** Buffer used to implement single-argument write */
char[] read_buf = new char[1];
/**
* Create an unconnected PipedWriter. It must be connected
* to a <code>PipedReader</code> using the <code>connect</code>
* method prior to writing any data or an exception will be thrown.
*/
public PipedWriter()
{
}
/**
* Create a new <code>PipedWriter</code> instance
* to write to the specified <code>PipedReader</code>. This stream
* is then ready for writing.
*
* @param sink The <code>PipedReader</code> to connect this stream to.
*
* @exception IOException If <code>sink</code> has already been connected
* to a different PipedWriter.
*/
public PipedWriter(PipedReader sink) throws IOException
{
sink.connect(this);
}
/**
* Connects this object to the specified <code>PipedReader</code>
* object. This stream will then be ready for writing.
*
* @param sink The <code>PipedReader</code> to connect this stream to
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void connect(PipedReader sink) throws IOException
{
if (this.sink != null || sink.source != null)
throw new IOException ("Already connected");
sink.connect(this);
}
/**
* Write a single char of date to the stream. Note that this method will
* block if the <code>PipedReader</code> to which this object is
* connected has a full buffer.
*
* @param b The char of data to be written, passed as an <code>int</code>.
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void write(int b) throws IOException
{
read_buf[0] = (char) (b & 0xffff);
sink.receive (read_buf, 0, 1);
}
/**
* This method writes <code>len</code> chars of data from the char array
* <code>buf</code> starting at index <code>offset</code> in the array
* to the stream. Note that this method will block if the
* <code>PipedReader</code> to which this object is connected has
* a buffer that cannot hold all of the chars to be written.
*
* @param buffer The array containing chars to write to the stream.
* @param offset The index into the array to start writing chars from.
* @param len The number of chars to write.
*
* @exception IOException If the stream has not been connected or has
* been closed.
*/
public void write(char[] buffer, int offset, int len) throws IOException
{
if (sink == null)
throw new IOException ("Not connected");
if (closed)
throw new IOException ("Pipe closed");
sink.receive(buffer, offset, len);
}
/**
* This method does nothing.
*
* @exception IOException If the stream is closed.
* @specnote You'd think that this method would block until the sink
* had read all available data. Thats not the case - this method
* appears to be a no-op?
*/
public void flush() throws IOException
{
if (closed)
throw new IOException ("Pipe closed");
}
/**
* This method closes this stream so that no more data can be written
* to it. Any further attempts to write to this stream may throw an
* exception
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
// A close call on an unconnected PipedWriter has no effect.
if (sink != null)
{
closed = true;
// Notify any waiting readers that the stream is now closed.
synchronized (sink)
{
sink.notifyAll();
}
}
}
}
+553
View File
@@ -0,0 +1,553 @@
/* PrintStream.java -- OutputStream for printing output
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Believed complete and correct to 1.3
*/
/**
* This class prints Java primitive values and object to a stream as
* text. None of the methods in this class throw an exception. However,
* errors can be detected by calling the <code>checkError()</code> method.
* Additionally, this stream can be designated as "autoflush" when
* created so that any writes are automatically flushed to the underlying
* output sink when the current line is terminated.
* <p>
* This class converts char's into byte's using the system default encoding.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class PrintStream extends FilterOutputStream
{
/* Notice the implementation is quite similar to OutputStreamWriter.
* This leads to some minor duplication, because neither inherits
* from the other, and we want to maximize performance. */
// Line separator string.
private static final char[] line_separator
= System.getProperty("line.separator").toCharArray();
/**
* Encoding name
*/
private String encoding;
/**
* This boolean indicates whether or not an error has ever occurred
* on this stream.
*/
private boolean error_occurred = false;
/**
* This is <code>true</code> if auto-flush is enabled,
* <code>false</code> otherwise
*/
private boolean auto_flush;
/**
* This method intializes a new <code>PrintStream</code> object to write
* to the specified output sink.
*
* @param out The <code>OutputStream</code> to write to.
*/
public PrintStream (OutputStream out)
{
this (out, false);
}
/**
* This method intializes a new <code>PrintStream</code> object to write
* to the specified output sink. This constructor also allows "auto-flush"
* functionality to be specified where the stream will be flushed after
* every <code>print</code> or <code>println</code> call, when the
* <code>write</code> methods with array arguments are called, or when a
* single new-line character is written.
* <p>
*
* @param out The <code>OutputStream</code> to write to.
* @param auto_flush <code>true</code> to flush the stream after every
* line, <code>false</code> otherwise
*/
public PrintStream (OutputStream out, boolean auto_flush)
{
super (out);
try {
this.encoding = System.getProperty("file.encoding");
} catch (SecurityException e){
this.encoding = "ISO8859_1";
} catch (IllegalArgumentException e){
this.encoding = "ISO8859_1";
} catch (NullPointerException e){
this.encoding = "ISO8859_1";
}
this.auto_flush = auto_flush;
}
/**
* This method intializes a new <code>PrintStream</code> object to write
* to the specified output sink. This constructor also allows "auto-flush"
* functionality to be specified where the stream will be flushed after
* every <code>print</code> or <code>println</code> call, when the
* <code>write</code> methods with array arguments are called, or when a
* single new-line character is written.
* <p>
*
* @param out The <code>OutputStream</code> to write to.
* @param auto_flush <code>true</code> to flush the stream after every
* line, <code>false</code> otherwise
* @param encoding The name of the character encoding to use for this
* object.
*/
public PrintStream (OutputStream out, boolean auto_flush, String encoding)
throws UnsupportedEncodingException
{
super (out);
new String(new byte[]{0}, encoding); // check if encoding is supported
this.encoding = encoding;
this.auto_flush = auto_flush;
}
/**
* This method checks to see if an error has occurred on this stream. Note
* that once an error has occurred, this method will continue to report
* <code>true</code> forever for this stream. Before checking for an
* error condition, this method flushes the stream.
*
* @return <code>true</code> if an error has occurred,
* <code>false</code> otherwise
*/
public boolean checkError ()
{
flush ();
return error_occurred;
}
/**
* This method can be called by subclasses to indicate that an error
* has occurred and should be reported by <code>checkError</code>.
*/
protected void setError ()
{
error_occurred = true;
}
/**
* This method closes this stream and all underlying streams.
*/
public void close ()
{
try
{
flush();
out.close();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread().interrupt();
}
catch (IOException e)
{
setError ();
}
}
/**
* This method flushes any buffered bytes to the underlying stream and
* then flushes that stream as well.
*/
public void flush ()
{
try
{
out.flush();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread().interrupt();
}
catch (IOException e)
{
setError ();
}
}
private synchronized void print (String str, boolean println)
{
try
{
writeChars(str, 0, str.length());
if (println)
writeChars(line_separator, 0, line_separator.length);
if (auto_flush)
flush();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread().interrupt();
}
catch (IOException e)
{
setError ();
}
}
private synchronized void print (char[] chars, int pos, int len,
boolean println)
{
try
{
writeChars(chars, pos, len);
if (println)
writeChars(line_separator, 0, line_separator.length);
if (auto_flush)
flush();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread().interrupt();
}
catch (IOException e)
{
setError ();
}
}
private void writeChars(char[] buf, int offset, int count)
throws IOException
{
byte[] bytes = (new String(buf, offset, count)).getBytes(encoding);
out.write(bytes, 0, bytes.length);
}
private void writeChars(String str, int offset, int count)
throws IOException
{
byte[] bytes = str.substring(offset, offset+count).getBytes(encoding);
out.write(bytes, 0, bytes.length);
}
/**
* This methods prints a boolean value to the stream. <code>true</code>
* values are printed as "true" and <code>false</code> values are printed
* as "false".
*
* @param bool The <code>boolean</code> value to print
*/
public void print (boolean bool)
{
print(String.valueOf(bool), false);
}
/**
* This method prints an integer to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param inum The <code>int</code> value to be printed
*/
public void print (int inum)
{
print(String.valueOf(inum), false);
}
/**
* This method prints a long to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param lnum The <code>long</code> value to be printed
*/
public void print (long lnum)
{
print(String.valueOf(lnum), false);
}
/**
* This method prints a float to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param fnum The <code>float</code> value to be printed
*/
public void print (float fnum)
{
print(String.valueOf(fnum), false);
}
/**
* This method prints a double to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param dnum The <code>double</code> value to be printed
*/
public void print (double dnum)
{
print(String.valueOf(dnum), false);
}
/**
* This method prints an <code>Object</code> to the stream. The actual
* value printed is determined by calling the <code>String.valueOf()</code>
* method.
*
* @param obj The <code>Object</code> to print.
*/
public void print (Object obj)
{
print(obj == null ? "null" : obj.toString(), false);
}
/**
* This method prints a <code>String</code> to the stream. The actual
* value printed depends on the system default encoding.
*
* @param str The <code>String</code> to print.
*/
public void print (String str)
{
print(str == null ? "null" : str, false);
}
/**
* This method prints a char to the stream. The actual value printed is
* determined by the character encoding in use.
*
* @param ch The <code>char</code> value to be printed
*/
public synchronized void print (char ch)
{
print(new char[]{ch}, 0, 1, false);
}
/**
* This method prints an array of characters to the stream. The actual
* value printed depends on the system default encoding.
*
* @param charArray The array of characters to print.
*/
public void print (char[] charArray)
{
print(charArray, 0, charArray.length, false);
}
/**
* This method prints a line separator sequence to the stream. The value
* printed is determined by the system property <xmp>line.separator</xmp>
* and is not necessarily the Unix '\n' newline character.
*/
public void println ()
{
print(line_separator, 0, line_separator.length, false);
}
/**
* This methods prints a boolean value to the stream. <code>true</code>
* values are printed as "true" and <code>false</code> values are printed
* as "false".
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param bool The <code>boolean</code> value to print
*/
public void println (boolean bool)
{
print(String.valueOf(bool), true);
}
/**
* This method prints an integer to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param inum The <code>int</code> value to be printed
*/
public void println (int inum)
{
print(String.valueOf(inum), true);
}
/**
* This method prints a long to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param lnum The <code>long</code> value to be printed
*/
public void println (long lnum)
{
print(String.valueOf(lnum), true);
}
/**
* This method prints a float to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param fnum The <code>float</code> value to be printed
*/
public void println (float fnum)
{
print(String.valueOf(fnum), true);
}
/**
* This method prints a double to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param dnum The <code>double</code> value to be printed
*/
public void println (double dnum)
{
print(String.valueOf(dnum), true);
}
/**
* This method prints an <code>Object</code> to the stream. The actual
* value printed is determined by calling the <code>String.valueOf()</code>
* method.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param obj The <code>Object</code> to print.
*/
public void println (Object obj)
{
print(obj == null ? "null" : obj.toString(), true);
}
/**
* This method prints a <code>String</code> to the stream. The actual
* value printed depends on the system default encoding.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param str The <code>String</code> to print.
*/
public void println (String str)
{
print (str == null ? "null" : str, true);
}
/**
* This method prints a char to the stream. The actual value printed is
* determined by the character encoding in use.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param ch The <code>char</code> value to be printed
*/
public synchronized void println (char ch)
{
print(new char[]{ch}, 0, 1, true);
}
/**
* This method prints an array of characters to the stream. The actual
* value printed depends on the system default encoding.
* <p>
* This method prints a line termination sequence after printing the value.
*
* @param charArray The array of characters to print.
*/
public void println (char[] charArray)
{
print(charArray, 0, charArray.length, true);
}
/**
* This method writes a byte of data to the stream. If auto-flush is
* enabled, printing a newline character will cause the stream to be
* flushed after the character is written.
*
* @param oneByte The byte to be written
*/
public void write (int oneByte)
{
try
{
out.write (oneByte & 0xff);
if (auto_flush && (oneByte == '\n'))
flush ();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread ().interrupt ();
}
catch (IOException e)
{
setError ();
}
}
/**
* This method writes <code>len</code> bytes from the specified array
* starting at index <code>offset</code> into the array.
*
* @param buffer The array of bytes to write
* @param offset The index into the array to start writing from
* @param len The number of bytes to write
*/
public void write (byte[] buffer, int offset, int len)
{
try
{
out.write (buffer, offset, len);
if (auto_flush)
flush ();
}
catch (InterruptedIOException iioe)
{
Thread.currentThread ().interrupt ();
}
catch (IOException e)
{
setError ();
}
}
} // class PrintStream
+571
View File
@@ -0,0 +1,571 @@
/* PrintWriter.java -- prints primitive values and objects to a stream as text
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
* However, should use native methods for conversion.
*/
/**
* This class prints Java primitive values and objects to a stream as
* text. None of the methods in this class throw an exception. However,
* errors can be detected by calling the <code>checkError()</code> method.
* Additionally, this stream can be designated as "autoflush" when
* created so that any writes are automatically flushed to the underlying
* output sink whenever one of the <code>println</code> methods is
* called. (Note that this differs from the <code>PrintStream</code>
* class which also auto-flushes when it encounters a newline character
* in the chars written).
*
* @author Per Bothner (bothner@cygnus.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
* @date April 17, 1998.
*/
public class PrintWriter extends Writer
{
/**
* <code>true</code> if auto-flush is enabled, <code>false</code> otherwise
*/
private boolean autoflush;
/**
* This boolean indicates whether or not an error has ever occurred
* on this stream.
*/
private boolean error;
/**
* This is the underlying <code>Writer</code> we are sending output
* to
*/
protected Writer out;
/**
* This method intializes a new <code>PrintWriter</code> object to write
* to the specified output sink. The form of the constructor does not
* enable auto-flush functionality.
*
* @param wr The <code>Writer</code> to write to.
*/
public PrintWriter(Writer wr)
{
super(wr.lock);
this.out = wr;
}
/**
* This method intializes a new <code>PrintWriter</code> object to write
* to the specified output sink. This constructor also allows "auto-flush"
* functionality to be specified where the stream will be flushed after
* every line is terminated or newline character is written.
*
* @param wr The <code>Writer</code> to write to.
* @param autoflush <code>true</code> to flush the stream after every
* line, <code>false</code> otherwise
*/
public PrintWriter(Writer wr, boolean autoflush)
{
super(wr.lock);
this.out = wr;
this.autoflush = autoflush;
}
/**
* This method initializes a new <code>PrintWriter</code> object to write
* to the specified <code>OutputStream</code>. Characters will be converted
* to chars using the system default encoding. Auto-flush functionality
* will not be enabled.
*
* @param out The <code>OutputStream</code> to write to
*/
public PrintWriter(OutputStream out)
{
super();
this.out = new OutputStreamWriter(out);
this.lock = this.out;
}
/**
* This method initializes a new <code>PrintWriter</code> object to write
* to the specified <code>OutputStream</code>. Characters will be converted
* to chars using the system default encoding. This form of the
* constructor allows auto-flush functionality to be enabled if desired
*
* @param out The <code>OutputStream</code> to write to
* @param autoflush <code>true</code> to flush the stream after every
* <code>println</code> call, <code>false</code> otherwise.
*/
public PrintWriter(OutputStream out, boolean autoflush)
{
this(out);
this.autoflush = autoflush;
}
/**
* This method can be called by subclasses to indicate that an error
* has occurred and should be reported by <code>checkError</code>.
*/
protected void setError()
{
error = true;
}
/**
* This method checks to see if an error has occurred on this stream. Note
* that once an error has occurred, this method will continue to report
* <code>true</code> forever for this stream. Before checking for an
* error condition, this method flushes the stream.
*
* @return <code>true</code> if an error has occurred,
* <code>false</code> otherwise
*/
public boolean checkError()
{
flush();
return error;
}
/**
* This method flushes any buffered chars to the underlying stream and
* then flushes that stream as well.
*/
public void flush()
{
try
{
out.flush();
}
catch (IOException ex)
{
error = true;
}
}
/**
* This method closes this stream and all underlying streams.
*/
public void close()
{
try
{
out.close();
}
catch (IOException ex)
{
error = true;
}
}
/**
* This method prints a <code>String</code> to the stream. The actual
* value printed depends on the system default encoding.
*
* @param str The <code>String</code> to print.
*/
public void print(String str)
{
write(str == null ? "null" : str);
}
/**
* This method prints a char to the stream. The actual value printed is
* determined by the character encoding in use.
*
* @param ch The <code>char</code> value to be printed
*/
public void print(char ch)
{
write((int) ch);
}
/**
* This method prints an array of characters to the stream. The actual
* value printed depends on the system default encoding.
*
* @param charArray The array of characters to print.
*/
public void print(char[] charArray)
{
write(charArray, 0, charArray.length);
}
/**
* This methods prints a boolean value to the stream. <code>true</code>
* values are printed as "true" and <code>false</code> values are printed
* as "false".
*
* @param bool The <code>boolean</code> value to print
*/
public void print(boolean bool)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write (bool ? "true" : "false");
}
/**
* This method prints an integer to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param inum The <code>int</code> value to be printed
*/
public void print(int inum)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write(Integer.toString(inum));
}
/**
* This method prints a long to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param lnum The <code>long</code> value to be printed
*/
public void print(long lnum)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write(Long.toString(lnum));
}
/**
* This method prints a float to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param fnum The <code>float</code> value to be printed
*/
public void print(float fnum)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write(Float.toString(fnum));
}
/**
* This method prints a double to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* @param dnum The <code>double</code> value to be printed
*/
public void print(double dnum)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write(Double.toString(dnum));
}
/**
* This method prints an <code>Object</code> to the stream. The actual
* value printed is determined by calling the <code>String.valueOf()</code>
* method.
*
* @param obj The <code>Object</code> to print.
*/
public void print(Object obj)
{
// We purposely call write() and not print() here. This preserves
// compatibility with JDK 1.2.
write(obj == null ? "null" : obj.toString());
}
/**
* This is the system dependent line separator
*/
private static final char[] line_separator
= System.getProperty("line.separator").toCharArray();
/**
* This method prints a line separator sequence to the stream. The value
* printed is determined by the system property <xmp>line.separator</xmp>
* and is not necessarily the Unix '\n' newline character.
*/
public void println()
{
synchronized (lock)
{
try
{
write(line_separator, 0, line_separator.length);
if (autoflush)
out.flush();
}
catch (IOException ex)
{
error = true;
}
}
}
/**
* This methods prints a boolean value to the stream. <code>true</code>
* values are printed as "true" and <code>false</code> values are printed
* as "false".
*
* This method prints a line termination sequence after printing the value.
*
* @param bool The <code>boolean</code> value to print
*/
public void println(boolean bool)
{
synchronized (lock)
{
print(bool);
println();
}
}
/**
* This method prints an integer to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* This method prints a line termination sequence after printing the value.
*
* @param inum The <code>int</code> value to be printed
*/
public void println(int inum)
{
synchronized (lock)
{
print(inum);
println();
}
}
/**
* This method prints a long to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* This method prints a line termination sequence after printing the value.
*
* @param lnum The <code>long</code> value to be printed
*/
public void println(long lnum)
{
synchronized (lock)
{
print(lnum);
println();
}
}
/**
* This method prints a float to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* This method prints a line termination sequence after printing the value.
*
* @param fnum The <code>float</code> value to be printed
*/
public void println(float fnum)
{
synchronized (lock)
{
print(fnum);
println();
}
}
/**
* This method prints a double to the stream. The value printed is
* determined using the <code>String.valueOf()</code> method.
*
* This method prints a line termination sequence after printing the value.
*
* @param dnum The <code>double</code> value to be printed
*/
public void println(double dnum)
{
synchronized (lock)
{
print(dnum);
println();
}
}
/**
* This method prints an <code>Object</code> to the stream. The actual
* value printed is determined by calling the <code>String.valueOf()</code>
* method.
*
* This method prints a line termination sequence after printing the value.
*
* @param obj The <code>Object</code> to print.
*/
public void println(Object obj)
{
synchronized (lock)
{
print(obj);
println();
}
}
/**
* This method prints a <code>String</code> to the stream. The actual
* value printed depends on the system default encoding.
*
* This method prints a line termination sequence after printing the value.
*
* @param str The <code>String</code> to print.
*/
public void println(String str)
{
synchronized (lock)
{
print(str);
println();
}
}
/**
* This method prints a char to the stream. The actual value printed is
* determined by the character encoding in use.
*
* This method prints a line termination sequence after printing the value.
*
* @param ch The <code>char</code> value to be printed
*/
public void println(char ch)
{
synchronized (lock)
{
print(ch);
println();
}
}
/**
* This method prints an array of characters to the stream. The actual
* value printed depends on the system default encoding.
*
* This method prints a line termination sequence after printing the value.
*
* @param charArray The array of characters to print.
*/
public void println(char[] charArray)
{
synchronized (lock)
{
print(charArray);
println();
}
}
/**
* This method writes a single char to the stream.
*
* @param ch The char to be written, passed as a int
*/
public void write(int ch)
{
try
{
out.write(ch);
}
catch (IOException ex)
{
error = true;
}
}
/**
* This method writes <code>count</code> chars from the specified array
* starting at index <code>offset</code> into the array.
*
* @param charArray The array of chars to write
* @param offset The index into the array to start writing from
* @param count The number of chars to write
*/
public void write(char[] charArray, int offset, int count)
{
try
{
out.write(charArray, offset, count);
}
catch (IOException ex)
{
error = true;
}
}
/**
* This method writes <code>count</code> chars from the specified
* <code>String</code> to the output starting at character position
* <code>offset</code> into the <code>String</code>
*
* @param str The <code>String</code> to write chars from
* @param offset The offset into the <code>String</code> to start writing from
* @param count The number of chars to write.
*/
public void write(String str, int offset, int count)
{
try
{
out.write(str, offset, count);
}
catch (IOException ex)
{
error = true;
}
}
/**
* This method write all the chars in the specified array to the output.
*
* @param charArray The array of characters to write
*/
public void write(char[] charArray)
{
write(charArray, 0, charArray.length);
}
/**
* This method writes the contents of the specified <code>String</code>
* to the underlying stream.
*
* @param str The <code>String</code> to write
*/
public void write(String str)
{
write(str, 0, str.length());
}
}
@@ -0,0 +1,328 @@
/* PushbackInputStream.java -- An input stream that can unread bytes
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This subclass of <code>FilterInputStream</code> provides the ability to
* unread data from a stream. It maintains an internal buffer of unread
* data that is supplied to the next read operation. This is conceptually
* similar to mark/reset functionality, except that in this case the
* position to reset the stream to does not need to be known in advance.
* <p>
* The default pushback buffer size one byte, but this can be overridden
* by the creator of the stream.
* <p>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class PushbackInputStream extends FilterInputStream
{
/**
* This is the default buffer size
*/
private static final int DEFAULT_BUFFER_SIZE = 1;
/**
* This is the buffer that is used to store the pushed back data
*/
protected byte[] buf;
/**
* This is the position in the buffer from which the next byte will be
* read. Bytes are stored in reverse order in the buffer, starting from
* <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
* <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
* it is empty
*/
protected int pos;
/**
* This method initializes a <code>PushbackInputStream</code> to
* read from the specified subordinate <code>InputStream</code>
* with a default pushback buffer size of 1.
*
* @param in The subordinate stream to read from
*/
public PushbackInputStream(InputStream in)
{
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a <code>PushbackInputStream</code> to
* read from the specified subordinate <code>InputStream</code> with
* the specified buffer size
*
* @param in The subordinate <code>InputStream</code> to read from
* @param size The pushback buffer size to use
*/
public PushbackInputStream(InputStream in, int size)
{
super(in);
if (size < 0)
throw new IllegalArgumentException();
buf = new byte[size];
pos = buf.length;
}
/**
* This method returns the number of bytes that can be read from this
* stream before a read can block. A return of 0 indicates that blocking
* might (or might not) occur on the very next read attempt.
* <p>
* This method will return the number of bytes available from the
* pushback buffer plus the number of bytes available from the
* underlying stream.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
return (buf.length - pos) + super.available();
}
/**
* This method closes the stream and releases any associated resources.
*
* @exception IOException If an error occurs.
*/
public synchronized void close() throws IOException
{
buf = null;
super.close();
}
/**
* This method returns <code>false</code> to indicate that it does
* not support mark/reset functionality.
*
* @return This method returns <code>false</code> to indicate that
* this class does not support mark/reset functionality
*/
public boolean markSupported()
{
return false;
}
/**
* This method always throws an IOException in this class because
* mark/reset functionality is not supported.
*
* @exception IOException Always thrown for this class
*/
public void reset() throws IOException
{
throw new IOException("Mark not supported in this class");
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached. The byte returned will be read
* from the pushback buffer, unless the buffer is empty, in which case
* the byte will be read from the underlying stream.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public synchronized int read() throws IOException
{
if (pos < buf.length)
return ((int) buf[pos++]) & 0xFF;
return super.read();
}
/**
* This method read bytes from a stream and stores them into a
* caller supplied buffer. It starts storing the data at index
* <code>offset</code> into the buffer and attempts to read
* <code>len</code> bytes. This method can return before reading the
* number of bytes requested. The actual number of bytes read is
* returned as an int. A -1 is returned to indicate the end of the
* stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method first reads bytes from the pushback buffer in order to
* satisfy the read request. If the pushback buffer cannot provide all
* of the bytes requested, the remaining bytes are read from the
* underlying stream.
*
* @param b The array into which the bytes read should be stored
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public synchronized int read(byte[] b, int off, int len) throws IOException
{
int numBytes = Math.min(buf.length - pos, len);
if (numBytes > 0)
{
System.arraycopy (buf, pos, b, off, numBytes);
pos += numBytes;
len -= numBytes;
off += numBytes;
}
if (len > 0)
{
len = super.read(b, off, len);
if (len == -1) //EOF
return numBytes > 0 ? numBytes : -1;
numBytes += len;
}
return numBytes;
}
/**
* This method pushes a single byte of data into the pushback buffer.
* The byte pushed back is the one that will be returned as the first byte
* of the next read.
* <p>
* If the pushback buffer is full, this method throws an exception.
* <p>
* The argument to this method is an <code>int</code>. Only the low
* eight bits of this value are pushed back.
*
* @param b The byte to be pushed back, passed as an int
*
* @exception IOException If the pushback buffer is full.
*/
public synchronized void unread(int b) throws IOException
{
if (pos <= 0)
throw new IOException("Insufficient space in pushback buffer");
buf[--pos] = (byte) b;
}
/**
* This method pushes all of the bytes in the passed byte array into
* the pushback bfer. These bytes are pushed in reverse order so that
* the next byte read from the stream after this operation will be
* <code>b[0]</code> followed by <code>b[1]</code>, etc.
* <p>
* If the pushback buffer cannot hold all of the requested bytes, an
* exception is thrown.
*
* @param b The byte array to be pushed back
*
* @exception IOException If the pushback buffer is full
*/
public synchronized void unread(byte[] b) throws IOException
{
unread(b, 0, b.length);
}
/**
* This method pushed back bytes from the passed in array into the
* pushback buffer. The bytes from <code>b[offset]</code> to
* <code>b[offset + len]</code> are pushed in reverse order so that
* the next byte read from the stream after this operation will be
* <code>b[offset]</code> followed by <code>b[offset + 1]</code>,
* etc.
* <p>
* If the pushback buffer cannot hold all of the requested bytes, an
* exception is thrown.
*
* @param b The byte array to be pushed back
* @param off The index into the array where the bytes to be push start
* @param len The number of bytes to be pushed.
*
* @exception IOException If the pushback buffer is full
*/
public synchronized void unread(byte[] b, int off, int len)
throws IOException
{
if (pos < len)
throw new IOException("Insufficient space in pushback buffer");
// Note the order that these bytes are being added is the opposite
// of what would be done if they were added to the buffer one at a time.
// See the Java Class Libraries book p. 1390.
System.arraycopy(b, off, buf, pos - len, len);
// Don't put this into the arraycopy above, an exception might be thrown
// and in that case we don't want to modify pos.
pos -= len;
}
/**
* This method skips the specified number of bytes in the stream. It
* returns the actual number of bytes skipped, which may be less than the
* requested amount.
* <p>
* This method first discards bytes from the buffer, then calls the
* <code>skip</code> method on the underlying <code>InputStream</code> to
* skip additional bytes if necessary.
*
* @param n The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*
* @exception IOException If an error occurs
*
* @since 1.2
*/
public synchronized long skip(long n) throws IOException
{
final long origN = n;
if (n > 0L)
{
int numread = (int) Math.min((long) (buf.length - pos), n);
pos += numread;
n -= numread;
if (n > 0)
n -= super.skip(n);
}
return origN - n;
}
}
@@ -0,0 +1,384 @@
/* PushbackReader.java -- An character stream that can unread chars
Copyright (C) 1998, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This subclass of <code>FilterReader</code> provides the ability to
* unread data from a stream. It maintains an internal buffer of unread
* data that is supplied to the next read operation. This is conceptually
* similar to mark/reset functionality, except that in this case the
* position to reset the stream to does not need to be known in advance.
* <p>
* The default pushback buffer size one char, but this can be overridden
* by the creator of the stream.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class PushbackReader extends FilterReader
{
/**
* This is the default buffer size
*/
private static final int DEFAULT_BUFFER_SIZE = 1;
/**
* This is the buffer that is used to store the pushed back data
*/
private char[] buf;
/**
* This is the position in the buffer from which the next char will be
* read. Bytes are stored in reverse order in the buffer, starting from
* <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
* <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
* it is empty
*/
private int pos;
/**
* This method initializes a <code>PushbackReader</code> to read from the
* specified subordinate <code>Reader</code> with a default pushback buffer
* size of 1.
*
* @param in The subordinate stream to read from
*/
public PushbackReader(Reader in)
{
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a <code>PushbackReader</code> to read from the
* specified subordinate <code>Reader</code> with the specified buffer
* size
*
* @param in The subordinate <code>Reader</code> to read from
* @param bufsize The pushback buffer size to use
*/
public PushbackReader(Reader in, int bufsize)
{
super(in);
if (bufsize < 0)
throw new IllegalArgumentException("buffer size must be positive");
buf = new char[bufsize];
pos = bufsize;
}
/**
* This method closes the stream and frees any associated resources.
*
* @exception IOException If an error occurs.
*/
public void close() throws IOException
{
synchronized (lock)
{
buf = null;
super.close();
}
}
/**
* This method throws an exception when called since this class does
* not support mark/reset.
*
* @param read_limit Not used.
*
* @exception IOException Always thrown to indicate mark/reset not supported.
*/
public void mark(int read_limit) throws IOException
{
throw new IOException("mark not supported in this class");
}
/**
* This method returns <code>false</code> to indicate that it does not support
* mark/reset functionality.
*
* @return This method returns <code>false</code> to indicate that this
* class does not support mark/reset functionality
*
*/
public boolean markSupported()
{
return(false);
}
/**
* This method always throws an IOException in this class because
* mark/reset functionality is not supported.
*
* @exception IOException Always thrown for this class
*/
public void reset() throws IOException
{
throw new IOException("reset not supported in this class");
}
/**
* This method determines whether or not this stream is ready to be read.
* If it returns <code>false</code> to indicate that the stream is not
* ready, any attempt to read from the stream could (but is not
* guaranteed to) block.
* <p>
* This stream is ready to read if there are either chars waiting to be
* read in the pushback buffer or if the underlying stream is ready to
* be read.
*
* @return <code>true</code> if this stream is ready to be read,
* <code>false</code> otherwise
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException ("stream closed");
if (((buf.length - pos) > 0) || super.ready())
return(true);
else
return(false);
}
}
// Don't delete this method just because the spec says it shouldn't be there!
// See the CVS log for details.
/**
* This method skips the specified number of chars in the stream. It
* returns the actual number of chars skipped, which may be less than the
* requested amount.
* <p>
* This method first discards chars from the buffer, then calls the
* <code>skip</code> method on the underlying <code>Reader</code> to
* skip additional chars if necessary.
*
* @param num_chars The requested number of chars to skip
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs
*/
public long skip(long num_chars) throws IOException
{
synchronized (lock)
{
if (num_chars <= 0)
return(0);
if ((buf.length - pos) >= num_chars)
{
pos += num_chars;
return(num_chars);
}
int chars_discarded = buf.length - pos;
pos = buf.length;
long chars_skipped = in.skip(num_chars - chars_discarded);
return(chars_discarded + chars_skipped);
}
}
/**
* This method reads an unsigned char from the input stream and returns it
* as an int in the range of 0-65535. This method also will return -1 if
* the end of the stream has been reached. The char returned will be read
* from the pushback buffer, unless the buffer is empty, in which case
* the char will be read from the underlying stream.
* <p>
* This method will block until the char can be read.
*
* @return The char read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
if (pos == buf.length)
return(super.read());
++pos;
return((buf[pos - 1] & 0xFFFF));
}
}
/**
* This method read chars from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code>
* into
* the buffer and attempts to read <code>len</code> chars. This method can
* return before reading the number of chars requested. The actual number
* of chars read is returned as an int. A -1 is returned to indicate the
* end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method first reads chars from the pushback buffer in order to
* satisfy the read request. If the pushback buffer cannot provide all
* of the chars requested, the remaining chars are read from the
* underlying stream.
*
* @param buffer The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
* @param length The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public synchronized int read(char[] buffer, int offset, int length)
throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
if (offset < 0 || length < 0 || offset + length > buffer.length)
throw new ArrayIndexOutOfBoundsException();
int numBytes = Math.min(buf.length - pos, length);
if (numBytes > 0)
{
System.arraycopy (buf, pos, buffer, offset, numBytes);
pos += numBytes;
return numBytes;
}
return super.read(buffer, offset, length);
}
}
/**
* This method pushes a single char of data into the pushback buffer.
* The char pushed back is the one that will be returned as the first char
* of the next read.
* <p>
* If the pushback buffer is full, this method throws an exception.
* <p>
* The argument to this method is an <code>int</code>. Only the low eight
* bits of this value are pushed back.
*
* @param b The char to be pushed back, passed as an int
*
* @exception IOException If the pushback buffer is full.
*/
public void unread(int b) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
if (pos == 0)
throw new IOException("Pushback buffer is full");
--pos;
buf[pos] = (char)(b & 0xFFFF);
}
}
/**
* This method pushes all of the chars in the passed char array into
* the pushback buffer. These chars are pushed in reverse order so that
* the next char read from the stream after this operation will be
* <code>buf[0]</code> followed by <code>buf[1]</code>, etc.
* <p>
* If the pushback buffer cannot hold all of the requested chars, an
* exception is thrown.
*
* @param buf The char array to be pushed back
*
* @exception IOException If the pushback buffer is full
*/
public synchronized void unread(char[] buf) throws IOException
{
unread(buf, 0, buf.length);
}
/**
* This method pushed back chars from the passed in array into the pushback
* buffer. The chars from <code>buf[offset]</code> to
* <code>buf[offset + len]</code>
* are pushed in reverse order so that the next char read from the stream
* after this operation will be <code>buf[offset]</code> followed by
* <code>buf[offset + 1]</code>, etc.
* <p>
* If the pushback buffer cannot hold all of the requested chars, an
* exception is thrown.
*
* @param buffer The char array to be pushed back
* @param offset The index into the array where the chars to be push start
* @param length The number of chars to be pushed.
*
* @exception IOException If the pushback buffer is full
*/
public synchronized void unread(char[] buffer, int offset, int length)
throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
if (pos < length)
throw new IOException("Pushback buffer is full");
// Note the order that these chars are being added is the opposite
// of what would be done if they were added to the buffer one at a time.
// See the Java Class Libraries book p. 1397.
System.arraycopy(buffer, offset, buf, pos - length, length);
// Don't put this into the arraycopy above, an exception might be thrown
// and in that case we don't want to modify pos.
pos -= length;
}
}
}
@@ -0,0 +1,991 @@
/* RandomAccessFile.java -- Class supporting random file I/O
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import gnu.java.nio.channels.FileChannelImpl;
import java.nio.channels.FileChannel;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* Status: Believe complete and correct to 1.1.
*/
/**
* This class allows reading and writing of files at random locations.
* Most Java I/O classes are either pure sequential input or output. This
* class fulfills the need to be able to read the bytes of a file in an
* arbitrary order. In addition, this class implements the
* <code>DataInput</code> and <code>DataOutput</code> interfaces to allow
* the reading and writing of Java primitives.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class RandomAccessFile implements DataOutput, DataInput
{
// The underlying file.
private FileChannelImpl ch;
private FileDescriptor fd;
// The corresponding input and output streams.
private DataOutputStream out;
private DataInputStream in;
/**
* This method initializes a new instance of <code>RandomAccessFile</code>
* to read from the specified <code>File</code> object with the specified
* access mode. The access mode is either "r" for read only access or "rw"
* for read-write access.
* <p>
* Note that a <code>SecurityManager</code> check is made prior to
* opening the file to determine whether or not this file is allowed to
* be read or written.
*
* @param file The <code>File</code> object to read and/or write.
* @param mode "r" for read only or "rw" for read-write access to the file
*
* @exception IllegalArgumentException If <code>mode</code> has an
* illegal value
* @exception SecurityException If the requested access to the file
* is not allowed
* @exception FileNotFoundException If the file is a directory, or
* any other error occurs
*/
public RandomAccessFile (File file, String mode)
throws FileNotFoundException
{
int fdmode;
if (mode.equals("r"))
fdmode = FileChannelImpl.READ;
else if (mode.equals("rw"))
fdmode = FileChannelImpl.READ | FileChannelImpl.WRITE;
else if (mode.equals("rws"))
{
fdmode = (FileChannelImpl.READ | FileChannelImpl.WRITE
| FileChannelImpl.SYNC);
}
else if (mode.equals("rwd"))
{
fdmode = (FileChannelImpl.READ | FileChannelImpl.WRITE
| FileChannelImpl.DSYNC);
}
else
throw new IllegalArgumentException ("invalid mode: " + mode);
final String fileName = file.getPath();
// The obligatory SecurityManager stuff
SecurityManager s = System.getSecurityManager();
if (s != null)
{
s.checkRead(fileName);
if ((fdmode & FileChannelImpl.WRITE) != 0)
s.checkWrite(fileName);
}
ch = FileChannelImpl.create(file, fdmode);
fd = new FileDescriptor(ch);
out = new DataOutputStream (new FileOutputStream (fd));
in = new DataInputStream (new FileInputStream (fd));
}
/**
* This method initializes a new instance of <code>RandomAccessFile</code>
* to read from the specified file name with the specified access mode.
* The access mode is either "r" for read only access, "rw" for read
* write access, "rws" for synchronized read/write access of both
* content and metadata, or "rwd" for read/write access
* where only content is required to be synchronous.
* <p>
* Note that a <code>SecurityManager</code> check is made prior to
* opening the file to determine whether or not this file is allowed to
* be read or written.
*
* @param fileName The name of the file to read and/or write
* @param mode "r", "rw", "rws", or "rwd"
*
* @exception IllegalArgumentException If <code>mode</code> has an
* illegal value
* @exception SecurityException If the requested access to the file
* is not allowed
* @exception FileNotFoundException If the file is a directory or
* any other error occurs
*/
public RandomAccessFile (String fileName, String mode)
throws FileNotFoundException
{
this (new File(fileName), mode);
}
/**
* This method closes the file and frees up all file related system
* resources. Since most operating systems put a limit on how many files
* may be opened at any given time, it is a good idea to close all files
* when no longer needed to avoid hitting this limit
*/
public void close () throws IOException
{
ch.close();
}
/**
* This method returns a <code>FileDescriptor</code> object that
* represents the native file handle for this file.
*
* @return The <code>FileDescriptor</code> object for this file
*
* @exception IOException If an error occurs
*/
public final FileDescriptor getFD () throws IOException
{
synchronized (this)
{
if (fd == null)
fd = new FileDescriptor (ch);
return fd;
}
}
/**
* This method returns the current offset in the file at which the next
* read or write will occur
*
* @return The current file position
*
* @exception IOException If an error occurs
*/
public long getFilePointer () throws IOException
{
return ch.position();
}
/**
* This method sets the length of the file to the specified length.
* If the currently length of the file is longer than the specified
* length, then the file is truncated to the specified length (the
* file position is set to the end of file in this case). If the
* current length of the file is shorter than the specified length,
* the file is extended with bytes of an undefined value (the file
* position is unchanged in this case).
* <p>
* The file must be open for write access for this operation to succeed.
*
* @param newLen The new length of the file
*
* @exception IOException If an error occurs
*/
public void setLength (long newLen) throws IOException
{
// FIXME: Extending a file should probably be done by one method call.
// FileChannel.truncate() can only shrink a file.
// To expand it we need to seek forward and write at least one byte.
if (newLen < length())
ch.truncate (newLen);
else if (newLen > length())
{
long pos = getFilePointer();
seek(newLen - 1);
write(0);
seek(pos);
}
}
/**
* This method returns the length of the file in bytes
*
* @return The length of the file
*
* @exception IOException If an error occurs
*/
public long length () throws IOException
{
return ch.size();
}
/**
* This method reads a single byte of data from the file and returns it
* as an integer.
*
* @return The byte read as an int, or -1 if the end of the file was reached.
*
* @exception IOException If an error occurs
*/
public int read () throws IOException
{
return in.read();
}
/**
* This method reads bytes from the file into the specified array. The
* bytes are stored starting at the beginning of the array and up to
* <code>buf.length</code> bytes can be read.
*
* @param buffer The buffer to read bytes from the file into
*
* @return The actual number of bytes read or -1 if end of file
*
* @exception IOException If an error occurs
*/
public int read (byte[] buffer) throws IOException
{
return in.read (buffer);
}
/**
* This methods reads up to <code>len</code> bytes from the file into the
* specified array starting at position <code>offset</code> into the array.
*
* @param buffer The array to read the bytes into
* @param offset The index into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of file
*
* @exception IOException If an error occurs
*/
public int read (byte[] buffer, int offset, int len) throws IOException
{
return in.read (buffer, offset, len);
}
/**
* This method reads a Java boolean value from an input stream. It does
* so by reading a single byte of data. If that byte is zero, then the
* value returned is <code>false</code> If the byte is non-zero, then
* the value returned is <code>true</code>
* <p>
* This method can read a <code>boolean</code> written by an object
* implementing the
* <code>writeBoolean()</code> method in the <code>DataOutput</code>
* interface.
*
* @return The <code>boolean</code> value read
*
* @exception EOFException If end of file is reached before reading the
* boolean
* @exception IOException If any other error occurs
*/
public final boolean readBoolean () throws IOException
{
return in.readBoolean ();
}
/**
* This method reads a Java byte value from an input stream. The value
* is in the range of -128 to 127.
* <p>
* This method can read a <code>byte</code> written by an object
* implementing the
* <code>writeByte()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>byte</code> value read
*
* @exception EOFException If end of file is reached before reading the byte
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final byte readByte () throws IOException
{
return in.readByte ();
}
/**
* This method reads a Java <code>char</code> value from an input stream.
* It operates by reading two bytes from the stream and converting them to
* a single 16-bit Java <code>char</code> The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code> represent
* the first
* and second byte read from the stream respectively, they will be
* transformed to a <code>char</code> in the following manner:
* <p>
* <code>(char)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
* <p>
* This method can read a <code>char</code> written by an object
* implementing the
* <code>writeChar()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>char</code> value read
*
* @exception EOFException If end of file is reached before reading the char
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final char readChar () throws IOException
{
return in.readChar();
}
/**
* This method reads a Java double value from an input stream. It operates
* by first reading a <code>logn</code> value from the stream by calling the
* <code>readLong()</code> method in this interface, then
* converts that <code>long</code>
* to a <code>double</code> using the <code>longBitsToDouble</code>
* method in the class <code>java.lang.Double</code>
* <p>
* This method can read a <code>double</code> written by an object
* implementing the
* <code>writeDouble()</code> method in the <code>DataOutput</code>
* interface.
*
* @return The <code>double</code> value read
*
* @exception EOFException If end of file is reached before reading
* the double
* @exception IOException If any other error occurs
*
* @see java.lang.Double
* @see DataOutput
*/
public final double readDouble () throws IOException
{
return in.readDouble ();
}
/**
* This method reads a Java float value from an input stream. It operates
* by first reading an <code>int</code> value from the stream by calling the
* <code>readInt()</code> method in this interface, then converts
* that <code>int</code>
* to a <code>float</code> using the <code>intBitsToFloat</code> method in
* the class <code>java.lang.Float</code>
* <p>
* This method can read a <code>float</code> written by an object
* implementing the
* <code>writeFloat()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>float</code> value read
*
* @exception EOFException If end of file is reached before reading the float
* @exception IOException If any other error occurs
*
* @see java.lang.Float
* @see DataOutput
*/
public final float readFloat () throws IOException
{
return in.readFloat();
}
/**
* This method reads raw bytes into the passed array until the array is
* full. Note that this method blocks until the data is available and
* throws an exception if there is not enough data left in the stream to
* fill the buffer
*
* @param buffer The buffer into which to read the data
*
* @exception EOFException If end of file is reached before filling the
* buffer
* @exception IOException If any other error occurs
*/
public final void readFully (byte[] buffer) throws IOException
{
in.readFully(buffer);
}
/**
* This method reads raw bytes into the passed array <code>buf</code>
* starting
* <code>offset</code> bytes into the buffer. The number of bytes read
* will be
* exactly <code>len</code> Note that this method blocks until the data is
* available and throws an exception if there is not enough data left in
* the stream to read <code>len</code> bytes.
*
* @param buffer The buffer into which to read the data
* @param offset The offset into the buffer to start storing data
* @param count The number of bytes to read into the buffer
*
* @exception EOFException If end of file is reached before filling
* the buffer
* @exception IOException If any other error occurs
*/
public final void readFully (byte[] buffer, int offset, int count)
throws IOException
{
in.readFully (buffer, offset, count);
}
/**
* This method reads a Java <code>int</code> value from an input stream
* It operates by reading four bytes from the stream and converting them to
* a single Java <code>int</code> The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte4</code>
* represent the first
* four bytes read from the stream, they will be
* transformed to an <code>int</code> in the following manner:
* <p>
* <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 24) + ((byte2 &amp; 0xFF) &lt;&lt; 16) +
* ((byte3 &amp; 0xFF) &lt;&lt; 8) + (byte4 &amp; 0xFF)))</code>
* <p>
* The value returned is in the range of 0 to 65535.
* <p>
* This method can read an <code>int</code> written by an object
* implementing the
* <code>writeInt()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>int</code> value read
*
* @exception EOFException If end of file is reached before reading the int
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final int readInt () throws IOException
{
return in.readInt();
}
/**
* This method reads the next line of text data from an input stream.
* It operates by reading bytes and converting those bytes to
* <code>char</code>
* values by treating the byte read as the low eight bits of the
* <code>char</code>
* and using <code>0</code> as the high eight bits. Because of this, it does
* not support the full 16-bit Unicode character set.
* <p>
* The reading of bytes ends when either the end of file or a line terminator
* is encountered. The bytes read are then returned as a <code>String</code>
* A line terminator is a byte sequence consisting of either
* <code>\r</code> <code>\n</code> or <code>\r\n</code> These
* termination charaters are
* discarded and are not returned as part of the string.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeLine()</code> method in <code>DataOutput</code>
*
* @return The line read as a <code>String</code>
*
* @exception IOException If an error occurs
*
* @see DataOutput
*/
public final String readLine () throws IOException
{
return in.readLine ();
}
/**
* This method reads a Java long value from an input stream
* It operates by reading eight bytes from the stream and converting them to
* a single Java <code>long</code> The bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> through <code>byte8</code>
* represent the first
* eight bytes read from the stream, they will be
* transformed to an <code>long</code> in the following manner:
* <p>
* <code>
* (long)((((long)byte1 &amp; 0xFF) &lt;&lt; 56) + (((long)byte2 &amp; 0xFF) &lt;&lt; 48) +
* (((long)byte3 &amp; 0xFF) &lt;&lt; 40) + (((long)byte4 &amp; 0xFF) &lt;&lt; 32) +
* (((long)byte5 &amp; 0xFF) &lt;&lt; 24) + (((long)byte6 &amp; 0xFF) &lt;&lt; 16) +
* (((long)byte7 &amp; 0xFF) &lt;&lt; 8) + ((long)byte9 &amp; 0xFF)))</code>
* <p>
* The value returned is in the range of 0 to 65535.
* <p>
* This method can read an <code>long</code> written by an object
* implementing the
* <code>writeLong()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>long</code> value read
*
* @exception EOFException If end of file is reached before reading the long
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final long readLong () throws IOException
{
return in.readLong();
}
/**
* This method reads a signed 16-bit value into a Java in from the stream.
* It operates by reading two bytes from the stream and converting them to
* a single 16-bit Java <code>short</code> The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first
* and second byte read from the stream respectively, they will be
* transformed to a <code>short</code> in the following manner:
* <p>
* <code>(short)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
* <p>
* The value returned is in the range of -32768 to 32767.
* <p>
* This method can read a <code>short</code> written by an object
* implementing the
* <code>writeShort()</code> method in the <code>DataOutput</code> interface.
*
* @return The <code>short</code> value read
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final short readShort () throws IOException
{
return in.readShort();
}
/**
* This method reads 8 unsigned bits into a Java <code>int</code> value
* from the
* stream. The value returned is in the range of 0 to 255.
* <p>
* This method can read an unsigned byte written by an object implementing
* the <code>writeUnsignedByte()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The unsigned bytes value read as a Java <code>int</code>
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final int readUnsignedByte () throws IOException
{
return in.readUnsignedByte();
}
/**
* This method reads 16 unsigned bits into a Java int value from the stream.
* It operates by reading two bytes from the stream and converting them to
* a single Java <code>int</code> The two bytes are stored most
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first
* and second byte read from the stream respectively, they will be
* transformed to an <code>int</code> in the following manner:
* <p>
* <code>(int)(((byte1 &amp; 0xFF) &lt;&lt; 8) + (byte2 &amp; 0xFF))</code>
* <p>
* The value returned is in the range of 0 to 65535.
* <p>
* This method can read an unsigned short written by an object implementing
* the <code>writeUnsignedShort()</code> method in the
* <code>DataOutput</code> interface.
*
* @return The unsigned short value read as a Java <code>int</code>
*
* @exception EOFException If end of file is reached before reading the value
* @exception IOException If any other error occurs
*/
public final int readUnsignedShort () throws IOException
{
return in.readUnsignedShort();
}
/**
* This method reads a <code>String</code> from an input stream that
* is encoded in
* a modified UTF-8 format. This format has a leading two byte sequence
* that contains the remaining number of bytes to read. This two byte
* sequence is read using the <code>readUnsignedShort()</code> method of this
* interface.
* <p>
* After the number of remaining bytes have been determined, these bytes
* are read an transformed into <code>char</code> values.
* These <code>char</code> values
* are encoded in the stream using either a one, two, or three byte format.
* The particular format in use can be determined by examining the first
* byte read.
* <p>
* If the first byte has a high order bit of 0 then
* that character consists on only one byte. This character value consists
* of seven bits that are at positions 0 through 6 of the byte. As an
* example, if <code>byte1</code> is the byte read from the stream, it would
* be converted to a <code>char</code> like so:
* <p>
* <code>(char)byte1</code>
* <p>
* If the first byte has <code>110</code> as its high order bits, then the
* character consists of two bytes. The bits that make up the character
* value are in positions 0 through 4 of the first byte and bit positions
* 0 through 5 of the second byte. (The second byte should have
* 10 as its high order bits). These values are in most significant
* byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code> and <code>byte2</code>
* are the first two bytes
* read respectively, and the high order bits of them match the patterns
* which indicate a two byte character encoding, then they would be
* converted to a Java <code>char</code> like so:
* <p>
* <code>(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))</code>
* <p>
* If the first byte has a <code>1110</code> as its high order bits, then the
* character consists of three bytes. The bits that make up the character
* value are in positions 0 through 3 of the first byte and bit positions
* 0 through 5 of the other two bytes. (The second and third bytes should
* have <code>10</code> as their high order bits). These values are in most
* significant byte first (i.e., "big endian") order.
* <p>
* As an example, if <code>byte1</code> <code>byte2</code>
* and <code>byte3</code> are the
* three bytes read, and the high order bits of them match the patterns
* which indicate a three byte character encoding, then they would be
* converted to a Java <code>char</code> like so:
* <p>
* <code>(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) |
* (byte3 & 0x3F))</code>
* <p>
* Note that all characters are encoded in the method that requires the
* fewest number of bytes with the exception of the character with the
* value of <code>&#92;u0000</code> which is encoded as two bytes. This is
* a modification of the UTF standard used to prevent C language style
* <code>NUL</code> values from appearing in the byte stream.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeUTF()</code> method in <code>DataOutput</code>
*
* @return The <code>String</code> read
*
* @exception EOFException If end of file is reached before reading the
* String
* @exception UTFDataFormatException If the data is not in UTF-8 format
* @exception IOException If any other error occurs
*
* @see DataOutput
*/
public final String readUTF () throws IOException
{
return in.readUTF();
}
/**
* This method sets the current file position to the specified offset
* from the beginning of the file. Note that some operating systems will
* allow the file pointer to be set past the current end of the file.
*
* @param pos The offset from the beginning of the file at which to set
* the file pointer
*
* @exception IOException If an error occurs
*/
public void seek (long pos) throws IOException
{
ch.position(pos);
}
/**
* This method attempts to skip and discard the specified number of bytes
* in the input stream. It may actually skip fewer bytes than requested.
* The actual number of bytes skipped is returned. This method will not
* skip any bytes if passed a negative number of bytes to skip.
*
* @param numBytes The requested number of bytes to skip.
*
* @return The number of bytes actually skipped.
*
* @exception IOException If an error occurs.
*/
public int skipBytes (int numBytes) throws IOException
{
if (numBytes < 0)
throw new IllegalArgumentException ("Can't skip negative bytes: " +
numBytes);
if (numBytes == 0)
return 0;
long oldPos = ch.position();
long newPos = oldPos + numBytes;
long size = ch.size();
if (newPos > size)
newPos = size;
ch.position(newPos);
return (int) (ch.position() - oldPos);
}
/**
* This method writes a single byte of data to the file. The file must
* be open for read-write in order for this operation to succeed.
*
* @param oneByte The byte of data to write, passed as an int.
*
* @exception IOException If an error occurs
*/
public void write (int oneByte) throws IOException
{
out.write(oneByte);
}
/**
* This method writes all the bytes in the specified array to the file.
* The file must be open read-write in order for this operation to succeed.
*
* @param buffer The array of bytes to write to the file
*/
public void write (byte[] buffer) throws IOException
{
out.write(buffer);
}
/**
* This method writes <code>len</code> bytes to the file from the specified
* array starting at index <code>offset</code> into the array.
*
* @param buffer The array of bytes to write to the file
* @param offset The index into the array to start writing file
* @param len The number of bytes to write
*
* @exception IOException If an error occurs
*/
public void write (byte[] buffer, int offset, int len) throws IOException
{
out.write (buffer, offset, len);
}
/**
* This method writes a Java <code>boolean</code> to the underlying output
* stream. For a value of <code>true</code>, 1 is written to the stream.
* For a value of <code>false</code>, 0 is written.
*
* @param val The <code>boolean</code> value to write to the stream
*
* @exception IOException If an error occurs
*/
public final void writeBoolean (boolean val) throws IOException
{
out.writeBoolean(val);
}
/**
* This method writes a Java <code>byte</code> value to the underlying
* output stream.
*
* @param val The <code>byte</code> to write to the stream, passed
* as an <code>int</code>.
*
* @exception IOException If an error occurs
*/
public final void writeByte (int val) throws IOException
{
out.writeByte(val);
}
/**
* This method writes a Java <code>short</code> to the stream, high byte
* first. This method requires two bytes to encode the value.
*
* @param val The <code>short</code> value to write to the stream,
* passed as an <code>int</code>.
*
* @exception IOException If an error occurs
*/
public final void writeShort (int val) throws IOException
{
out.writeShort(val);
}
/**
* This method writes a single <code>char</code> value to the stream,
* high byte first.
*
* @param val The <code>char</code> value to write, passed as
* an <code>int</code>.
*
* @exception IOException If an error occurs
*/
public final void writeChar (int val) throws IOException
{
out.writeChar(val);
}
/**
* This method writes a Java <code>int</code> to the stream, high bytes
* first. This method requires four bytes to encode the value.
*
* @param val The <code>int</code> value to write to the stream.
*
* @exception IOException If an error occurs
*/
public final void writeInt (int val) throws IOException
{
out.writeInt(val);
}
/**
* This method writes a Java <code>long</code> to the stream, high bytes
* first. This method requires eight bytes to encode the value.
*
* @param val The <code>long</code> value to write to the stream.
*
* @exception IOException If an error occurs
*/
public final void writeLong (long val) throws IOException
{
out.writeLong(val);
}
/**
* This method writes a Java <code>float</code> value to the stream. This
* value is written by first calling the method
* <code>Float.floatToIntBits</code>
* to retrieve an <code>int</code> representing the floating point number,
* then writing this <code>int</code> value to the stream exactly the same
* as the <code>writeInt()</code> method does.
*
* @param val The floating point number to write to the stream.
*
* @exception IOException If an error occurs
*
* @see #writeInt(int)
*/
public final void writeFloat (float val) throws IOException
{
out.writeFloat(val);
}
/**
* This method writes a Java <code>double</code> value to the stream. This
* value is written by first calling the method
* <code>Double.doubleToLongBits</code>
* to retrieve an <code>long</code> representing the floating point number,
* then writing this <code>long</code> value to the stream exactly the same
* as the <code>writeLong()</code> method does.
*
* @param val The double precision floating point number to write to the
* stream.
*
* @exception IOException If an error occurs
*
* @see #writeLong(long)
*/
public final void writeDouble (double val) throws IOException
{
out.writeDouble(val);
}
/**
* This method writes all the bytes in a <code>String</code> out to the
* stream. One byte is written for each character in the <code>String</code>.
* The high eight bits of each character are discarded.
*
* @param val The <code>String</code> to write to the stream
*
* @exception IOException If an error occurs
*/
public final void writeBytes (String val) throws IOException
{
out.writeBytes(val);
}
/**
* This method writes all the characters in a <code>String</code> to the
* stream. There will be two bytes for each character value. The high
* byte of the character will be written first.
*
* @param val The <code>String</code> to write to the stream.
*
* @exception IOException If an error occurs
*/
public final void writeChars (String val) throws IOException
{
out.writeChars(val);
}
/**
* This method writes a Java <code>String</code> to the stream in a modified
* UTF-8 format. First, two bytes are written to the stream indicating the
* number of bytes to follow. Note that this is the number of bytes in the
* encoded <code>String</code> not the <code>String</code> length. Next
* come the encoded characters. Each character in the <code>String</code>
* is encoded as either one, two or three bytes. For characters in the
* range of <code>&#92;u0001</code> to <code>&#92;u007F</code>,
* one byte is used. The character
* value goes into bits 0-7 and bit eight is 0. For characters in the range
* of <code>&#92;u0080</code> to <code>&#92;u007FF</code>, two
* bytes are used. Bits
* 6-10 of the character value are encoded bits 0-4 of the first byte, with
* the high bytes having a value of "110". Bits 0-5 of the character value
* are stored in bits 0-5 of the second byte, with the high bits set to
* "10". This type of encoding is also done for the null character
* <code>&#92;u0000</code>. This eliminates any C style NUL character values
* in the output. All remaining characters are stored as three bytes.
* Bits 12-15 of the character value are stored in bits 0-3 of the first
* byte. The high bits of the first bytes are set to "1110". Bits 6-11
* of the character value are stored in bits 0-5 of the second byte. The
* high bits of the second byte are set to "10". And bits 0-5 of the
* character value are stored in bits 0-5 of byte three, with the high bits
* of that byte set to "10".
*
* @param val The <code>String</code> to write to the output in UTF format
*
* @exception IOException If an error occurs
*/
public final void writeUTF (String val) throws IOException
{
out.writeUTF(val);
}
/**
* This method creates a java.nio.channels.FileChannel.
* Nio does not allow one to create a file channel directly.
* A file channel must be created by first creating an instance of
* Input/Output/RandomAccessFile and invoking the getChannel() method on it.
*/
public final synchronized FileChannel getChannel ()
{
return ch;
}
}
+271
View File
@@ -0,0 +1,271 @@
/* Reader.java -- base class of classes that read input as a stream of chars
Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This abstract class forms the base of the hierarchy of classes that read
* input as a stream of characters. It provides a common set of methods for
* reading characters from streams. Subclasses implement and extend these
* methods to read characters from a particular input source such as a file
* or network connection.
*
* @author Per Bothner (bothner@cygnus.com)
* @date April 21, 1998.
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public abstract class Reader
{
/**
* This is the <code>Object</code> used for synchronizing critical code
* sections. Subclasses should use this variable instead of a
* synchronized method or an explicit synchronization on <code>this</code>
*/
protected Object lock;
/**
* Unitializes a <code>Reader</code> that will use the object
* itself for synchronization of critical code sections.
*/
protected Reader()
{
this.lock = this;
}
/**
* Initializes a <code>Reader</code> that will use the specified
* <code>Object</code> for synchronization of critical code sections.
*
* @param lock The <code>Object</code> to use for synchronization
*/
protected Reader(Object lock)
{
this.lock = lock;
}
/**
* Read chars from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code>
* into the buffer and attempts to read <code>len</code> chars. This method
* can return before reading the number of chars requested. The actual
* number of chars read is returned as an int. A -1 is returned to indicate
* the end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling the single char <code>read()</code> method
* in a loop until the desired number of chars are read. The read loop
* stops short if the end of the stream is encountered or if an IOException
* is encountered on any read operation except the first. If the first
* attempt to read a chars fails, the IOException is allowed to propagate
* upward. And subsequent IOException is caught and treated identically
* to an end of stream condition. Subclasses can (and should if possible)
* override this method to provide a more efficient implementation.
*
* @param buf The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
* @param count The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public abstract int read(char buf[], int offset, int count)
throws IOException;
/**
* Reads chars from a stream and stores them into a caller
* supplied buffer. This method attempts to completely fill the buffer,
* but can return before doing so. The actual number of chars read is
* returned as an int. A -1 is returned to indicate the end of the stream.
* <p>
* This method will block until some data can be read.
* <p>
* This method operates by calling an overloaded read method like so:
* <code>read(buf, 0, buf.length)</code>
*
* @param buf The buffer into which the chars read will be stored.
*
* @return The number of chars read or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(char buf[]) throws IOException
{
return read(buf, 0, buf.length);
}
/**
* Reads an char from the input stream and returns it
* as an int in the range of 0-65535. This method also will return -1 if
* the end of the stream has been reached.
* <p>
* This method will block until the char can be read.
*
* @return The char read or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
char[] buf = new char[1];
int count = read(buf, 0, 1);
return count > 0 ? buf[0] : -1;
}
/**
* Closes the stream. Any futher attempts to read from the
* stream may generate an <code>IOException</code>.
*
* @exception IOException If an error occurs
*/
public abstract void close() throws IOException;
/**
* Returns a boolean that indicates whether the mark/reset
* methods are supported in this class. Those methods can be used to
* remember a specific point in the stream and reset the stream to that
* point.
* <p>
* This method always returns <code>false</code> in this class, but
* subclasses can override this method to return <code>true</code> if they
* support mark/reset functionality.
*
* @return <code>true</code> if mark/reset functionality is supported,
* <code>false</code> otherwise
*
*/
public boolean markSupported()
{
return false;
}
/**
* Marks a position in the input to which the stream can be
* "reset" by calling the <code>reset()</code> method. The parameter
* <code>readlimit</code> is the number of chars that can be read from the
* stream after setting the mark before the mark becomes invalid. For
* example, if <code>mark()</code> is called with a read limit of 10, then
* when 11 chars of data are read from the stream before the
* <code>reset()</code> method is called, then the mark is invalid and the
* stream object instance is not required to remember the mark.
*
* @param readLimit The number of chars that can be read before the mark
* becomes invalid
*
* @exception IOException If an error occurs such as mark not being
* supported for this class
*/
public void mark(int readLimit) throws IOException
{
throw new IOException("mark not supported");
}
/**
* Resets a stream to the point where the <code>mark()</code>
* method was called. Any chars that were read after the mark point was
* set will be re-read during subsequent reads.
* <p>
* This method always throws an IOException in this class, but subclasses
* can override this method if they provide mark/reset functionality.
*
* @exception IOException Always thrown for this class
*/
public void reset() throws IOException
{
throw new IOException("reset not supported");
}
/**
* Determines whether or not this stream is ready to be
* read. If it returns <code>false</code> the stream may block if a
* read is attempted, but it is not guaranteed to do so.
* <p>
* This method always returns <code>false</code> in this class
*
* @return <code>true</code> if the stream is ready to be read,
* <code>false</code> otherwise.
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException
{
return false;
}
/**
* Skips the specified number of chars in the stream. It
* returns the actual number of chars skipped, which may be less than the
* requested amount.
* <p>
* This method reads and discards chars into a 256 char array until the
* specified number of chars were skipped or until either the end of stream
* is reached or a read attempt returns a short count. Subclasses can
* override this method to provide a more efficient implementation where
* one exists.
*
* @param count The requested number of chars to skip
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs
*/
public long skip(long count) throws IOException
{
if (count <= 0)
return 0;
int bsize = count > 1024 ? 1024 : (int) count;
char[] buffer = new char[bsize];
long todo = count;
synchronized (lock)
{
while (todo > 0)
{
int skipped = read(buffer, 0, bsize > todo ? (int) todo : bsize);
if (skipped <= 0)
break;
todo -= skipped;
}
}
return count - todo;
}
}
@@ -0,0 +1,221 @@
/* SequenceInputStream.java -- Reads multiple input streams in sequence
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.util.Enumeration;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This class merges a sequence of multiple <code>InputStream</code>'s in
* order to form a single logical stream that can be read by applications
* that expect only one stream.
* <p>
* The streams passed to the constructor method are read in order until
* they return -1 to indicate they are at end of stream. When a stream
* reports end of stream, it is closed, then the next stream is read.
* When the last stream is closed, the next attempt to read from this
* stream will return a -1 to indicate it is at end of stream.
* <p>
* If this stream is closed prior to all subordinate streams being read
* to completion, all subordinate streams are closed.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class SequenceInputStream extends InputStream
{
/** The handle for the current input stream. */
private InputStream in;
/** Secondary input stream; not used if constructed w/ enumeration. */
private InputStream in2;
/** The enumeration handle; not used if constructed w/ 2 explicit input streams. */
private Enumeration e;
/**
* This method creates a new <code>SequenceInputStream</code> that obtains
* its list of subordinate <code>InputStream</code>s from the specified
* <code>Enumeration</code>
*
* @param e An <code>Enumeration</code> that will return a list of
* <code>InputStream</code>s to read in sequence
*/
public SequenceInputStream(Enumeration e)
{
this.e = e;
in = (InputStream) e.nextElement();
in2 = null;
}
/**
* This method creates a new <code>SequenceInputStream</code> that will read
* the two specified subordinate <code>InputStream</code>s in sequence.
*
* @param s1 The first <code>InputStream</code> to read
* @param s2 The second <code>InputStream</code> to read
*/
public SequenceInputStream(InputStream s1, InputStream s2)
{
in = s1;
in2 = s2;
}
/**
* This method returns the number of bytes than can be read from the
* currently being read subordinate stream before that stream could
* block. Note that it is possible more bytes than this can actually
* be read without the stream blocking. If a 0 is returned, then the
* stream could block on the very next read.
*
* @return The number of bytes that can be read before blocking could occur
*
* @exception IOException If an error occurs
*/
public int available() throws IOException
{
if (in == null)
return 0;
return in.available();
}
/**
* Closes this stream. This will cause any remaining unclosed subordinate
* <code>InputStream</code>'s to be closed as well. Subsequent attempts to
* read from this stream may cause an exception.
*
* @exception IOException If an error occurs
*/
public void close() throws IOException
{
while (in != null)
{
in.close();
in = getNextStream ();
}
}
/**
* This method reads an unsigned byte from the input stream and returns it
* as an int in the range of 0-255. This method also will return -1 if
* the end of the stream has been reached. This will only happen when
* all of the subordinate streams have been read.
* <p>
* This method will block until the byte can be read.
*
* @return The byte read, or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read() throws IOException
{
int ch = -1;
while (in != null && (ch = in.read()) < 0)
{
in.close();
in = getNextStream();
}
return ch;
}
/**
* This method reads bytes from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code>
* into the buffer and attempts to read <code>len</code> bytes. This method
* can return before reading the number of bytes requested. The actual number
* of bytes read is returned as an int. A -1 is returend to indicate the
* end of the stream. This will only happen when all of the subordinate
* streams have been read.
* <p>
* This method will block until at least one byte can be read.
*
* @param b The array into which bytes read should be stored
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream
*
* @exception IOException If an error occurs
*/
public int read(byte[] b, int off, int len) throws IOException
{
int ch = -1;
// The validity of the parameters will be checked by in.read so
// don't bother doing it here.
while (in != null && (ch = in.read(b, off, len)) < 0)
{
in.close();
in = getNextStream();
}
return ch;
}
/**
* This private method is used to get the next <code>InputStream</code> to
* read from. Returns null when no more streams are available.
*/
private InputStream getNextStream()
{
InputStream nextIn = null;
if (e != null)
{
if (e.hasMoreElements())
nextIn = (InputStream) e.nextElement();
}
else
if (in2 != null)
{
nextIn = in2;
in2 = null;
}
return nextIn;
}
}
@@ -0,0 +1,54 @@
/* Serializable.java -- Interface to indicate a class may be serialized
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* Status: Believed complete
*/
/**
* This interface has no methods. It simply serves to indicate that
* the implementing class may be serialized.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public interface Serializable
{
} // interface Serializable
@@ -0,0 +1,113 @@
/* SerializablePermission.java -- Basic permissions related to serialization.
Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
import java.security.BasicPermission;
/**
* This class models permissions related to serialization. As a subclass
* of <code>BasicPermission</code>, this class has permissions that have
* a name only. There is no associated action list.
* <p>
* There are currently two allowable permission names for this class:
* <ul>
* <li><code>enableSubclassImplementation</code> - Allows a subclass to
* override the default serialization behavior of objects.</li>
* <li><code>enableSubstitution</code> - Allows substitution of one object
* for another during serialization or deserialization.</li>
* </ul>
*
* @see java.security.BasicPermission
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public final class SerializablePermission extends BasicPermission
{
static final long serialVersionUID = 8537212141160296410L;
/*
* Class Variables
*/
private static final String[] legal_names = { "enableSubclassImplementation",
"enableSubstitution" };
/*
* Constructors
*/
/**
* This method initializes a new instance of
* <code>SerializablePermission</code>
* that has the specified name.
*
* @param name The name of the permission.
*
* @exception IllegalArgumentException If the name is not valid for
* this class.
*/
public SerializablePermission(String name)
{
this(name, null);
}
/**
* This method initializes a new instance of
* <code>SerializablePermission</code>
* that has the specified name and action list. Note that the action list
* is unused in this class.
*
* @param name The name of the permission.
* @param actions The action list (unused).
*
* @exception IllegalArgumentException If the name is not valid for
* this class.
*/
public SerializablePermission(String name, String actions)
{
super(name, actions);
for (int i = 0; i < legal_names.length; i++)
if (legal_names[i].equals(name))
return;
throw new IllegalArgumentException("Bad permission name: " + name);
}
} // class SerializablePermission
@@ -0,0 +1,73 @@
/* StreamCorruptedException.java -- Error in stream during serialization
Copyright (C) 1998, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when there is an error in the data that is
* read from a stream during de-serialization.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @since 1.1
* @status updated to 1.4
*/
public class StreamCorruptedException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = 8983558202217591746L;
/**
* Create an exception without a descriptive error message.
*/
public StreamCorruptedException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public StreamCorruptedException(String message)
{
super(message);
}
} // class StreamCorruptedException
@@ -0,0 +1,708 @@
/* StreamTokenizer.java -- parses streams of characters into tokens
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This class parses streams of characters into tokens. There are a
* million-zillion flags that can be set to control the parsing, as
* described under the various method headings.
*
* @author Warren Levy (warrenl@cygnus.com)
* @date October 25, 1998.
*/
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
public class StreamTokenizer
{
/** A constant indicating that the end of the stream has been read. */
public static final int TT_EOF = -1;
/** A constant indicating that the end of the line has been read. */
public static final int TT_EOL = '\n';
/** A constant indicating that a number token has been read. */
public static final int TT_NUMBER = -2;
/** A constant indicating that a word token has been read. */
public static final int TT_WORD = -3;
/** A constant indicating that no tokens have been read yet. */
private static final int TT_NONE = -4;
/**
* Contains the type of the token read resulting from a call to nextToken
* The rules are as follows:
* <ul>
* <li>For a token consisting of a single ordinary character, this is the
* value of that character.</li>
* <li>For a quoted string, this is the value of the quote character</li>
* <li>For a word, this is TT_WORD</li>
* <li>For a number, this is TT_NUMBER</li>
* <li>For the end of the line, this is TT_EOL</li>
* <li>For the end of the stream, this is TT_EOF</li>
* </ul>
*/
public int ttype = TT_NONE;
/** The String associated with word and string tokens. */
public String sval;
/** The numeric value associated with number tokens. */
public double nval;
/* Indicates whether end-of-line is recognized as a token. */
private boolean eolSignificant = false;
/* Indicates whether word tokens are automatically made lower case. */
private boolean lowerCase = false;
/* Indicates whether C++ style comments are recognized and skipped. */
private boolean slashSlash = false;
/* Indicates whether C style comments are recognized and skipped. */
private boolean slashStar = false;
/* Attribute tables of each byte from 0x00 to 0xFF. */
private boolean[] whitespace = new boolean[256];
private boolean[] alphabetic = new boolean[256];
private boolean[] numeric = new boolean[256];
private boolean[] quote = new boolean[256];
private boolean[] comment = new boolean[256];
/* The Reader associated with this class. */
private PushbackReader in;
/* Indicates if a token has been pushed back. */
private boolean pushedBack = false;
/* Contains the current line number of the reader. */
private int lineNumber = 1;
/**
* This method reads bytes from an <code>InputStream</code> and tokenizes
* them. For details on how this method operates by default, see
* <code>StreamTokenizer(Reader)</code>.
*
* @param is The <code>InputStream</code> to read from
*
* @deprecated Since JDK 1.1.
*/
public StreamTokenizer(InputStream is)
{
this(new InputStreamReader(is));
}
/**
* This method initializes a new <code>StreamTokenizer</code> to read
* characters from a <code>Reader</code> and parse them. The char values
* have their hight bits masked so that the value is treated a character
* in the range of 0x0000 to 0x00FF.
* <p>
* This constructor sets up the parsing table to parse the stream in the
* following manner:
* <ul>
* <li>The values 'A' through 'Z', 'a' through 'z' and 0xA0 through 0xFF
* are initialized as alphabetic</li>
* <li>The values 0x00 through 0x20 are initialized as whitespace</li>
* <li>The values '\'' and '"' are initialized as quote characters</li>
* <li>'/' is a comment character</li>
* <li>Numbers will be parsed</li>
* <li>EOL is not treated as significant</li>
* <li>C and C++ (//) comments are not recognized</li>
* </ul>
*
* @param r The <code>Reader</code> to read chars from
*/
public StreamTokenizer(Reader r)
{
in = new PushbackReader(r);
whitespaceChars(0x00, 0x20);
wordChars('A', 'Z');
wordChars('a', 'z');
wordChars(0xA0, 0xFF);
commentChar('/');
quoteChar('\'');
quoteChar('"');
parseNumbers();
}
/**
* This method sets the comment attribute on the specified
* character. Other attributes for the character are cleared.
*
* @param ch The character to set the comment attribute for, passed as an int
*/
public void commentChar(int ch)
{
if (ch >= 0 && ch <= 255)
{
comment[ch] = true;
whitespace[ch] = false;
alphabetic[ch] = false;
numeric[ch] = false;
quote[ch] = false;
}
}
/**
* This method sets a flag that indicates whether or not the end of line
* sequence terminates and is a token. The defaults to <code>false</code>
*
* @param flag <code>true</code> if EOF is significant, <code>false</code>
* otherwise
*/
public void eolIsSignificant(boolean flag)
{
eolSignificant = flag;
}
/**
* This method returns the current line number. Note that if the
* <code>pushBack()</code> method is called, it has no effect on the
* line number returned by this method.
*
* @return The current line number
*/
public int lineno()
{
return lineNumber;
}
/**
* This method sets a flag that indicates whether or not alphabetic
* tokens that are returned should be converted to lower case.
*
* @param flag <code>true</code> to convert to lower case,
* <code>false</code> otherwise
*/
public void lowerCaseMode(boolean flag)
{
lowerCase = flag;
}
private boolean isWhitespace(int ch)
{
return (ch >= 0 && ch <= 255 && whitespace[ch]);
}
private boolean isAlphabetic(int ch)
{
return ((ch > 255) || (ch >= 0 && alphabetic[ch]));
}
private boolean isNumeric(int ch)
{
return (ch >= 0 && ch <= 255 && numeric[ch]);
}
private boolean isQuote(int ch)
{
return (ch >= 0 && ch <= 255 && quote[ch]);
}
private boolean isComment(int ch)
{
return (ch >= 0 && ch <= 255 && comment[ch]);
}
/**
* This method reads the next token from the stream. It sets the
* <code>ttype</code> variable to the appropriate token type and
* returns it. It also can set <code>sval</code> or <code>nval</code>
* as described below. The parsing strategy is as follows:
* <ul>
* <li>Skip any whitespace characters.</li>
* <li>If a numeric character is encountered, attempt to parse a numeric
* value. Leading '-' characters indicate a numeric only if followed by
* another non-'-' numeric. The value of the numeric token is terminated
* by either the first non-numeric encountered, or the second occurrence of
* '-' or '.'. The token type returned is TT_NUMBER and <code>nval</code>
* is set to the value parsed.</li>
* <li>If an alphabetic character is parsed, all subsequent characters
* are read until the first non-alphabetic or non-numeric character is
* encountered. The token type returned is TT_WORD and the value parsed
* is stored in <code>sval</code>. If lower case mode is set, the token
* stored in <code>sval</code> is converted to lower case. The end of line
* sequence terminates a word only if EOL signficance has been turned on.
* The start of a comment also terminates a word. Any character with a
* non-alphabetic and non-numeric attribute (such as white space, a quote,
* or a commet) are treated as non-alphabetic and terminate the word.</li>
* <li>If a comment character is parsed, then all remaining characters on
* the current line are skipped and another token is parsed. Any EOL or
* EOF's encountered are not discarded, but rather terminate the comment.</li>
* <li>If a quote character is parsed, then all characters up to the
* second occurrence of the same quote character are parsed into a
* <code>String</code>. This <code>String</code> is stored as
* <code>sval</code>, but is not converted to lower case, even if lower case
* mode is enabled. The token type returned is the value of the quote
* character encountered. Any escape sequences
* (\b (backspace), \t (HTAB), \n (linefeed), \f (form feed), \r
* (carriage return), \" (double quote), \' (single quote), \\
* (backslash), \XXX (octal esacpe)) are converted to the appropriate
* char values. Invalid esacape sequences are left in untranslated.
* Unicode characters like ('\ u0000') are not recognized. </li>
* <li>If the C++ comment sequence "//" is encountered, and the parser
* is configured to handle that sequence, then the remainder of the line
* is skipped and another token is read exactly as if a character with
* the comment attribute was encountered.</li>
* <li>If the C comment sequence "/*" is encountered, and the parser
* is configured to handle that sequence, then all characters up to and
* including the comment terminator sequence are discarded and another
* token is parsed.</li>
* <li>If all cases above are not met, then the character is an ordinary
* character that is parsed as a token by itself. The char encountered
* is returned as the token type.</li>
* </ul>
*
* @return The token type
* @exception IOException If an I/O error occurs
*/
public int nextToken() throws IOException
{
if (pushedBack)
{
pushedBack = false;
if (ttype != TT_NONE)
return ttype;
}
sval = null;
int ch;
// Skip whitespace. Deal with EOL along the way.
while (isWhitespace(ch = in.read()))
if (ch == '\n' || ch == '\r')
{
lineNumber++;
// Throw away \n if in combination with \r.
if (ch == '\r' && (ch = in.read()) != '\n')
{
if (ch != TT_EOF)
in.unread(ch);
}
if (eolSignificant)
return (ttype = TT_EOL);
}
if (ch == '/')
if ((ch = in.read()) == '/' && slashSlash)
{
while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
;
if (ch != TT_EOF)
in.unread(ch);
return nextToken(); // Recursive, but not too deep in normal cases
}
else if (ch == '*' && slashStar)
{
while (true)
{
ch = in.read();
if (ch == '*')
{
if ((ch = in.read()) == '/')
break;
else if (ch != TT_EOF)
in.unread(ch);
}
else if (ch == '\n' || ch == '\r')
{
lineNumber++;
if (ch == '\r' && (ch = in.read()) != '\n')
{
if (ch != TT_EOF)
in.unread(ch);
}
}
else if (ch == TT_EOF)
{
break;
}
}
return nextToken(); // Recursive, but not too deep in normal cases
}
else
{
if (ch != TT_EOF)
in.unread(ch);
ch = '/';
}
if (ch == TT_EOF)
ttype = TT_EOF;
else if (isNumeric(ch))
{
boolean isNegative = false;
if (ch == '-')
{
// Read ahead to see if this is an ordinary '-' rather than numeric.
ch = in.read();
if (isNumeric(ch) && ch != '-')
{
isNegative = true;
}
else
{
if (ch != TT_EOF)
in.unread(ch);
return (ttype = '-');
}
}
StringBuffer tokbuf = new StringBuffer();
tokbuf.append((char) ch);
int decCount = 0;
while (isNumeric(ch = in.read()) && ch != '-')
if (ch == '.' && decCount++ > 0)
break;
else
tokbuf.append((char) ch);
if (ch != TT_EOF)
in.unread(ch);
ttype = TT_NUMBER;
try
{
nval = Double.valueOf(tokbuf.toString()).doubleValue();
}
catch (NumberFormatException _)
{
nval = 0.0;
}
if (isNegative)
nval = -nval;
}
else if (isAlphabetic(ch))
{
StringBuffer tokbuf = new StringBuffer();
tokbuf.append((char) ch);
while (isAlphabetic(ch = in.read()) || isNumeric(ch))
tokbuf.append((char) ch);
if (ch != TT_EOF)
in.unread(ch);
ttype = TT_WORD;
sval = tokbuf.toString();
if (lowerCase)
sval = sval.toLowerCase();
}
else if (isComment(ch))
{
while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
;
if (ch != TT_EOF)
in.unread(ch);
return nextToken(); // Recursive, but not too deep in normal cases.
}
else if (isQuote(ch))
{
ttype = ch;
StringBuffer tokbuf = new StringBuffer();
while ((ch = in.read()) != ttype && ch != '\n' && ch != '\r' &&
ch != TT_EOF)
{
if (ch == '\\')
switch (ch = in.read())
{
case 'a': ch = 0x7;
break;
case 'b': ch = '\b';
break;
case 'f': ch = 0xC;
break;
case 'n': ch = '\n';
break;
case 'r': ch = '\r';
break;
case 't': ch = '\t';
break;
case 'v': ch = 0xB;
break;
case '\n': ch = '\n';
break;
case '\r': ch = '\r';
break;
case '\"':
case '\'':
case '\\':
break;
default:
int ch1, nextch;
if ((nextch = ch1 = ch) >= '0' && ch <= '7')
{
ch -= '0';
if ((nextch = in.read()) >= '0' && nextch <= '7')
{
ch = ch * 8 + nextch - '0';
if ((nextch = in.read()) >= '0' && nextch <= '7' &&
ch1 >= '0' && ch1 <= '3')
{
ch = ch * 8 + nextch - '0';
nextch = in.read();
}
}
}
if (nextch != TT_EOF)
in.unread(nextch);
}
tokbuf.append((char) ch);
}
// Throw away matching quote char.
if (ch != ttype && ch != TT_EOF)
in.unread(ch);
sval = tokbuf.toString();
}
else
{
ttype = ch;
}
return ttype;
}
private void resetChar(int ch)
{
whitespace[ch] = alphabetic[ch] = numeric[ch] = quote[ch] = comment[ch] =
false;
}
/**
* This method makes the specified character an ordinary character. This
* means that none of the attributes (whitespace, alphabetic, numeric,
* quote, or comment) will be set on this character. This character will
* parse as its own token.
*
* @param ch The character to make ordinary, passed as an int
*/
public void ordinaryChar(int ch)
{
if (ch >= 0 && ch <= 255)
resetChar(ch);
}
/**
* This method makes all the characters in the specified range, range
* terminators included, ordinary. This means the none of the attributes
* (whitespace, alphabetic, numeric, quote, or comment) will be set on
* any of the characters in the range. This makes each character in this
* range parse as its own token.
*
* @param low The low end of the range of values to set the whitespace
* attribute for
* @param hi The high end of the range of values to set the whitespace
* attribute for
*/
public void ordinaryChars(int low, int hi)
{
if (low < 0)
low = 0;
if (hi > 255)
hi = 255;
for (int i = low; i <= hi; i++)
resetChar(i);
}
/**
* This method sets the numeric attribute on the characters '0' - '9' and
* the characters '.' and '-'.
*/
public void parseNumbers()
{
for (int i = 0; i <= 9; i++)
numeric['0' + i] = true;
numeric['.'] = true;
numeric['-'] = true;
}
/**
* Puts the current token back into the StreamTokenizer so
* <code>nextToken</code> will return the same value on the next call.
* May cause the lineno method to return an incorrect value
* if lineno is called before the next call to nextToken.
*/
public void pushBack()
{
pushedBack = true;
}
/**
* This method sets the quote attribute on the specified character.
* Other attributes for the character are cleared.
*
* @param ch The character to set the quote attribute for, passed as an int.
*/
public void quoteChar(int ch)
{
if (ch >= 0 && ch <= 255)
{
quote[ch] = true;
comment[ch] = false;
whitespace[ch] = false;
alphabetic[ch] = false;
numeric[ch] = false;
}
}
/**
* This method removes all attributes (whitespace, alphabetic, numeric,
* quote, and comment) from all characters. It is equivalent to calling
* <code>ordinaryChars(0x00, 0xFF)</code>.
*
* @see #ordinaryChars(int, int)
*/
public void resetSyntax()
{
ordinaryChars(0x00, 0xFF);
}
/**
* This method sets a flag that indicates whether or not "C++" language style
* comments ("//" comments through EOL ) are handled by the parser.
* If this is <code>true</code> commented out sequences are skipped and
* ignored by the parser. This defaults to <code>false</code>.
*
* @param flag <code>true</code> to recognized and handle "C++" style
* comments, <code>false</code> otherwise
*/
public void slashSlashComments(boolean flag)
{
slashSlash = flag;
}
/**
* This method sets a flag that indicates whether or not "C" language style
* comments (with nesting not allowed) are handled by the parser.
* If this is <code>true</code> commented out sequences are skipped and
* ignored by the parser. This defaults to <code>false</code>.
*
* @param flag <code>true</code> to recognized and handle "C" style comments,
* <code>false</code> otherwise
*/
public void slashStarComments(boolean flag)
{
slashStar = flag;
}
/**
* This method returns the current token value as a <code>String</code> in
* the form "Token[x], line n", where 'n' is the current line numbers and
* 'x' is determined as follows.
* <p>
* <ul>
* <li>If no token has been read, then 'x' is "NOTHING" and 'n' is 0</li>
* <li>If <code>ttype</code> is TT_EOF, then 'x' is "EOF"</li>
* <li>If <code>ttype</code> is TT_EOL, then 'x' is "EOL"</li>
* <li>If <code>ttype</code> is TT_WORD, then 'x' is <code>sval</code></li>
* <li>If <code>ttype</code> is TT_NUMBER, then 'x' is "n=strnval" where
* 'strnval' is <code>String.valueOf(nval)</code>.</li>
* <li>If <code>ttype</code> is a quote character, then 'x' is
* <code>sval</code></li>
* <li>For all other cases, 'x' is <code>ttype</code></li>
* </ul>
*/
public String toString()
{
String tempstr;
if (ttype == TT_EOF)
tempstr = "EOF";
else if (ttype == TT_EOL)
tempstr = "EOL";
else if (ttype == TT_WORD)
tempstr = sval;
else if (ttype == TT_NUMBER)
tempstr = "n=" + nval;
else if (ttype == TT_NONE)
tempstr = "NOTHING";
else // must be an ordinary char.
tempstr = "\'" + (char) ttype + "\'";
return "Token[" + tempstr + "], line " + lineno();
}
/**
* This method sets the whitespace attribute for all characters in the
* specified range, range terminators included.
*
* @param low The low end of the range of values to set the whitespace
* attribute for
* @param hi The high end of the range of values to set the whitespace
* attribute for
*/
public void whitespaceChars(int low, int hi)
{
if (low < 0)
low = 0;
if (hi > 255)
hi = 255;
for (int i = low; i <= hi; i++)
{
resetChar(i);
whitespace[i] = true;
}
}
/**
* This method sets the alphabetic attribute for all characters in the
* specified range, range terminators included.
*
* @param low The low end of the range of values to set the alphabetic
* attribute for
* @param hi The high end of the range of values to set the alphabetic
* attribute for
*/
public void wordChars(int low, int hi)
{
if (low < 0)
low = 0;
if (hi > 255)
hi = 255;
for (int i = low; i <= hi; i++)
alphabetic[i] = true;
}
}
@@ -0,0 +1,187 @@
/* StringBufferInputStream.java -- Read an String as a stream
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct. Deprecated in JDK 1.1.
*/
/**
* This class permits a <code>String</code> to be read as an input stream.
* The low eight bits of each character in the <code>String</code> are the
* bytes that are returned. The high eight bits of each character are
* discarded.
* <p>
* The mark/reset functionality in this class behaves differently than
* normal. The <code>mark()</code> method is always ignored and the
* <code>reset()</code> method always resets in stream to start reading from
* position 0 in the String. Note that since this method does not override
* <code>markSupported()</code> in <code>InputStream</code>, calling that
* method will return <code>false</code>.
* <p>
* Note that this class is deprecated because it does not properly handle
* 16-bit Java characters. It is provided for backwards compatibility only
* and should not be used for new development. The <code>StringReader</code>
* class should be used instead.
*
* @deprecated
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
*/
public class StringBufferInputStream extends InputStream
{
/** The String which is the input to this stream. */
protected String buffer;
/** Position of the next byte in buffer to be read. */
protected int pos = 0;
/** The length of the String buffer. */
protected int count;
/**
* Create a new <code>StringBufferInputStream</code> that will read bytes
* from the passed in <code>String</code>. This stream will read from the
* beginning to the end of the <code>String</code>.
*
* @param s The <code>String</code> this stream will read from.
*/
public StringBufferInputStream(String s)
{
buffer = s;
count = s.length();
}
/**
* This method returns the number of bytes available to be read from this
* stream. The value returned will be equal to <code>count - pos</code>.
*
* @return The number of bytes that can be read from this stream before
* blocking, which is all of them
*/
public int available()
{
return count - pos;
}
/**
* This method reads one byte from the stream. The <code>pos</code> counter
* is advanced to the next byte to be read. The byte read is returned as
* an int in the range of 0-255. If the stream position is already at the
* end of the buffer, no byte is read and a -1 is returned in order to
* indicate the end of the stream.
*
* @return The byte read, or -1 if end of stream
*/
public int read()
{
if (pos >= count)
return -1; // EOF
return ((int) buffer.charAt(pos++)) & 0xFF;
}
/**
* This method reads bytes from the stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code>
* into the buffer and attempts to read <code>len</code> bytes. This method
* can return before reading the number of bytes requested if the end of the
* stream is encountered first. The actual number of bytes read is
* returned. If no bytes can be read because the stream is already at
* the end of stream position, a -1 is returned.
* <p>
* This method does not block.
*
* @param b The array into which the bytes read should be stored.
* @param off The offset into the array to start storing bytes
* @param len The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*/
public int read(byte[] b, int off, int len)
{
if (off < 0 || len < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
if (pos >= count)
return -1; // EOF
int numRead = Math.min(len, count - pos);
if (numRead < 0)
return 0;
buffer.getBytes(pos, pos + numRead, b, off);
pos += numRead;
return numRead;
}
/**
* This method sets the read position in the stream to the beginning
* setting the <code>pos</code> variable equal to 0. Note that this differs
* from the common implementation of the <code>reset()</code> method.
*/
public void reset()
{
pos = 0;
}
/**
* This method attempts to skip the requested number of bytes in the
* input stream. It does this by advancing the <code>pos</code> value by the
* specified number of bytes. It this would exceed the length of the
* buffer, then only enough bytes are skipped to position the stream at
* the end of the buffer. The actual number of bytes skipped is returned.
*
* @param n The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*/
public long skip(long n)
{
if (n < 0)
return 0L;
long actualSkip = Math.min(n, count - pos);
pos += actualSkip;
return actualSkip;
}
}
+209
View File
@@ -0,0 +1,209 @@
/* StringReader.java -- permits a String to be read as a character input stream
Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct
*/
/**
* This class permits a <code>String</code> to be read as a character
* input stream.
* <p>
* The mark/reset functionality in this class behaves differently than
* normal. If no mark has been set, then calling the <code>reset()</code>
* method rewinds the read pointer to the beginning of the <code>String</code>.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @date October 19, 1998.
*/
public class StringReader extends Reader
{
/* A String provided by the creator of the stream. */
private String buf;
/* Position of the next char in buf to be read. */
private int pos;
/* The currently marked position in the stream. */
private int markedPos;
/* The index in buf one greater than the last valid character. */
private int count;
/**
* Create a new <code>StringReader</code> that will read chars from the
* passed in <code>String</code>. This stream will read from the beginning
* to the end of the <code>String</code>.
*
* @param buffer The <code>String</code> this stream will read from.
*/
public StringReader(String buffer)
{
super();
buf = buffer;
count = buffer.length();
markedPos = pos = 0;
}
public void close()
{
synchronized (lock)
{
buf = null;
}
}
public void mark(int readAheadLimit) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
// readAheadLimit is ignored per Java Class Lib. book, p. 1692.
markedPos = pos;
}
}
public boolean markSupported()
{
return true;
}
public int read() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
if (pos < count)
return ((int) buf.charAt(pos++)) & 0xFFFF;
return -1;
}
}
public int read(char[] b, int off, int len) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
/* Don't need to check pos value, arraycopy will check it. */
if (off < 0 || len < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
if (pos >= count)
return -1;
int lastChar = Math.min(count, pos + len);
buf.getChars(pos, lastChar, b, off);
int numChars = lastChar - pos;
pos = lastChar;
return numChars;
}
}
/**
* This method determines if the stream is ready to be read. This class
* is always ready to read and so always returns <code>true</code>, unless
* close() has previously been called in which case an IOException is
* thrown.
*
* @return <code>true</code> to indicate that this object is ready to be read.
* @exception IOException If the stream is closed.
*/
public boolean ready() throws IOException
{
if (buf == null)
throw new IOException("Stream closed");
return true;
}
/**
* Sets the read position in the stream to the previously
* marked position or to 0 (i.e., the beginning of the stream) if the mark
* has not already been set.
*/
public void reset() throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
pos = markedPos;
}
}
/**
* This method attempts to skip the requested number of chars in the
* input stream. It does this by advancing the <code>pos</code> value by
* the specified number of chars. It this would exceed the length of the
* buffer, then only enough chars are skipped to position the stream at
* the end of the buffer. The actual number of chars skipped is returned.
*
* @param n The requested number of chars to skip
*
* @return The actual number of chars skipped.
*/
public long skip(long n) throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("Stream closed");
// Even though the var numChars is a long, in reality it can never
// be larger than an int since the result of subtracting 2 positive
// ints will always fit in an int. Since we have to return a long
// anyway, numChars might as well just be a long.
long numChars = Math.min((long) (count - pos), n < 0 ? 0L : n);
pos += numChars;
return numChars;
}
}
}
+191
View File
@@ -0,0 +1,191 @@
/* StringWriter.java -- Writes bytes to a StringBuffer
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
// Wow is this a dumb class. CharArrayWriter can do all this and
// more. I would redirect all calls to one in fact, but the javadocs say
// use a StringBuffer so I will comply.
/**
* This class writes chars to an internal <code>StringBuffer</code> that
* can then be used to retrieve a <code>String</code>.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public class StringWriter extends Writer
{
/**
* This is the default size of the buffer if the user doesn't specify it.
* @specnote The JCL Volume 1 says that 16 is the default size.
*/
private static final int DEFAULT_BUFFER_SIZE = 16;
/**
* This method closes the stream. The contents of the internal buffer
* can still be retrieved, but future writes are not guaranteed to work.
*
* @exception IOException If an error orrurs.
*/
public void close () throws IOException
{
// JCL says this does nothing. This seems to violate the Writer
// contract, in that other methods should still throw an
// IOException after a close. Still, we just follow JCL.
}
/**
* This method flushes any buffered characters to the underlying output.
* It does nothing in this class.
*/
public void flush ()
{
}
/**
* This method returns the <code>StringBuffer</code> object that this
* object is writing to. Note that this is the actual internal buffer, so
* any operations performed on it will affect this stream object.
*
* @return The <code>StringBuffer</code> object being written to
*/
public StringBuffer getBuffer ()
{
return buffer;
}
/**
* This method initializes a new <code>StringWriter</code> to write to a
* <code>StringBuffer</code> initially sized to a default size of 16
* chars.
*/
public StringWriter ()
{
this (DEFAULT_BUFFER_SIZE);
}
/**
* This method initializes a new <code>StringWriter</code> to write to a
* <code>StringBuffer</code> with the specified initial size.
*
* @param size The initial size to make the <code>StringBuffer</code>
*/
public StringWriter (int size)
{
super ();
buffer = new StringBuffer (size);
lock = buffer;
}
/**
* This method returns the contents of the internal <code>StringBuffer</code>
* as a <code>String</code>.
*
* @return A <code>String</code> representing the chars written to
* this stream.
*/
public String toString ()
{
return buffer.toString();
}
/**
* This method writes a single character to the output, storing it in
* the internal buffer.
*
* @param oneChar The <code>char</code> to write, passed as an int.
*/
public void write (int oneChar)
{
buffer.append((char) (oneChar & 0xFFFF));
}
/**
* This method writes <code>len</code> chars from the specified
* array starting at index <code>offset</code> in that array to this
* stream by appending the chars to the end of the internal buffer.
*
* @param chars The array of chars to write
* @param offset The index into the array to start writing from
* @param len The number of chars to write
*/
public void write (char[] chars, int offset, int len)
{
buffer.append(chars, offset, len);
}
/**
* This method writes the characters in the specified <code>String</code>
* to the stream by appending them to the end of the internal buffer.
*
* @param str The <code>String</code> to write to the stream.
*/
public void write (String str)
{
buffer.append(str);
}
/**
* This method writes out <code>len</code> characters of the specified
* <code>String</code> to the stream starting at character position
* <code>offset</code> into the stream. This is done by appending the
* characters to the internal buffer.
*
* @param str The <code>String</code> to write characters from
* @param offset The character position to start writing from
* @param len The number of characters to write.
*/
public void write (String str, int offset, int len)
{
// char[] tmpbuf = new char[len];
// str.getChars(offset, offset+len, tmpbuf, 0);
// buf.append(tmpbuf, 0, tmpbuf.length);
// This implementation assumes that String.substring is more
// efficient than using String.getChars and copying the data
// twice. For libgcj, this is true. For Classpath, it is not.
// FIXME.
buffer.append(str.substring(offset, offset + len));
}
/**
* This is the <code>StringBuffer</code> that we use to store bytes that
* are written.
*/
private StringBuffer buffer;
}
@@ -0,0 +1,66 @@
/* SyncFailedException.java -- a file sync failed
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* Thrown when a file synchronization fails.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @see FileDescriptor#sync()
* @since 1.1
* @status updated to 1.4
*/
public class SyncFailedException extends IOException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -2353342684412443330L;
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public SyncFailedException(String message)
{
super(message);
}
} // class SyncFailedException
@@ -0,0 +1,74 @@
/* UTFDataFormatException.java -- thrown on bad format in UTF data
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* When reading a UTF string from an input stream, this exception is thrown
* to indicate that the data read is invalid.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
* @see DataInput
* @see DataInputStream#readUTF(DataInput)
* @status updated to 1.4
*/
public class UTFDataFormatException extends IOException
{
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = 420743449228280612L;
/**
* Create a new UTFDataFormatException without a descriptive error message.
*/
public UTFDataFormatException()
{
}
/**
* Create a new UTFDataFormatException with a descriptive error message.
*
* @param message the descriptive error message
*/
public UTFDataFormatException(String message)
{
super(message);
}
} // class UTFDataFormatException
@@ -0,0 +1,73 @@
/* UnsupportedEncodingException.java -- the requested encoding isn't supported
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when the requested character encoding is
* not supported.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner (bothner@cygnus.com)
* @since 1.1
* @status updated to 1.4
*/
public class UnsupportedEncodingException extends IOException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -4274276298326136670L;
/**
* Create an exception without a descriptive error message.
*/
public UnsupportedEncodingException()
{
}
/**
* Create an exception with a descriptive error message.
*
* @param message the descriptive error message
*/
public UnsupportedEncodingException(String message)
{
super(message);
}
} // class UnsupportedEncodingException
@@ -0,0 +1,109 @@
/* WriteAbortedException.java -- wraps an exception thrown while writing
Copyright (C) 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/**
* This exception is thrown when another ObjectStreamException occurs during
* a serialization read or write. The stream is reset, and deserialized
* objects are discarded.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Eric Blake (ebb9@email.byu.edu)
* @since 1.1
* @status updated to 1.4
*/
public class WriteAbortedException extends ObjectStreamException
{
/**
* Compatible with JDK 1.1+.
*/
private static final long serialVersionUID = -3326426625597282442L;
/**
* The cause of this exception. This pre-dates the exception chaining
* of Throwable; and although you can change this field, you are wiser
* to leave it alone.
*
* @serial the exception cause
*/
public Exception detail;
/**
* Create a new WriteAbortedException with a specified message and
* cause.
*
* @param msg the message
* @param detail the cause
*/
public WriteAbortedException(String msg, Exception detail)
{
super(msg);
initCause(detail);
this.detail = detail;
}
/**
* This method returns a message indicating what went wrong, in this
* format:
* <code>super.getMessage() + (detail == null ? "" : "; " + detail)</code>.
*
* @return the chained message
*/
public String getMessage()
{
if (detail == this || detail == null)
return super.getMessage();
return super.getMessage() + "; " + detail;
}
/**
* Returns the cause of this exception. Note that this may not be the
* original cause, thanks to the <code>detail</code> field being public
* and non-final (yuck). However, to avoid violating the contract of
* Throwable.getCause(), this returns null if <code>detail == this</code>,
* as no exception can be its own cause.
*
* @return the cause
* @since 1.4
*/
public Throwable getCause()
{
return detail == this ? null : detail;
}
} // class WriteAbortedException
+192
View File
@@ -0,0 +1,192 @@
/* Writer.java -- Base class for character output streams
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.io;
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
/**
* This abstract class forms the base of the hierarchy of classes that
* write output as a stream of chars. It provides a common set of methods
* for writing chars to stream. Subclasses implement and/or extend these
* methods to write chars in a particular manner or to a particular
* destination such as a file on disk or network connection.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner (bothner@cygnus.com)
*/
public abstract class Writer
{
/**
* This is the object used to synchronize criticial code sections for
* thread safety. Subclasses should use this field instead of using
* synchronized methods or explicity synchronizations on <code>this</code>
*/
protected Object lock;
/**
* This is the default no-argument constructor for this class. This method
* will set up the class to synchronize criticial sections on itself.
*/
protected Writer()
{
lock = this;
}
/**
* This method initializes a <code>Writer</code> that will synchronize
* on the specified <code>Object</code>.
*
* @param lock The <code>Object</code> to use for synchronizing critical
* sections. Must not be null.
*/
protected Writer(Object lock)
{
if (lock == null)
throw new NullPointerException();
this.lock = lock;
}
/**
* This method forces any data that may have been buffered to be written
* to the underlying output device. Please note that the host environment
* might perform its own buffering unbeknowst to Java. In that case, a
* write made (for example, to a disk drive) might be cached in OS
* buffers instead of actually being written to disk.
*
* @exception IOException If an error occurs
*/
public abstract void flush() throws IOException;
/**
* This method closes the stream. Any internal or native resources
* associated
* with this stream are freed. Any subsequent attempt to access the stream
* might throw an exception.
* <p>
* This method in this class does nothing.
*
* @exception IOException If an error occurs
*/
public abstract void close() throws IOException;
/**
* This method writes a single char to the output stream.
*
* @param b The char to be written to the output stream, passed as an int
*
* @exception IOException If an error occurs
*/
public void write(int b) throws IOException
{
char[] buf = new char[1];
buf[0] = (char)b;
write(buf, 0, buf.length);
}
/**
* This method all the writes char from the passed array to the output
* stream. This method is equivalent to
* <code>write(buf, 0, buf.length)</code> which
* is exactly how it is implemented in this class.
*
* @param buf The array of char to write
*
* @exception IOException If an error occurs
*/
public void write(char[] buf) throws IOException
{
write(buf, 0, buf.length);
}
/**
* This method writes <code>len</code> char from the specified array
* <code>buf</code> starting at index <code>offset</code> into the array.
* <p>
* Subclasses must provide an implementation of this abstract method.
*
* @param buf The array of char to write from
* @param offset The index into the array to start writing from
* @param len The number of char to write
*
* @exception IOException If an error occurs
*/
public abstract void write(char[] buf, int offset, int len)
throws IOException;
/**
* This method writes all the characters in a <code>String</code> to the
* output.
*
* @param str The <code>String</code> whose chars are to be written.
*
* @exception IOException If an error occurs
*/
public void write(String str) throws IOException
{
write(str, 0, str.length());
}
/**
* This method writes <code>len</code> chars from the <code>String</code>
* starting at position <code>offset</code>.
*
* @param str The <code>String</code> that is to be written
* @param offset The character offset into the <code>String</code> to start
* writing from
* @param len The number of chars to write
*
* @exception IOException If an error occurs
*/
public void write(String str, int offset, int len) throws IOException
{
// FIXME - for libgcj re-write using native code to not require
// copied buffer.
char[] buf = new char[len];
str.getChars(offset, offset + len, buf, 0);
write(buf, 0, len);
}
} // class Writer
@@ -0,0 +1,100 @@
# This property file contains dependencies of classes, methods, and
# field on other methods or classes.
#
# Syntax:
#
# <used>: <needed 1> [... <needed N>]
#
# means that when <used> is included, <needed 1> (... <needed N>) must
# be included as well.
#
# <needed X> and <used> are of the form
#
# <class.methodOrField(signature)>
#
# or just
#
# <class>
#
# Within dependencies, variables can be used. A variable is defined as
# follows:
#
# {variable}: value1 value2 ... value<n>
#
# variables can be used on the right side of dependencies as follows:
#
# <used>: com.bla.blu.{variable}.Class.m()V
#
# The use of the variable will expand to <n> dependencies of the form
#
# <used>: com.bla.blu.value1.Class.m()V
# <used>: com.bla.blu.value2.Class.m()V
# ...
# <used>: com.bla.blu.value<n>.Class.m()V
#
# Variables can be redefined when building a system to select the
# required support for features like encodings, protocols, etc.
#
# Hints:
#
# - For methods and fields, the signature is mandatory. For
# specification, please see the Java Virtual Machine Specification by
# SUN. Unlike in the spec, field signatures (types) are in brackets.
#
# - Package names must be separated by '/' (and not '.'). E.g.,
# java/lang/Class (this is necessary, because the '.' is used to
# separate method or field names from classes)
#
# - In case <needed> refers to a class, only the class itself will be
# included in the resulting binary, NOT necessarily all its methods
# and fields. If you want to refer to all methods and fields, you can
# write class.* as an abbreviation.
#
# - Abbreviations for packages are also possible: my/package/* means all
# methods and fields of all classes in my/package.
#
# - A line with a trailing '\' continues in the next line.
java/io/File: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/FileDescriptor: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
java/io/FileInputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V
java/io/FileOutputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
java/io/ObjectInputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/SecurityManager.currentClassLoader()Ljava/lang/ClassLoader; \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/ObjectOutputStream: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/lang/SecurityManager.currentClassLoader()Ljava/lang/ClassLoader; \
java/lang/IllegalArgumentException.<init>(Ljava/lang/String;)V
java/io/RandomAccessFile: \
java/lang/ClassNotFoundException.<init>(Ljava/lang/String;)V \
java/lang/InternalError.<init>(Ljava/lang/String;)V \
java/io/FileNotFoundException.<init>(Ljava/lang/String;)V \
java/io/IOException.<init>(Ljava/lang/String;)V
# end of file
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<!-- package.html - describes classes in java.io package.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. -->
<html>
<head><title>GNU Classpath - java.io</title></head>
<body>
<p>Classes for manipulating character and byte streams and files.</p>
</body>
</html>