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
14 changed files with 2006 additions and 82 deletions
|
@ -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>
|
2002-11-11 Jesse Rosenstock <jmr@ugcs.caltech.edu>
|
||||||
|
|
||||||
* gnu/java/nio/charset/ISO_8859_1.java,
|
* gnu/java/nio/charset/ISO_8859_1.java,
|
||||||
|
@ -9,10 +28,7 @@
|
||||||
gnu/java/nio/charset/UTF_16Encoder.java,
|
gnu/java/nio/charset/UTF_16Encoder.java,
|
||||||
gnu/java/nio/charset/UTF_16LE.java,
|
gnu/java/nio/charset/UTF_16LE.java,
|
||||||
gnu/java/nio/charset/UTF_8.java: New files.
|
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>
|
2002-11-11 Michael Koch <konqueror@gmx.de>
|
||||||
|
|
||||||
* java/nio/charset/CharacterCodingException.java:
|
* 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_SG.java \
|
||||||
gnu/java/locale/LocaleInformation_zh_TW.java \
|
gnu/java/locale/LocaleInformation_zh_TW.java \
|
||||||
gnu/java/math/MPN.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/der/DEREncodingException.java \
|
||||||
gnu/java/security/provider/DERReader.java \
|
gnu/java/security/provider/DERReader.java \
|
||||||
gnu/java/security/provider/DERWriter.java \
|
gnu/java/security/provider/DERWriter.java \
|
||||||
|
@ -1963,6 +1972,8 @@ java/nio/BufferOverflowException.java \
|
||||||
java/nio/BufferUnderflowException.java \
|
java/nio/BufferUnderflowException.java \
|
||||||
java/nio/ByteBuffer.java \
|
java/nio/ByteBuffer.java \
|
||||||
java/nio/ByteOrder.java \
|
java/nio/ByteOrder.java \
|
||||||
|
java/nio/CharBuffer.java \
|
||||||
|
java/nio/InvalidMarkException.java \
|
||||||
java/nio/MappedByteBuffer.java \
|
java/nio/MappedByteBuffer.java \
|
||||||
java/nio/channels/AlreadyConnectedException.java \
|
java/nio/channels/AlreadyConnectedException.java \
|
||||||
java/nio/channels/ByteChannel.java \
|
java/nio/channels/ByteChannel.java \
|
||||||
|
@ -1982,14 +1993,16 @@ java/nio/channels/ServerSocketChannel.java \
|
||||||
java/nio/channels/SocketChannel.java \
|
java/nio/channels/SocketChannel.java \
|
||||||
java/nio/channels/WritableByteChannel.java \
|
java/nio/channels/WritableByteChannel.java \
|
||||||
java/nio/channels/spi/AbstractSelectableChannel.java \
|
java/nio/channels/spi/AbstractSelectableChannel.java \
|
||||||
java/nio/channels/spi/AbstractChannel.java \
|
|
||||||
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
||||||
java/nio/channels/spi/AbstractSelectionKey.java \
|
java/nio/channels/spi/AbstractSelectionKey.java \
|
||||||
java/nio/channels/spi/AbstractSelector.java \
|
java/nio/channels/spi/AbstractSelector.java \
|
||||||
java/nio/channels/spi/SelectorProvider.java \
|
java/nio/channels/spi/SelectorProvider.java \
|
||||||
java/nio/charset/Charset.java \
|
java/nio/charset/Charset.java \
|
||||||
java/nio/charset/CharacterCodingException.java \
|
java/nio/charset/CharacterCodingException.java \
|
||||||
|
java/nio/charset/CharsetDecoder.java \
|
||||||
|
java/nio/charset/CharsetEncoder.java \
|
||||||
java/nio/charset/CoderMalfunctionError.java \
|
java/nio/charset/CoderMalfunctionError.java \
|
||||||
|
java/nio/charset/CoderResult.java \
|
||||||
java/nio/charset/CodingErrorAction.java \
|
java/nio/charset/CodingErrorAction.java \
|
||||||
java/nio/charset/IllegalCharsetNameException.java \
|
java/nio/charset/IllegalCharsetNameException.java \
|
||||||
java/nio/charset/MalformedInputException.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_SG.java \
|
||||||
gnu/java/locale/LocaleInformation_zh_TW.java \
|
gnu/java/locale/LocaleInformation_zh_TW.java \
|
||||||
gnu/java/math/MPN.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/der/DEREncodingException.java \
|
||||||
gnu/java/security/provider/DERReader.java \
|
gnu/java/security/provider/DERReader.java \
|
||||||
gnu/java/security/provider/DERWriter.java \
|
gnu/java/security/provider/DERWriter.java \
|
||||||
|
@ -1713,6 +1722,8 @@ java/nio/BufferOverflowException.java \
|
||||||
java/nio/BufferUnderflowException.java \
|
java/nio/BufferUnderflowException.java \
|
||||||
java/nio/ByteBuffer.java \
|
java/nio/ByteBuffer.java \
|
||||||
java/nio/ByteOrder.java \
|
java/nio/ByteOrder.java \
|
||||||
|
java/nio/CharBuffer.java \
|
||||||
|
java/nio/InvalidMarkException.java \
|
||||||
java/nio/MappedByteBuffer.java \
|
java/nio/MappedByteBuffer.java \
|
||||||
java/nio/channels/AlreadyConnectedException.java \
|
java/nio/channels/AlreadyConnectedException.java \
|
||||||
java/nio/channels/ByteChannel.java \
|
java/nio/channels/ByteChannel.java \
|
||||||
|
@ -1732,14 +1743,16 @@ java/nio/channels/ServerSocketChannel.java \
|
||||||
java/nio/channels/SocketChannel.java \
|
java/nio/channels/SocketChannel.java \
|
||||||
java/nio/channels/WritableByteChannel.java \
|
java/nio/channels/WritableByteChannel.java \
|
||||||
java/nio/channels/spi/AbstractSelectableChannel.java \
|
java/nio/channels/spi/AbstractSelectableChannel.java \
|
||||||
java/nio/channels/spi/AbstractChannel.java \
|
|
||||||
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
java/nio/channels/spi/AbstractInterruptibleChannel.java \
|
||||||
java/nio/channels/spi/AbstractSelectionKey.java \
|
java/nio/channels/spi/AbstractSelectionKey.java \
|
||||||
java/nio/channels/spi/AbstractSelector.java \
|
java/nio/channels/spi/AbstractSelector.java \
|
||||||
java/nio/channels/spi/SelectorProvider.java \
|
java/nio/channels/spi/SelectorProvider.java \
|
||||||
java/nio/charset/Charset.java \
|
java/nio/charset/Charset.java \
|
||||||
java/nio/charset/CharacterCodingException.java \
|
java/nio/charset/CharacterCodingException.java \
|
||||||
|
java/nio/charset/CharsetDecoder.java \
|
||||||
|
java/nio/charset/CharsetEncoder.java \
|
||||||
java/nio/charset/CoderMalfunctionError.java \
|
java/nio/charset/CoderMalfunctionError.java \
|
||||||
|
java/nio/charset/CoderResult.java \
|
||||||
java/nio/charset/CodingErrorAction.java \
|
java/nio/charset/CodingErrorAction.java \
|
||||||
java/nio/charset/IllegalCharsetNameException.java \
|
java/nio/charset/IllegalCharsetNameException.java \
|
||||||
java/nio/charset/MalformedInputException.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_HK.P \
|
||||||
.deps/gnu/java/locale/LocaleInformation_zh_SG.P \
|
.deps/gnu/java/locale/LocaleInformation_zh_SG.P \
|
||||||
.deps/gnu/java/locale/LocaleInformation_zh_TW.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/RMIMarshalledObjectInputStream.P \
|
||||||
.deps/gnu/java/rmi/RMIMarshalledObjectOutputStream.P \
|
.deps/gnu/java/rmi/RMIMarshalledObjectOutputStream.P \
|
||||||
.deps/gnu/java/rmi/dgc/DGCImpl.P .deps/gnu/java/rmi/dgc/DGCImpl_Skel.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/net/natPlainSocketImpl.P .deps/java/nio/Buffer.P \
|
||||||
.deps/java/nio/BufferOverflowException.P \
|
.deps/java/nio/BufferOverflowException.P \
|
||||||
.deps/java/nio/BufferUnderflowException.P .deps/java/nio/ByteBuffer.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/AlreadyConnectedException.P \
|
||||||
.deps/java/nio/channels/ByteChannel.P .deps/java/nio/channels/Channel.P \
|
.deps/java/nio/channels/ByteChannel.P .deps/java/nio/channels/Channel.P \
|
||||||
.deps/java/nio/channels/ClosedChannelException.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/ServerSocketChannel.P \
|
||||||
.deps/java/nio/channels/SocketChannel.P \
|
.deps/java/nio/channels/SocketChannel.P \
|
||||||
.deps/java/nio/channels/WritableByteChannel.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/AbstractInterruptibleChannel.P \
|
||||||
.deps/java/nio/channels/spi/AbstractSelectableChannel.P \
|
.deps/java/nio/channels/spi/AbstractSelectableChannel.P \
|
||||||
.deps/java/nio/channels/spi/AbstractSelectionKey.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/channels/spi/SelectorProvider.P \
|
||||||
.deps/java/nio/charset/CharacterCodingException.P \
|
.deps/java/nio/charset/CharacterCodingException.P \
|
||||||
.deps/java/nio/charset/Charset.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/CoderMalfunctionError.P \
|
||||||
|
.deps/java/nio/charset/CoderResult.P \
|
||||||
.deps/java/nio/charset/CodingErrorAction.P \
|
.deps/java/nio/charset/CodingErrorAction.P \
|
||||||
.deps/java/nio/charset/IllegalCharsetNameException.P \
|
.deps/java/nio/charset/IllegalCharsetNameException.P \
|
||||||
.deps/java/nio/charset/MalformedInputException.P \
|
.deps/java/nio/charset/MalformedInputException.P \
|
||||||
|
|
|
@ -39,4 +39,155 @@ package java.nio;
|
||||||
|
|
||||||
public abstract class Buffer
|
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.
|
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Classpath.
|
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
|
obligated to do so. If you do not wish to do so, delete this
|
||||||
exception statement from your version. */
|
exception statement from your version. */
|
||||||
|
|
||||||
package java.nio.channels.spi;
|
package java.nio;
|
||||||
|
|
||||||
import java.io.IOException;
|
/**
|
||||||
import java.nio.channels.Channel;
|
* @author Michael Koch
|
||||||
|
* @since 1.4
|
||||||
public abstract class AbstractChannel implements Channel
|
*/
|
||||||
|
public class InvalidMarkException extends IllegalStateException
|
||||||
{
|
{
|
||||||
boolean opened;
|
/**
|
||||||
|
* Creates the exception
|
||||||
public boolean isOpen()
|
*/
|
||||||
|
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;
|
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.AbstractSelectableChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
public abstract class DatagramChannel
|
public abstract class DatagramChannel
|
||||||
extends AbstractSelectableChannel
|
extends AbstractSelectableChannel
|
||||||
|
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel
|
||||||
{
|
{
|
||||||
public DatagramChannel (SelectorProvider provider)
|
/**
|
||||||
|
* Initializes the channel.
|
||||||
|
*/
|
||||||
|
protected DatagramChannel (SelectorProvider provider)
|
||||||
{
|
{
|
||||||
super (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.AbstractSelectableChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
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
|
public abstract class ServerSocketChannel
|
||||||
extends AbstractSelectableChannel
|
extends AbstractSelectableChannel
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Initializes this channel.
|
||||||
|
*/
|
||||||
public ServerSocketChannel (SelectorProvider provider)
|
public ServerSocketChannel (SelectorProvider provider)
|
||||||
{
|
{
|
||||||
super (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.AbstractSelectableChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
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);
|
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.
|
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Classpath.
|
This file is part of GNU Classpath.
|
||||||
|
@ -37,18 +37,171 @@ exception statement from your version. */
|
||||||
|
|
||||||
package java.nio.channels.spi;
|
package java.nio.channels.spi;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.SelectableChannel;
|
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
|
public abstract class AbstractSelectableChannel extends SelectableChannel
|
||||||
extends SelectableChannel
|
|
||||||
{
|
{
|
||||||
|
int registered;
|
||||||
|
boolean blocking = true;
|
||||||
|
Object LOCK = new Object ();
|
||||||
|
SelectorProvider provider;
|
||||||
|
List keys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the channel
|
||||||
|
*/
|
||||||
protected AbstractSelectableChannel (SelectorProvider provider)
|
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()
|
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;
|
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.*;
|
/**
|
||||||
|
* @author Jesse Rosenstock
|
||||||
public class Charset
|
* @since 1.4
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
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…
Add table
Add a link
Reference in a new issue