Buffer.java: Implemented.
2002-11-13 Michael Koch <konqueror@gmx.de> * java/nio/Buffer.java: Implemented. * java/nio/CharBuffer.java: New file. * java/nio/InvalidMarkException.java: New file. * java/nio/channels/DatagramChannel.java: Implemented. * java/nio/channels/ServerSocketChannel.java: Implemented. * java/nio/channels/SocketChannel.java: Implemented. * java/nio/channels/spi/AbstractChannel.java: Removed. * java/nio/channels/spi/AbstractSelectableChannel.java: Implemented. * java/nio/charset/Charset.java: Merge from Classpath. * java/nio/charset/CharsetDecoder.java: New file. * java/nio/charset/CharsetEncoder.java: New file. * java/nio/charset/CoderResult.java: New file. * Makefile.am (ordinary_java_source_files): Added new files. * Makefile.in: Regenerated. From-SVN: r59075
This commit is contained in:
parent
7b53becc10
commit
93f93f9f28
@ -1,3 +1,22 @@
|
||||
2002-11-12 Michael Koch <konqueror@gmx.de>
|
||||
|
||||
* java/nio/Buffer.java: Implemented.
|
||||
* java/nio/CharBuffer.java: New file.
|
||||
* java/nio/InvalidMarkException.java: New file.
|
||||
* java/nio/channels/DatagramChannel.java: Implemented.
|
||||
* java/nio/channels/ServerSocketChannel.java: Implemented.
|
||||
* java/nio/channels/SocketChannel.java: Implemented.
|
||||
* java/nio/channels/spi/AbstractChannel.java: Removed.
|
||||
* java/nio/channels/spi/AbstractSelectableChannel.java:
|
||||
Implemented.
|
||||
* java/nio/charset/Charset.java:
|
||||
Merge from Classpath.
|
||||
* java/nio/charset/CharsetDecoder.java: New file.
|
||||
* java/nio/charset/CharsetEncoder.java: New file.
|
||||
* java/nio/charset/CoderResult.java: New file.
|
||||
* Makefile.am (ordinary_java_source_files): Added new files.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
2002-11-11 Jesse Rosenstock <jmr@ugcs.caltech.edu>
|
||||
|
||||
* gnu/java/nio/charset/ISO_8859_1.java,
|
||||
@ -9,10 +28,7 @@
|
||||
gnu/java/nio/charset/UTF_16Encoder.java,
|
||||
gnu/java/nio/charset/UTF_16LE.java,
|
||||
gnu/java/nio/charset/UTF_8.java: New files.
|
||||
* Makefile.am ():
|
||||
Added new files.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
|
||||
2002-11-11 Michael Koch <konqueror@gmx.de>
|
||||
|
||||
* java/nio/charset/CharacterCodingException.java:
|
||||
|
@ -1871,6 +1871,15 @@ gnu/java/locale/LocaleInformation_zh_HK.java \
|
||||
gnu/java/locale/LocaleInformation_zh_SG.java \
|
||||
gnu/java/locale/LocaleInformation_zh_TW.java \
|
||||
gnu/java/math/MPN.java \
|
||||
gnu/java/nio/charset/ISO_8859_1.java \
|
||||
gnu/java/nio/charset/Provider.java \
|
||||
gnu/java/nio/charset/US_ASCII.java \
|
||||
gnu/java/nio/charset/UTF_16.java \
|
||||
gnu/java/nio/charset/UTF_16BE.java \
|
||||
gnu/java/nio/charset/UTF_16Decoder.java \
|
||||
gnu/java/nio/charset/UTF_16Encoder.java \
|
||||
gnu/java/nio/charset/UTF_16LE.java \
|
||||
gnu/java/nio/charset/UTF_8.java \
|
||||
gnu/java/security/der/DEREncodingException.java \
|
||||
gnu/java/security/provider/DERReader.java \
|
||||
gnu/java/security/provider/DERWriter.java \
|
||||
@ -1963,6 +1972,8 @@ java/nio/BufferOverflowException.java \
|
||||
java/nio/BufferUnderflowException.java \
|
||||
java/nio/ByteBuffer.java \
|
||||
java/nio/ByteOrder.java \
|
||||
java/nio/CharBuffer.java \
|
||||
java/nio/InvalidMarkException.java \
|
||||
java/nio/MappedByteBuffer.java \
|
||||
java/nio/channels/AlreadyConnectedException.java \
|
||||
java/nio/channels/ByteChannel.java \
|
||||
@ -1982,14 +1993,16 @@ java/nio/channels/ServerSocketChannel.java \
|
||||
java/nio/channels/SocketChannel.java \
|
||||
java/nio/channels/WritableByteChannel.java \
|
||||
java/nio/channels/spi/AbstractSelectableChannel.java \
|
||||
java/nio/channels/spi/AbstractChannel.java \
|
||||
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
||||
java/nio/channels/spi/AbstractSelectionKey.java \
|
||||
java/nio/channels/spi/AbstractSelector.java \
|
||||
java/nio/channels/spi/SelectorProvider.java \
|
||||
java/nio/charset/Charset.java \
|
||||
java/nio/charset/CharacterCodingException.java \
|
||||
java/nio/charset/CharsetDecoder.java \
|
||||
java/nio/charset/CharsetEncoder.java \
|
||||
java/nio/charset/CoderMalfunctionError.java \
|
||||
java/nio/charset/CoderResult.java \
|
||||
java/nio/charset/CodingErrorAction.java \
|
||||
java/nio/charset/IllegalCharsetNameException.java \
|
||||
java/nio/charset/MalformedInputException.java \
|
||||
|
@ -1621,6 +1621,15 @@ gnu/java/locale/LocaleInformation_zh_HK.java \
|
||||
gnu/java/locale/LocaleInformation_zh_SG.java \
|
||||
gnu/java/locale/LocaleInformation_zh_TW.java \
|
||||
gnu/java/math/MPN.java \
|
||||
gnu/java/nio/charset/ISO_8859_1.java \
|
||||
gnu/java/nio/charset/Provider.java \
|
||||
gnu/java/nio/charset/US_ASCII.java \
|
||||
gnu/java/nio/charset/UTF_16.java \
|
||||
gnu/java/nio/charset/UTF_16BE.java \
|
||||
gnu/java/nio/charset/UTF_16Decoder.java \
|
||||
gnu/java/nio/charset/UTF_16Encoder.java \
|
||||
gnu/java/nio/charset/UTF_16LE.java \
|
||||
gnu/java/nio/charset/UTF_8.java \
|
||||
gnu/java/security/der/DEREncodingException.java \
|
||||
gnu/java/security/provider/DERReader.java \
|
||||
gnu/java/security/provider/DERWriter.java \
|
||||
@ -1713,6 +1722,8 @@ java/nio/BufferOverflowException.java \
|
||||
java/nio/BufferUnderflowException.java \
|
||||
java/nio/ByteBuffer.java \
|
||||
java/nio/ByteOrder.java \
|
||||
java/nio/CharBuffer.java \
|
||||
java/nio/InvalidMarkException.java \
|
||||
java/nio/MappedByteBuffer.java \
|
||||
java/nio/channels/AlreadyConnectedException.java \
|
||||
java/nio/channels/ByteChannel.java \
|
||||
@ -1732,14 +1743,16 @@ java/nio/channels/ServerSocketChannel.java \
|
||||
java/nio/channels/SocketChannel.java \
|
||||
java/nio/channels/WritableByteChannel.java \
|
||||
java/nio/channels/spi/AbstractSelectableChannel.java \
|
||||
java/nio/channels/spi/AbstractChannel.java \
|
||||
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
||||
java/nio/channels/spi/AbstractSelectionKey.java \
|
||||
java/nio/channels/spi/AbstractSelector.java \
|
||||
java/nio/channels/spi/SelectorProvider.java \
|
||||
java/nio/charset/Charset.java \
|
||||
java/nio/charset/CharacterCodingException.java \
|
||||
java/nio/charset/CharsetDecoder.java \
|
||||
java/nio/charset/CharsetEncoder.java \
|
||||
java/nio/charset/CoderMalfunctionError.java \
|
||||
java/nio/charset/CoderResult.java \
|
||||
java/nio/charset/CodingErrorAction.java \
|
||||
java/nio/charset/IllegalCharsetNameException.java \
|
||||
java/nio/charset/MalformedInputException.java \
|
||||
@ -2514,7 +2527,15 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/gnu/java/locale/LocaleInformation_zh_HK.P \
|
||||
.deps/gnu/java/locale/LocaleInformation_zh_SG.P \
|
||||
.deps/gnu/java/locale/LocaleInformation_zh_TW.P \
|
||||
.deps/gnu/java/math/MPN.P \
|
||||
.deps/gnu/java/math/MPN.P .deps/gnu/java/nio/charset/ISO_8859_1.P \
|
||||
.deps/gnu/java/nio/charset/Provider.P \
|
||||
.deps/gnu/java/nio/charset/US_ASCII.P \
|
||||
.deps/gnu/java/nio/charset/UTF_16.P \
|
||||
.deps/gnu/java/nio/charset/UTF_16BE.P \
|
||||
.deps/gnu/java/nio/charset/UTF_16Decoder.P \
|
||||
.deps/gnu/java/nio/charset/UTF_16Encoder.P \
|
||||
.deps/gnu/java/nio/charset/UTF_16LE.P \
|
||||
.deps/gnu/java/nio/charset/UTF_8.P \
|
||||
.deps/gnu/java/rmi/RMIMarshalledObjectInputStream.P \
|
||||
.deps/gnu/java/rmi/RMIMarshalledObjectOutputStream.P \
|
||||
.deps/gnu/java/rmi/dgc/DGCImpl.P .deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \
|
||||
@ -2981,7 +3002,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/java/net/natPlainSocketImpl.P .deps/java/nio/Buffer.P \
|
||||
.deps/java/nio/BufferOverflowException.P \
|
||||
.deps/java/nio/BufferUnderflowException.P .deps/java/nio/ByteBuffer.P \
|
||||
.deps/java/nio/ByteOrder.P .deps/java/nio/MappedByteBuffer.P \
|
||||
.deps/java/nio/ByteOrder.P .deps/java/nio/CharBuffer.P \
|
||||
.deps/java/nio/InvalidMarkException.P .deps/java/nio/MappedByteBuffer.P \
|
||||
.deps/java/nio/channels/AlreadyConnectedException.P \
|
||||
.deps/java/nio/channels/ByteChannel.P .deps/java/nio/channels/Channel.P \
|
||||
.deps/java/nio/channels/ClosedChannelException.P \
|
||||
@ -2998,7 +3020,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/java/nio/channels/ServerSocketChannel.P \
|
||||
.deps/java/nio/channels/SocketChannel.P \
|
||||
.deps/java/nio/channels/WritableByteChannel.P \
|
||||
.deps/java/nio/channels/spi/AbstractChannel.P \
|
||||
.deps/java/nio/channels/spi/AbstractInterruptibleChannel.P \
|
||||
.deps/java/nio/channels/spi/AbstractSelectableChannel.P \
|
||||
.deps/java/nio/channels/spi/AbstractSelectionKey.P \
|
||||
@ -3006,7 +3027,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/java/nio/channels/spi/SelectorProvider.P \
|
||||
.deps/java/nio/charset/CharacterCodingException.P \
|
||||
.deps/java/nio/charset/Charset.P \
|
||||
.deps/java/nio/charset/CharsetDecoder.P \
|
||||
.deps/java/nio/charset/CharsetEncoder.P \
|
||||
.deps/java/nio/charset/CoderMalfunctionError.P \
|
||||
.deps/java/nio/charset/CoderResult.P \
|
||||
.deps/java/nio/charset/CodingErrorAction.P \
|
||||
.deps/java/nio/charset/IllegalCharsetNameException.P \
|
||||
.deps/java/nio/charset/MalformedInputException.P \
|
||||
|
@ -39,4 +39,155 @@ package java.nio;
|
||||
|
||||
public abstract class Buffer
|
||||
{
|
||||
int cap = 0;
|
||||
int limit = 0;
|
||||
int pos = 0;
|
||||
int mark = -1;
|
||||
|
||||
/**
|
||||
* Retrieves the capacity of the buffer.
|
||||
*/
|
||||
public final int capacity ()
|
||||
{
|
||||
return cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the buffer.
|
||||
*/
|
||||
public final Buffer clear ()
|
||||
{
|
||||
limit = cap;
|
||||
pos = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the buffer.
|
||||
*/
|
||||
public final Buffer flip ()
|
||||
{
|
||||
limit = pos;
|
||||
pos = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the buffer has remaining data to read or not.
|
||||
*/
|
||||
public final boolean hasRemaining ()
|
||||
{
|
||||
return limit > pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether this buffer is read only or not.
|
||||
*/
|
||||
public abstract boolean isReadOnly ();
|
||||
|
||||
/**
|
||||
* Retrieves the current limit of the buffer.
|
||||
*/
|
||||
public final int limit ()
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this buffer's limit.
|
||||
*
|
||||
* @param newLimit The new limit value; must be non-negative and no larger
|
||||
* than this buffer's capacity.
|
||||
*
|
||||
* @exception IllegalArgumentException If the preconditions on newLimit
|
||||
* do not hold.
|
||||
*/
|
||||
public final Buffer limit (int newLimit)
|
||||
{
|
||||
if ((newLimit < 0) || (newLimit > cap))
|
||||
throw new IllegalArgumentException ();
|
||||
|
||||
if (newLimit <= mark)
|
||||
mark = -1;
|
||||
|
||||
if (pos > newLimit)
|
||||
pos = newLimit - 1;
|
||||
|
||||
limit = newLimit;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this buffer's mark at its position.
|
||||
*/
|
||||
public final Buffer mark ()
|
||||
{
|
||||
mark = pos;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current position of this buffer.
|
||||
*/
|
||||
public final int position ()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this buffer's position. If the mark is defined and larger than the
|
||||
* new position then it is discarded.
|
||||
*
|
||||
* @param newPosition The new position value; must be non-negative and no
|
||||
* larger than the current limit.
|
||||
*
|
||||
* @exception IllegalArgumentException If the preconditions on newPosition
|
||||
* do not hold
|
||||
*/
|
||||
public final Buffer position (int newPosition)
|
||||
{
|
||||
if ((newPosition < 0) || (newPosition > limit))
|
||||
throw new IllegalArgumentException ();
|
||||
|
||||
if (newPosition <= mark)
|
||||
mark = -1;
|
||||
|
||||
pos = newPosition;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements between the current position and the limit.
|
||||
*/
|
||||
public final int remaining()
|
||||
{
|
||||
return limit - pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this buffer's position to the previously-marked position.
|
||||
*
|
||||
* @exception InvalidMarkException If the mark has not been set.
|
||||
*/
|
||||
public final Buffer reset()
|
||||
{
|
||||
if (mark == -1)
|
||||
throw new InvalidMarkException ();
|
||||
|
||||
pos = mark;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds this buffer. The position is set to zero and the mark
|
||||
* is discarded.
|
||||
*/
|
||||
public final Buffer rewind()
|
||||
{
|
||||
pos = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
291
libjava/java/nio/CharBuffer.java
Normal file
291
libjava/java/nio/CharBuffer.java
Normal file
@ -0,0 +1,291 @@
|
||||
/* CharBuffer.java --
|
||||
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., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 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.nio;
|
||||
|
||||
public abstract class CharBuffer extends Buffer
|
||||
{
|
||||
private ByteOrder endian = ByteOrder.BIG_ENDIAN;
|
||||
|
||||
protected char [] backing_buffer;
|
||||
|
||||
public static CharBuffer allocate (int capacity)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException If the preconditions on the offset
|
||||
* and length parameters do not hold
|
||||
*/
|
||||
final public static CharBuffer wrap (char[] array, int offset, int length)
|
||||
{
|
||||
if ((offset < 0) ||
|
||||
(offset > array.length) ||
|
||||
(length < 0) ||
|
||||
(length > (array.length - offset)))
|
||||
throw new IndexOutOfBoundsException ();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
final public static CharBuffer wrap (CharSequence a)
|
||||
{
|
||||
return wrap (a, 0, a.length ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException If the preconditions on the offset
|
||||
* and length parameters do not hold
|
||||
*/
|
||||
final public static CharBuffer wrap (CharSequence a, int offset, int length)
|
||||
{
|
||||
char [] buffer = new char [length];
|
||||
|
||||
for (int i = offset; i < length; i++)
|
||||
{
|
||||
buffer [i] = a.charAt (i);
|
||||
}
|
||||
|
||||
return wrap (buffer, 0, length);
|
||||
}
|
||||
|
||||
final public static CharBuffer wrap (char[] array)
|
||||
{
|
||||
return wrap (array, 0, array.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferUnderflowException FIXME
|
||||
* @exception IndexOutOfBoundsException If the preconditions on the offset
|
||||
* and length parameters do not hold
|
||||
*/
|
||||
final public CharBuffer get (char[] dst, int offset, int length)
|
||||
{
|
||||
for (int i = offset; i < offset + length; i++)
|
||||
{
|
||||
dst [i] = get ();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferUnderflowException FIXME
|
||||
*/
|
||||
final public CharBuffer get (char[] dst)
|
||||
{
|
||||
return get (dst, 0, dst.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception IllegalArgumentException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
final public CharBuffer put (CharBuffer src)
|
||||
{
|
||||
while (src.hasRemaining ())
|
||||
put (src.get ());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception IndexOutOfBoundsException If the preconditions on the offset
|
||||
* and length parameters do not hold
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
final public CharBuffer put (char[] src, int offset, int length)
|
||||
{
|
||||
for (int i = offset; i < offset + length; i++)
|
||||
put (src [i]);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public final CharBuffer put (char[] src)
|
||||
{
|
||||
return put (src, 0, src.length);
|
||||
}
|
||||
|
||||
public final boolean hasArray ()
|
||||
{
|
||||
return backing_buffer != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
* @exception UnsupportedOperationException FIXME
|
||||
*/
|
||||
public final char[] array ()
|
||||
{
|
||||
return backing_buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
* @exception UnsupportedOperationException FIXME
|
||||
*/
|
||||
public final int arrayOffset ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int hashCode ()
|
||||
{
|
||||
return super.hashCode ();
|
||||
}
|
||||
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (obj instanceof CharBuffer)
|
||||
return compareTo (obj) == 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception ClassCastException FIXME
|
||||
*/
|
||||
public int compareTo(Object obj)
|
||||
{
|
||||
CharBuffer a = (CharBuffer) obj;
|
||||
|
||||
if (a.remaining () != remaining ())
|
||||
return 1;
|
||||
|
||||
if (! hasArray () || ! a.hasArray ())
|
||||
return 1;
|
||||
|
||||
int r = remaining ();
|
||||
int i1 = pos;
|
||||
int i2 = a.pos;
|
||||
|
||||
for (int i = 0; i < r; i++)
|
||||
{
|
||||
int t = (int) (get (i1)- a.get (i2));
|
||||
|
||||
if (t != 0)
|
||||
return (int) t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferUnderflowException FIXME
|
||||
*/
|
||||
public abstract char get ();
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public abstract CharBuffer put (char b);
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException FIXME
|
||||
*/
|
||||
public abstract char get (int index);
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public abstract CharBuffer put (int index, char b);
|
||||
|
||||
/**
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public abstract CharBuffer compact ();
|
||||
|
||||
public abstract boolean isDirect ();
|
||||
|
||||
public abstract CharBuffer slice ();
|
||||
|
||||
public abstract CharBuffer duplicate ();
|
||||
|
||||
public abstract CharBuffer asReadOnlyBuffer ();
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public final int length ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public abstract ByteOrder order ();
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException FIXME
|
||||
*/
|
||||
public abstract CharSequence subSequence (int start, int length);
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception IndexOutOfBoundsException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public CharBuffer put (String str, int start, int length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception BufferOverflowException FIXME
|
||||
* @exception ReadOnlyBufferException FIXME
|
||||
*/
|
||||
public final CharBuffer put (String str)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception IndexOutOfBoundsException FIXME
|
||||
*/
|
||||
public final char charAt (int index)
|
||||
{
|
||||
return ' ';
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* AbstractChannel.java --
|
||||
/* InvalidMarkException.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
@ -35,23 +35,18 @@ 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.nio.channels.spi;
|
||||
package java.nio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channel;
|
||||
|
||||
public abstract class AbstractChannel implements Channel
|
||||
/**
|
||||
* @author Michael Koch
|
||||
* @since 1.4
|
||||
*/
|
||||
public class InvalidMarkException extends IllegalStateException
|
||||
{
|
||||
boolean opened;
|
||||
|
||||
public boolean isOpen()
|
||||
/**
|
||||
* Creates the exception
|
||||
*/
|
||||
public InvalidMarkException ()
|
||||
{
|
||||
return opened;
|
||||
}
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (! isOpen())
|
||||
return;
|
||||
}
|
||||
}
|
@ -37,14 +37,117 @@ exception statement from your version. */
|
||||
|
||||
package java.nio.channels;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.spi.AbstractSelectableChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
|
||||
/**
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class DatagramChannel
|
||||
extends AbstractSelectableChannel
|
||||
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel
|
||||
{
|
||||
public DatagramChannel (SelectorProvider provider)
|
||||
/**
|
||||
* Initializes the channel.
|
||||
*/
|
||||
protected DatagramChannel (SelectorProvider provider)
|
||||
{
|
||||
super (provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a datagram channel.
|
||||
*/
|
||||
public static DatagramChannel open () throws IOException
|
||||
{
|
||||
return SelectorProvider.provider ().openDatagramChannel ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from this channel.
|
||||
*/
|
||||
public final long read (ByteBuffer[] dsts) throws IOException
|
||||
{
|
||||
long b = 0;
|
||||
|
||||
for (int i = 0; i < dsts.length; i++)
|
||||
b += read (dsts[i]);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to this channel.
|
||||
*/
|
||||
public final long write (ByteBuffer[] srcs)
|
||||
{
|
||||
long b = 0;
|
||||
|
||||
for (int i = 0;i < srcs.length; i++)
|
||||
b += write (srcs[i]);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects this channel's socket.
|
||||
*/
|
||||
public abstract DatagramChannel connect (SocketAddress remote);
|
||||
|
||||
/**
|
||||
* Disonnects this channel's socket.
|
||||
*/
|
||||
public abstract DatagramChannel disconnect ();
|
||||
|
||||
/**
|
||||
* Tells whether or not this channel's socket is connected.
|
||||
*/
|
||||
public abstract boolean isConnected ();
|
||||
|
||||
/**
|
||||
* Reads data from this channel.
|
||||
*/
|
||||
public abstract int read (ByteBuffer dst);
|
||||
|
||||
/**
|
||||
* Reads data from this channel.
|
||||
*/
|
||||
public abstract long read (ByteBuffer[] dsts, int offset, int length);
|
||||
|
||||
/**
|
||||
* Receives a datagram via this channel.
|
||||
*/
|
||||
public abstract SocketAddress receive (ByteBuffer dst);
|
||||
|
||||
/**
|
||||
* Sends a datagram via this channel.
|
||||
*/
|
||||
public abstract int send (ByteBuffer src, SocketAddress target);
|
||||
|
||||
/**
|
||||
* Retrieves the channel's socket.
|
||||
*/
|
||||
public abstract DatagramSocket socket ();
|
||||
|
||||
/**
|
||||
* Writes data to this channel.
|
||||
*/
|
||||
public abstract int write (ByteBuffer src);
|
||||
|
||||
/**
|
||||
* Writes data to this channel.
|
||||
*/
|
||||
public abstract long write (ByteBuffer[] srcs, int offset, int length);
|
||||
|
||||
/**
|
||||
* Retrieves the valid operations for this channel.
|
||||
*/
|
||||
public final int validOps ()
|
||||
{
|
||||
return SelectionKey.OP_READ | SelectionKey.OP_WRITE;
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,49 @@ package java.nio.channels;
|
||||
|
||||
import java.nio.channels.spi.AbstractSelectableChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
/**
|
||||
* @author Michael Koch
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class ServerSocketChannel
|
||||
extends AbstractSelectableChannel
|
||||
{
|
||||
/**
|
||||
* Initializes this channel.
|
||||
*/
|
||||
public ServerSocketChannel (SelectorProvider provider)
|
||||
{
|
||||
super (provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a connection made to this channel's socket.
|
||||
*/
|
||||
public abstract SocketChannel accept ();
|
||||
|
||||
/**
|
||||
* Retrieves the channels socket.
|
||||
*/
|
||||
public abstract ServerSocket socket ();
|
||||
|
||||
/**
|
||||
* Opens a server socker channel.
|
||||
*/
|
||||
public static ServerSocketChannel open () throws IOException
|
||||
{
|
||||
return SelectorProvider.provider ().openServerSocketChannel ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the valid operations for this channel.
|
||||
*/
|
||||
public final int validOps ()
|
||||
{
|
||||
return SelectionKey.OP_ACCEPT;
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,127 @@ package java.nio.channels;
|
||||
|
||||
import java.nio.channels.spi.AbstractSelectableChannel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
public abstract class SocketChannel
|
||||
extends AbstractSelectableChannel
|
||||
/**
|
||||
* @author Michael Koch
|
||||
* @since 1.4
|
||||
*/
|
||||
abstract public class SocketChannel extends AbstractSelectableChannel
|
||||
{
|
||||
public SocketChannel (SelectorProvider provider)
|
||||
/**
|
||||
* Initializes this socket.
|
||||
*/
|
||||
protected SocketChannel (SelectorProvider provider)
|
||||
{
|
||||
super (provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a socket channel.
|
||||
*/
|
||||
public static SocketChannel open () throws IOException
|
||||
{
|
||||
return SelectorProvider.provider ().openSocketChannel ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a channel and connects it to a remote address.
|
||||
*/
|
||||
public static SocketChannel open (SocketAddress remote) throws IOException
|
||||
{
|
||||
SocketChannel ch = open ();
|
||||
|
||||
if (ch.connect (remote))
|
||||
{
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the channel.
|
||||
*/
|
||||
public final long read (ByteBuffer[] dsts)
|
||||
{
|
||||
long b = 0;
|
||||
|
||||
for (int i = 0; i < dsts.length; i++)
|
||||
{
|
||||
b += read (dsts [i]);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to the channel.
|
||||
*/
|
||||
public final long write (ByteBuffer[] dsts)
|
||||
{
|
||||
long b = 0;
|
||||
|
||||
for (int i= 0; i < dsts.length; i++)
|
||||
{
|
||||
b += write (dsts [i]);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the valid operations for this channel.
|
||||
*/
|
||||
public final int validOps ()
|
||||
{
|
||||
return SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the channel.
|
||||
*/
|
||||
public abstract int read (ByteBuffer dst);
|
||||
|
||||
/**
|
||||
* Connects the channel's socket to the remote address.
|
||||
*/
|
||||
public abstract boolean connect (SocketAddress remote) throws IOException;
|
||||
|
||||
/**
|
||||
* Finishes the process of connecting a socket channel.
|
||||
*/
|
||||
public abstract boolean finishConnect ();
|
||||
|
||||
/**
|
||||
* Tells whether or not the channel's socket is connected.
|
||||
*/
|
||||
public abstract boolean isConnected ();
|
||||
|
||||
/**
|
||||
* Tells whether or not a connection operation is in progress on this channel.
|
||||
*/
|
||||
public abstract boolean isConnectionPending ();
|
||||
|
||||
/**
|
||||
* Reads data from the channel.
|
||||
*/
|
||||
public abstract long read (ByteBuffer[] dsts, int offset, int length);
|
||||
|
||||
/**
|
||||
* Retrieves the channel's socket.
|
||||
*/
|
||||
public abstract Socket socket ();
|
||||
|
||||
/**
|
||||
* Writes data to the channel.
|
||||
*/
|
||||
public abstract int write (ByteBuffer src);
|
||||
|
||||
/**
|
||||
* Writes data to the channel.
|
||||
*/
|
||||
public abstract long write (ByteBuffer[] srcs, int offset, int length);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* AbstractSelectableChannel.java --
|
||||
/* AbstractSelectableChannel.java
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
@ -37,18 +37,171 @@ exception statement from your version. */
|
||||
|
||||
package java.nio.channels.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public abstract class AbstractSelectableChannel
|
||||
extends SelectableChannel
|
||||
public abstract class AbstractSelectableChannel extends SelectableChannel
|
||||
{
|
||||
int registered;
|
||||
boolean blocking = true;
|
||||
Object LOCK = new Object ();
|
||||
SelectorProvider provider;
|
||||
List keys;
|
||||
|
||||
/**
|
||||
* Initializes the channel
|
||||
*/
|
||||
protected AbstractSelectableChannel (SelectorProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the object upon which the configureBlocking and register
|
||||
* methods synchronize.
|
||||
*/
|
||||
public final Object blockingLock ()
|
||||
{
|
||||
return LOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts this channel's blocking mode.
|
||||
*/
|
||||
public final SelectableChannel configureBlocking (boolean block)
|
||||
{
|
||||
synchronized (LOCK)
|
||||
{
|
||||
blocking = true;
|
||||
implConfigureBlocking (block);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this channel.
|
||||
*/
|
||||
protected final void implCloseChannel ()
|
||||
{
|
||||
implCloseSelectableChannel ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this selectable channel.
|
||||
*/
|
||||
protected abstract void implCloseSelectableChannel ();
|
||||
|
||||
/**
|
||||
* Adjusts this channel's blocking mode.
|
||||
*/
|
||||
protected abstract void implConfigureBlocking (boolean block);
|
||||
|
||||
/**
|
||||
* Tells whether or not every I/O operation on this channel will block
|
||||
* until it completes.
|
||||
*/
|
||||
public final boolean isBlocking()
|
||||
{
|
||||
return true;
|
||||
return blocking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether or not this channel is currently registered with
|
||||
* any selectors.
|
||||
*/
|
||||
public final boolean isRegistered()
|
||||
{
|
||||
return registered > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the key representing the channel's registration with the
|
||||
* given selector.
|
||||
*/
|
||||
public final SelectionKey keyFor(Selector selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
return register (selector, 0, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider that created this channel.
|
||||
*/
|
||||
public final SelectorProvider provider ()
|
||||
{
|
||||
return provider;
|
||||
}
|
||||
|
||||
private SelectionKey locate (Selector selector)
|
||||
{
|
||||
if (keys == null)
|
||||
return null;
|
||||
|
||||
SelectionKey k = null;
|
||||
ListIterator it = keys.listIterator ();
|
||||
|
||||
while (it.hasNext ())
|
||||
{
|
||||
k = (SelectionKey) it.next ();
|
||||
if (k.selector () == selector)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
private void add (SelectionKey key)
|
||||
{
|
||||
if (keys == null)
|
||||
keys = new LinkedList ();
|
||||
|
||||
keys.add (key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this channel with the given selector, returning a selection key.
|
||||
*/
|
||||
public final SelectionKey register (Selector selin, int ops, Object att)
|
||||
throws ClosedChannelException
|
||||
{
|
||||
if (!isOpen ())
|
||||
throw new ClosedChannelException();
|
||||
|
||||
SelectionKey k = null;
|
||||
AbstractSelector selector = (AbstractSelector) selin;
|
||||
|
||||
synchronized (LOCK)
|
||||
{
|
||||
k = locate (selector);
|
||||
|
||||
if (k != null)
|
||||
{
|
||||
k.attach (att);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = selector.register (this, ops, att);
|
||||
|
||||
if (k != null)
|
||||
add (k);
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,54 +37,215 @@ exception statement from your version. */
|
||||
|
||||
package java.nio.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.spi.CharsetProvider;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import gnu.java.nio.charset.Provider;
|
||||
|
||||
import java.nio.*;
|
||||
|
||||
public class Charset
|
||||
{
|
||||
public static Charset forName(String name)
|
||||
{
|
||||
return new Charset();
|
||||
}
|
||||
|
||||
/*
|
||||
public CharsetDecoder newDecoder()
|
||||
{
|
||||
return new CharsetDecoder(this,2,2)
|
||||
{
|
||||
protected CoderResult decodeLoop(ByteBuffer in,
|
||||
CharBuffer out)
|
||||
{
|
||||
while (in.hasRemaining())
|
||||
{
|
||||
char a = (char) in.get();
|
||||
out.put(a);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder()
|
||||
{
|
||||
return new CharsetEncoder(this,2,2)
|
||||
{
|
||||
protected CoderResult encodeLoop(CharBuffer in,
|
||||
ByteBuffer out)
|
||||
{
|
||||
//System.out.println("in encode loop:"+in.hasRemaining());
|
||||
|
||||
while (in.hasRemaining())
|
||||
{
|
||||
char a = in.get();
|
||||
out.put((byte)a);
|
||||
|
||||
//int len = out.position();
|
||||
//System.out.println("pos="+len + ","+a);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @author Jesse Rosenstock
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class Charset implements Comparable
|
||||
{
|
||||
private final String canonicalName;
|
||||
private final String[] aliases;
|
||||
|
||||
protected Charset (String canonicalName, String[] aliases)
|
||||
{
|
||||
checkName (canonicalName);
|
||||
if (aliases != null)
|
||||
{
|
||||
int n = aliases.length;
|
||||
for (int i = 0; i < n; ++i)
|
||||
checkName (aliases[i]);
|
||||
}
|
||||
|
||||
this.canonicalName = canonicalName;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalCharsetNameException if the name is illegal
|
||||
*/
|
||||
private static void checkName (String name)
|
||||
{
|
||||
int n = name.length ();
|
||||
|
||||
if (n == 0)
|
||||
throw new IllegalCharsetNameException (name);
|
||||
|
||||
char ch = name.charAt (0);
|
||||
if (!(('A' <= ch && ch <= 'Z')
|
||||
|| ('a' <= ch && ch <= 'z')
|
||||
|| ('0' <= ch && ch <= '9')))
|
||||
throw new IllegalCharsetNameException (name);
|
||||
|
||||
for (int i = 1; i < n; ++i)
|
||||
{
|
||||
ch = name.charAt (i);
|
||||
if (!(('A' <= ch && ch <= 'Z')
|
||||
|| ('a' <= ch && ch <= 'z')
|
||||
|| ('0' <= ch && ch <= '9')
|
||||
|| ch == '-' || ch == '.' || ch == ':' || ch == '_'))
|
||||
throw new IllegalCharsetNameException (name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSupported (String charsetName)
|
||||
{
|
||||
return charsetForName (charsetName) != null;
|
||||
}
|
||||
|
||||
public static Charset forName (String charsetName)
|
||||
{
|
||||
Charset cs = charsetForName (charsetName);
|
||||
if (cs == null)
|
||||
throw new UnsupportedCharsetException (charsetName);
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a charset for the given charset name.
|
||||
*
|
||||
* @return A charset object for the charset with the specified name, or
|
||||
* <code>null</code> if no such charset exists.
|
||||
*
|
||||
* @throws IllegalCharsetNameException if the name is illegal
|
||||
*/
|
||||
private static Charset charsetForName (String charsetName)
|
||||
{
|
||||
checkName (charsetName);
|
||||
return provider ().charsetForName (charsetName);
|
||||
}
|
||||
|
||||
public static SortedMap availableCharsets ()
|
||||
{
|
||||
TreeMap charsets = new TreeMap (String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (Iterator i = provider ().charsets (); i.hasNext (); )
|
||||
{
|
||||
Charset cs = (Charset) i.next ();
|
||||
charsets.put (cs.name (), cs);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSortedMap (charsets);
|
||||
}
|
||||
|
||||
// XXX: we need to support multiple providers, reading them from
|
||||
// java.nio.charset.spi.CharsetProvider in the resource directory
|
||||
// META-INF/services
|
||||
private static final CharsetProvider provider ()
|
||||
{
|
||||
return Provider.provider ();
|
||||
}
|
||||
|
||||
public final String name ()
|
||||
{
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
public final Set aliases ()
|
||||
{
|
||||
if (aliases == null)
|
||||
return Collections.EMPTY_SET;
|
||||
|
||||
// should we cache the aliasSet instead?
|
||||
int n = aliases.length;
|
||||
HashSet aliasSet = new HashSet (n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
aliasSet.add (aliases[i]);
|
||||
return Collections.unmodifiableSet (aliasSet);
|
||||
}
|
||||
|
||||
public String displayName ()
|
||||
{
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
public String displayName (Locale locale)
|
||||
{
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
public final boolean isRegistered (String name)
|
||||
{
|
||||
return !name.startsWith ("x-") && !name.startsWith ("X-");
|
||||
}
|
||||
|
||||
public abstract boolean contains (Charset cs);
|
||||
|
||||
public abstract CharsetDecoder newDecoder ();
|
||||
|
||||
public abstract CharsetEncoder newEncoder ();
|
||||
|
||||
public boolean canEncode ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public final ByteBuffer encode (CharBuffer cb)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: cache encoders between sucessive invocations
|
||||
return newEncoder ().onMalformedInput (CodingErrorAction.REPLACE)
|
||||
.onUnmappableCharacter (CodingErrorAction.REPLACE)
|
||||
.encode (cb);
|
||||
}
|
||||
catch (CharacterCodingException e)
|
||||
{
|
||||
throw new AssertionError (e);
|
||||
}
|
||||
}
|
||||
|
||||
public final ByteBuffer encode (String str)
|
||||
{
|
||||
return encode (CharBuffer.wrap (str));
|
||||
}
|
||||
|
||||
public CharBuffer decode (ByteBuffer bb)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: cache encoders between sucessive invocations
|
||||
return newDecoder ().onMalformedInput (CodingErrorAction.REPLACE)
|
||||
.onUnmappableCharacter (CodingErrorAction.REPLACE)
|
||||
.decode (bb);
|
||||
}
|
||||
catch (CharacterCodingException e)
|
||||
{
|
||||
throw new AssertionError (e);
|
||||
}
|
||||
}
|
||||
|
||||
public final int compareTo (Object ob)
|
||||
{
|
||||
return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
|
||||
}
|
||||
|
||||
public final int hashCode ()
|
||||
{
|
||||
return canonicalName.hashCode ();
|
||||
}
|
||||
|
||||
public final boolean equals (Object ob)
|
||||
{
|
||||
if (ob instanceof Charset)
|
||||
return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public final String toString ()
|
||||
{
|
||||
return canonicalName;
|
||||
}
|
||||
}
|
||||
|
312
libjava/java/nio/charset/CharsetDecoder.java
Normal file
312
libjava/java/nio/charset/CharsetDecoder.java
Normal file
@ -0,0 +1,312 @@
|
||||
/* CharsetDecoder.java --
|
||||
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., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 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.nio.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
/**
|
||||
* @author Jesse Rosenstock
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class CharsetDecoder
|
||||
{
|
||||
private static final int STATE_RESET = 0;
|
||||
private static final int STATE_CODING = 1;
|
||||
private static final int STATE_END = 2;
|
||||
private static final int STATE_FLUSHED = 3;
|
||||
|
||||
private static final String DEFAULT_REPLACEMENT = "\uFFFD";
|
||||
|
||||
private final Charset charset;
|
||||
private final float averageCharsPerByte;
|
||||
private final float maxCharsPerByte;
|
||||
private String replacement;
|
||||
|
||||
private int state = STATE_RESET;
|
||||
|
||||
private CodingErrorAction malformedInputAction
|
||||
= CodingErrorAction.REPORT;
|
||||
private CodingErrorAction unmappableCharacterAction
|
||||
= CodingErrorAction.REPORT;
|
||||
|
||||
private CharsetDecoder (Charset cs, float averageCharsPerByte,
|
||||
float maxCharsPerByte, String replacement)
|
||||
{
|
||||
if (averageCharsPerByte <= 0.0f)
|
||||
throw new IllegalArgumentException ("Non-positive averageCharsPerByte");
|
||||
if (maxCharsPerByte <= 0.0f)
|
||||
throw new IllegalArgumentException ("Non-positive maxCharsPerByte");
|
||||
|
||||
this.charset = cs;
|
||||
this.averageCharsPerByte
|
||||
= averageCharsPerByte;
|
||||
this.maxCharsPerByte
|
||||
= maxCharsPerByte;
|
||||
this.replacement = replacement;
|
||||
implReplaceWith (replacement);
|
||||
}
|
||||
|
||||
protected CharsetDecoder (Charset cs, float averageCharsPerByte,
|
||||
float maxCharsPerByte)
|
||||
{
|
||||
this (cs, averageCharsPerByte, maxCharsPerByte, DEFAULT_REPLACEMENT);
|
||||
}
|
||||
|
||||
public final float averageCharsPerByte ()
|
||||
{
|
||||
return averageCharsPerByte;
|
||||
}
|
||||
|
||||
public final Charset charset ()
|
||||
{
|
||||
return charset;
|
||||
}
|
||||
|
||||
public final CharBuffer decode (ByteBuffer in)
|
||||
throws CharacterCodingException
|
||||
{
|
||||
// XXX: Sun's Javadoc seems to contradict itself saying an
|
||||
// IllegalStateException is thrown "if a decoding operation is already
|
||||
// in progress" and also that "it resets this Decoder".
|
||||
// Should we check to see that the state is reset, or should we
|
||||
// call reset()?
|
||||
if (state != STATE_RESET)
|
||||
throw new IllegalStateException ();
|
||||
|
||||
// REVIEW: Using max instead of average may allocate a very large
|
||||
// buffer. Maybe we should do something more efficient?
|
||||
int remaining = in.remaining ();
|
||||
int n = (int) (remaining * maxCharsPerByte ());
|
||||
CharBuffer out = CharBuffer.allocate (n);
|
||||
|
||||
if (remaining == 0)
|
||||
{
|
||||
state = STATE_FLUSHED;
|
||||
return out;
|
||||
}
|
||||
|
||||
CoderResult cr = decode (in, out, true);
|
||||
if (cr.isError ())
|
||||
cr.throwException ();
|
||||
|
||||
cr = flush (out);
|
||||
if (cr.isError ())
|
||||
cr.throwException ();
|
||||
|
||||
out.flip ();
|
||||
return out;
|
||||
}
|
||||
|
||||
public final CoderResult decode (ByteBuffer in, CharBuffer out,
|
||||
boolean endOfInput)
|
||||
{
|
||||
int newState = endOfInput ? STATE_END : STATE_CODING;
|
||||
// XXX: Need to check for "previous step was an invocation [not] of
|
||||
// this method with a value of true for the endOfInput parameter but
|
||||
// a return value indicating an incomplete decoding operation"
|
||||
// XXX: We will not check the previous return value, just
|
||||
// that the previous call passed true for endOfInput
|
||||
if (state != STATE_RESET && state != STATE_CODING
|
||||
&& !(endOfInput && state == STATE_END))
|
||||
throw new IllegalStateException ();
|
||||
state = newState;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CoderResult cr;
|
||||
try
|
||||
{
|
||||
cr = decodeLoop (in, out);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
throw new CoderMalfunctionError (e);
|
||||
}
|
||||
|
||||
if (cr.isOverflow ())
|
||||
return cr;
|
||||
|
||||
if (cr.isUnderflow ())
|
||||
{
|
||||
if (endOfInput && in.hasRemaining ())
|
||||
cr = CoderResult.malformedForLength (in.remaining ());
|
||||
else
|
||||
return cr;
|
||||
}
|
||||
|
||||
CodingErrorAction action = cr.isMalformed ()
|
||||
? malformedInputAction
|
||||
: unmappableCharacterAction;
|
||||
|
||||
if (action == CodingErrorAction.REPORT)
|
||||
return cr;
|
||||
|
||||
if (action == CodingErrorAction.REPLACE)
|
||||
{
|
||||
if (out.remaining () < replacement.length ())
|
||||
return CoderResult.OVERFLOW;
|
||||
out.put (replacement);
|
||||
}
|
||||
|
||||
in.position (in.position () + cr.length ());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract CoderResult decodeLoop (ByteBuffer in, CharBuffer out);
|
||||
|
||||
public Charset detectedCharset ()
|
||||
{
|
||||
throw new UnsupportedOperationException ();
|
||||
}
|
||||
|
||||
public final CoderResult flush (CharBuffer out)
|
||||
{
|
||||
// It seems weird that you can flush after reset, but Sun's javadoc
|
||||
// says an IllegalStateException is thrown "If the previous step of the
|
||||
// current decoding operation was an invocation neither of the reset
|
||||
// method nor ... of the three-argument decode method with a value of
|
||||
// true for the endOfInput parameter."
|
||||
// Further note that flush() only requires that there not be
|
||||
// an IllegalStateException if the previous step was a call to
|
||||
// decode with true as the last argument. It does not require
|
||||
// that the call succeeded. decode() does require that it succeeded.
|
||||
// XXX: test this to see if reality matches javadoc
|
||||
if (state != STATE_RESET && state != STATE_END)
|
||||
throw new IllegalStateException ();
|
||||
|
||||
state = STATE_FLUSHED;
|
||||
return implFlush (out);
|
||||
}
|
||||
|
||||
protected CoderResult implFlush (CharBuffer out)
|
||||
{
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
public final CharsetDecoder onMalformedInput (CodingErrorAction newAction)
|
||||
{
|
||||
if (newAction == null)
|
||||
throw new IllegalArgumentException ("Null action");
|
||||
|
||||
malformedInputAction = newAction;
|
||||
implOnMalformedInput (newAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void implOnMalformedInput (CodingErrorAction newAction)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implOnUnmappableCharacter (CodingErrorAction newAction)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implReplaceWith (String newReplacement)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implReset ()
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
public boolean isAutoDetecting ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCharsetDetected ()
|
||||
{
|
||||
throw new UnsupportedOperationException ();
|
||||
}
|
||||
|
||||
public CodingErrorAction malformedInputAction ()
|
||||
{
|
||||
return malformedInputAction;
|
||||
}
|
||||
|
||||
public final float maxCharsPerByte ()
|
||||
{
|
||||
return maxCharsPerByte;
|
||||
}
|
||||
|
||||
public final CharsetDecoder onUnmappableCharacter
|
||||
(CodingErrorAction newAction)
|
||||
{
|
||||
if (newAction == null)
|
||||
throw new IllegalArgumentException ("Null action");
|
||||
|
||||
unmappableCharacterAction = newAction;
|
||||
implOnUnmappableCharacter (newAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final String replacement ()
|
||||
{
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public final CharsetDecoder replaceWith (String newReplacement)
|
||||
{
|
||||
if (newReplacement == null)
|
||||
throw new IllegalArgumentException ("Null replacement");
|
||||
if (newReplacement.length () == 0)
|
||||
throw new IllegalArgumentException ("Empty replacement");
|
||||
// XXX: what about maxCharsPerByte?
|
||||
|
||||
this.replacement = newReplacement;
|
||||
implReplaceWith (newReplacement);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final CharsetDecoder reset ()
|
||||
{
|
||||
state = STATE_RESET;
|
||||
implReset ();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodingErrorAction unmappableCharacterAction ()
|
||||
{
|
||||
return unmappableCharacterAction;
|
||||
}
|
||||
}
|
360
libjava/java/nio/charset/CharsetEncoder.java
Normal file
360
libjava/java/nio/charset/CharsetEncoder.java
Normal file
@ -0,0 +1,360 @@
|
||||
/* CharsetEncoder.java --
|
||||
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., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 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.nio.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
/**
|
||||
* @author Jesse Rosenstock
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class CharsetEncoder
|
||||
{
|
||||
private static final int STATE_RESET = 0;
|
||||
private static final int STATE_CODING = 1;
|
||||
private static final int STATE_END = 2;
|
||||
private static final int STATE_FLUSHED = 3;
|
||||
|
||||
private static final byte[] DEFAULT_REPLACEMENT = {(byte)'?'};
|
||||
|
||||
private final Charset charset;
|
||||
private final float averageBytesPerChar;
|
||||
private final float maxBytesPerChar;
|
||||
private byte[] replacement;
|
||||
|
||||
private int state = STATE_RESET;
|
||||
|
||||
private CodingErrorAction malformedInputAction
|
||||
= CodingErrorAction.REPORT;
|
||||
private CodingErrorAction unmappableCharacterAction
|
||||
= CodingErrorAction.REPORT;
|
||||
|
||||
protected CharsetEncoder (Charset cs, float averageBytesPerChar,
|
||||
float maxBytesPerChar)
|
||||
{
|
||||
this (cs, averageBytesPerChar, maxBytesPerChar, DEFAULT_REPLACEMENT);
|
||||
}
|
||||
|
||||
protected CharsetEncoder (Charset cs, float averageBytesPerChar,
|
||||
float maxBytesPerChar, byte[] replacement)
|
||||
{
|
||||
if (averageBytesPerChar <= 0.0f)
|
||||
throw new IllegalArgumentException ("Non-positive averageBytesPerChar");
|
||||
if (maxBytesPerChar <= 0.0f)
|
||||
throw new IllegalArgumentException ("Non-positive maxBytesPerChar");
|
||||
|
||||
this.charset = cs;
|
||||
this.averageBytesPerChar
|
||||
= averageBytesPerChar;
|
||||
this.maxBytesPerChar
|
||||
= maxBytesPerChar;
|
||||
this.replacement = replacement;
|
||||
implReplaceWith (replacement);
|
||||
}
|
||||
|
||||
public final float averageBytesPerChar ()
|
||||
{
|
||||
return averageBytesPerChar;
|
||||
}
|
||||
|
||||
public boolean canEncode (char c)
|
||||
{
|
||||
CharBuffer cb = CharBuffer.allocate (1).put (c);
|
||||
cb.flip ();
|
||||
return canEncode (cb);
|
||||
}
|
||||
|
||||
public boolean canEncode (CharSequence cs)
|
||||
{
|
||||
CharBuffer cb;
|
||||
if (cs instanceof CharBuffer)
|
||||
cb = ((CharBuffer) cs).duplicate ();
|
||||
else
|
||||
cb = CharBuffer.wrap (cs);
|
||||
return canEncode (cb);
|
||||
}
|
||||
|
||||
private boolean canEncode (CharBuffer cb)
|
||||
{
|
||||
// It is an error if a coding operation is "in progress"
|
||||
// I take that to mean the state is not reset or flushed.
|
||||
// XXX: check "in progress" everywhere
|
||||
if (state == STATE_FLUSHED)
|
||||
reset ();
|
||||
else if (state != STATE_RESET)
|
||||
throw new IllegalStateException ();
|
||||
|
||||
CodingErrorAction oldMalformedInputAction = malformedInputAction;
|
||||
CodingErrorAction oldUnmappableCharacterAction
|
||||
= unmappableCharacterAction;
|
||||
|
||||
try
|
||||
{
|
||||
if (oldMalformedInputAction != CodingErrorAction.REPORT)
|
||||
onMalformedInput (CodingErrorAction.REPORT);
|
||||
if (oldUnmappableCharacterAction != CodingErrorAction.REPORT)
|
||||
onUnmappableCharacter (CodingErrorAction.REPORT);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oldMalformedInputAction != CodingErrorAction.REPORT)
|
||||
onMalformedInput (oldMalformedInputAction);
|
||||
if (oldUnmappableCharacterAction != CodingErrorAction.REPORT)
|
||||
onUnmappableCharacter (oldUnmappableCharacterAction);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public final Charset charset ()
|
||||
{
|
||||
return charset;
|
||||
}
|
||||
|
||||
public final ByteBuffer encode (CharBuffer in)
|
||||
throws CharacterCodingException
|
||||
{
|
||||
// XXX: Sun's Javadoc seems to contradict itself saying an
|
||||
// IllegalStateException is thrown "if a decoding operation is already
|
||||
// in progress" and also that "it resets this Encoder".
|
||||
// Should we check to see that the state is reset, or should we
|
||||
// call reset()?
|
||||
if (state != STATE_RESET)
|
||||
throw new IllegalStateException ();
|
||||
|
||||
// REVIEW: Using max instead of average may allocate a very large
|
||||
// buffer. Maybe we should do something more efficient?
|
||||
int remaining = in.remaining ();
|
||||
int n = (int) (remaining * maxBytesPerChar ());
|
||||
ByteBuffer out = ByteBuffer.allocate (n);
|
||||
|
||||
if (remaining == 0)
|
||||
{
|
||||
state = STATE_FLUSHED;
|
||||
return out;
|
||||
}
|
||||
|
||||
CoderResult cr = encode (in, out, true);
|
||||
if (cr.isError ())
|
||||
cr.throwException ();
|
||||
|
||||
cr = flush (out);
|
||||
if (cr.isError ())
|
||||
cr.throwException ();
|
||||
|
||||
out.flip ();
|
||||
return out;
|
||||
}
|
||||
|
||||
public final CoderResult encode (CharBuffer in, ByteBuffer out,
|
||||
boolean endOfInput)
|
||||
{
|
||||
int newState = endOfInput ? STATE_END : STATE_CODING;
|
||||
// XXX: Need to check for "previous step was an invocation [not] of
|
||||
// this method with a value of true for the endOfInput parameter but
|
||||
// a return value indicating an incomplete decoding operation"
|
||||
// XXX: We will not check the previous return value, just
|
||||
// that the previous call passed true for endOfInput
|
||||
if (state != STATE_RESET && state != STATE_CODING
|
||||
&& !(endOfInput && state == STATE_END))
|
||||
throw new IllegalStateException ();
|
||||
state = newState;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CoderResult cr;
|
||||
try
|
||||
{
|
||||
cr = encodeLoop (in, out);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
throw new CoderMalfunctionError (e);
|
||||
}
|
||||
|
||||
if (cr.isOverflow ())
|
||||
return cr;
|
||||
|
||||
if (cr.isUnderflow ())
|
||||
{
|
||||
if (endOfInput && in.hasRemaining ())
|
||||
cr = CoderResult.malformedForLength (in.remaining ());
|
||||
else
|
||||
return cr;
|
||||
}
|
||||
|
||||
CodingErrorAction action = cr.isMalformed ()
|
||||
? malformedInputAction
|
||||
: unmappableCharacterAction;
|
||||
|
||||
if (action == CodingErrorAction.REPORT)
|
||||
return cr;
|
||||
|
||||
if (action == CodingErrorAction.REPLACE)
|
||||
{
|
||||
if (out.remaining () < replacement.length)
|
||||
return CoderResult.OVERFLOW;
|
||||
out.put (replacement);
|
||||
}
|
||||
|
||||
in.position (in.position () + cr.length ());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract CoderResult encodeLoop (CharBuffer in, ByteBuffer out);
|
||||
|
||||
public final CoderResult flush (ByteBuffer out)
|
||||
{
|
||||
// It seems weird that you can flush after reset, but Sun's javadoc
|
||||
// says an IllegalStateException is thrown "If the previous step of the
|
||||
// current decoding operation was an invocation neither of the reset
|
||||
// method nor ... of the three-argument encode method with a value of
|
||||
// true for the endOfInput parameter."
|
||||
// Further note that flush() only requires that there not be
|
||||
// an IllegalStateException if the previous step was a call to
|
||||
// encode with true as the last argument. It does not require
|
||||
// that the call succeeded. encode() does require that it succeeded.
|
||||
// XXX: test this to see if reality matches javadoc
|
||||
if (state != STATE_RESET && state != STATE_END)
|
||||
throw new IllegalStateException ();
|
||||
|
||||
state = STATE_FLUSHED;
|
||||
return implFlush (out);
|
||||
}
|
||||
|
||||
protected CoderResult implFlush (ByteBuffer out)
|
||||
{
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
protected void implOnMalformedInput (CodingErrorAction newAction)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implOnUnmappableCharacter (CodingErrorAction newAction)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implReplaceWith (byte[] newReplacement)
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
protected void implReset ()
|
||||
{
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
public boolean isLegalReplacement (byte[] replacement)
|
||||
{
|
||||
// TODO: cache the decoder
|
||||
// error actions will be REPORT after construction
|
||||
CharsetDecoder decoder = charset.newDecoder ();
|
||||
ByteBuffer bb = ByteBuffer.wrap (replacement);
|
||||
CharBuffer cb
|
||||
= CharBuffer.allocate ((int) (replacement.length
|
||||
* decoder.maxCharsPerByte ()));
|
||||
return !decoder.decode (bb, cb, true).isError ();
|
||||
}
|
||||
|
||||
public CodingErrorAction malformedInputAction ()
|
||||
{
|
||||
return malformedInputAction;
|
||||
}
|
||||
|
||||
public final float maxBytesPerChar ()
|
||||
{
|
||||
return maxBytesPerChar;
|
||||
}
|
||||
|
||||
public final CharsetEncoder onMalformedInput (CodingErrorAction newAction)
|
||||
{
|
||||
if (newAction == null)
|
||||
throw new IllegalArgumentException ("Null action");
|
||||
|
||||
malformedInputAction = newAction;
|
||||
implOnMalformedInput (newAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final CharsetEncoder onUnmappableCharacter
|
||||
(CodingErrorAction newAction)
|
||||
{
|
||||
if (newAction == null)
|
||||
throw new IllegalArgumentException ("Null action");
|
||||
|
||||
unmappableCharacterAction = newAction;
|
||||
implOnUnmappableCharacter (newAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final byte[] replacement ()
|
||||
{
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public final CharsetEncoder replaceWith (byte[] newReplacement)
|
||||
{
|
||||
if (newReplacement == null)
|
||||
throw new IllegalArgumentException ("Null replacement");
|
||||
if (newReplacement.length == 0)
|
||||
throw new IllegalArgumentException ("Empty replacement");
|
||||
// XXX: what about maxBytesPerChar?
|
||||
|
||||
if (!isLegalReplacement (newReplacement))
|
||||
throw new IllegalArgumentException ("Illegal replacement");
|
||||
|
||||
this.replacement = newReplacement;
|
||||
implReplaceWith (newReplacement);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final CharsetEncoder reset ()
|
||||
{
|
||||
state = STATE_RESET;
|
||||
implReset ();
|
||||
return this;
|
||||
}
|
||||
}
|
193
libjava/java/nio/charset/CoderResult.java
Normal file
193
libjava/java/nio/charset/CoderResult.java
Normal file
@ -0,0 +1,193 @@
|
||||
/* CoderResult.java --
|
||||
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., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 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.nio.charset;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author Jesse Rosenstock
|
||||
* @since 1.4
|
||||
*/
|
||||
public class CoderResult
|
||||
{
|
||||
private static final int TYPE_MALFORMED = 0;
|
||||
private static final int TYPE_OVERFLOW = 1;
|
||||
private static final int TYPE_UNDERFLOW = 2;
|
||||
private static final int TYPE_UNMAPPABLE = 3;
|
||||
|
||||
public static final CoderResult OVERFLOW
|
||||
= new CoderResult (TYPE_OVERFLOW, 0);
|
||||
public static final CoderResult UNDERFLOW
|
||||
= new CoderResult (TYPE_UNDERFLOW, 0);
|
||||
|
||||
private static final String[] names
|
||||
= { "MALFORMED", "OVERFLOW", "UNDERFLOW", "UNMAPPABLE" };
|
||||
|
||||
private static final Cache malformedCache
|
||||
= new Cache ()
|
||||
{
|
||||
protected CoderResult make (int length)
|
||||
{
|
||||
return new CoderResult (TYPE_MALFORMED, length);
|
||||
}
|
||||
};
|
||||
|
||||
private static final Cache unmappableCache
|
||||
= new Cache ()
|
||||
{
|
||||
protected CoderResult make (int length)
|
||||
{
|
||||
return new CoderResult (TYPE_UNMAPPABLE, length);
|
||||
}
|
||||
};
|
||||
|
||||
private final int type;
|
||||
private final int length;
|
||||
|
||||
private CoderResult (int type, int length)
|
||||
{
|
||||
this.type = type;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public boolean isError ()
|
||||
{
|
||||
return length > 0;
|
||||
}
|
||||
|
||||
public boolean isMalformed ()
|
||||
{
|
||||
return type == TYPE_MALFORMED;
|
||||
}
|
||||
|
||||
public boolean isOverflow ()
|
||||
{
|
||||
return type == TYPE_OVERFLOW;
|
||||
}
|
||||
|
||||
public boolean isUnderflow ()
|
||||
{
|
||||
return type == TYPE_UNDERFLOW;
|
||||
}
|
||||
|
||||
public boolean isUnmappable ()
|
||||
{
|
||||
return type == TYPE_UNMAPPABLE;
|
||||
}
|
||||
|
||||
public int length ()
|
||||
{
|
||||
if (length <= 0)
|
||||
throw new UnsupportedOperationException ();
|
||||
else
|
||||
return length;
|
||||
}
|
||||
|
||||
public static CoderResult malformedForLength (int length)
|
||||
{
|
||||
return malformedCache.get (length);
|
||||
}
|
||||
|
||||
public void throwException ()
|
||||
throws CharacterCodingException
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_MALFORMED:
|
||||
throw new MalformedInputException (length);
|
||||
case TYPE_OVERFLOW:
|
||||
throw new BufferOverflowException ();
|
||||
case TYPE_UNDERFLOW:
|
||||
throw new BufferUnderflowException ();
|
||||
case TYPE_UNMAPPABLE:
|
||||
throw new UnmappableCharacterException (length);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
String name = names[type];
|
||||
return (length > 0) ? name + '[' + length + ']' : name;
|
||||
}
|
||||
|
||||
public static CoderResult unmappableForLength (int length)
|
||||
{
|
||||
return unmappableCache.get (length);
|
||||
}
|
||||
|
||||
private abstract static class Cache
|
||||
{
|
||||
private final HashMap cache;
|
||||
|
||||
private Cache ()
|
||||
{
|
||||
// If we didn't synchronize on this, then cache would be initialized
|
||||
// without holding a lock. Undefined behavior would occur if the
|
||||
// first thread to call get(int) was not the same as the one that
|
||||
// called the constructor.
|
||||
synchronized (this)
|
||||
{
|
||||
cache = new HashMap ();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized CoderResult get (int length)
|
||||
{
|
||||
if (length <= 0)
|
||||
throw new IllegalArgumentException ("Non-positive length");
|
||||
|
||||
Integer len = new Integer (length);
|
||||
CoderResult cr = null;
|
||||
Object o;
|
||||
if ((o = cache.get (len)) != null)
|
||||
cr = (CoderResult) ((WeakReference) o).get ();
|
||||
if (cr == null)
|
||||
{
|
||||
cr = make (length);
|
||||
cache.put (len, cr);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
protected abstract CoderResult make (int length);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user