diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 0000000000..2a766675ab
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: Apache-2.0
+name: Java CI
+
+on:
+ # Build only the production branches on push, so internal feature branches do not trigger a build twice (once on push, once on the pull request).
+ push:
+ # Restricts push builds to these branches, even if the workflow is copied to another branch.
+ branches:
+ - 2.0.X
+ - 2.1.X
+ - 2.2.X
+ # Build every pull request targeting the branch this workflow lives on.
+ pull_request:
+
+# Permissions are granted per job.
+permissions: { }
+
+# Check all pushes to production branches, but interrupt a PR job if a new commit is pushed.
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ java-version: [17, 21, 25]
+ distribution: [temurin]
+ fail-fast: false
+ name: Test JDK ${{ matrix.java-version }}, ${{ matrix.os }}
+
+ # Actions from the `actions` and `github` organizations are pinned to a major version tag rather than a commit SHA.
+ # This is a deliberate decision:
+ #
+ # - Those organizations have strong expertise in securing GitHub Actions.
+ # - A compromise of either organization would likely also compromise the GitHub Actions service itself, so pinning would not help.
+ # - These actions release frequently.
+ #
+ # The residual risk is deemed acceptable in exchange for less Dependabot churn across the maintained branches.
+ steps:
+
+ - name: Checkout repository
+ uses: actions/checkout@v6
+ with:
+ # Don't persist the GitHub token used to check out the repository.
+ persist-credentials: false
+
+ - name: Set up JDK
+ uses: actions/setup-java@v5
+ with:
+ java-version: ${{ matrix.java-version }}
+ distribution: ${{ matrix.distribution }}
+ cache: maven
+
+ - name: Test with Maven
+ shell: bash
+ run: |
+ mvn verify \
+ -Pserial \
+ --show-version --batch-mode --errors --no-transfer-progress
+
+ # Upload the test results, even when the build failed.
+ - name: Upload test reports
+ if: always()
+ uses: actions/upload-artifact@v7
+ with:
+ name: "test-report-${{matrix.os}}-${{matrix.distribution}}-${{matrix.java-version}}-${{github.run_number}}-${{github.run_attempt}}"
+ # Don't warn or fail when no tests ran (e.g. a compilation failure).
+ if-no-files-found: ignore
+ path: |
+ **/target/surefire-reports
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..00930c7b0a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+.classpath
+.project
+.settings
+.wtpmodules
+*.ipr
+*.iws
+*.iml
+target/
+bin/
+*.log
+.deployables
+.clover
+META-INF/
+Dockerfile
+/.idea/
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000000..80b8856e8d
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+pipeline {
+ agent any
+
+ tools {
+ maven 'maven_3_latest'
+ jdk params.jdkVersion
+ }
+
+ options {
+ // Configure an overall timeout for the build of ten hours.
+ timeout(time: 20, unit: 'HOURS')
+ // When we have test-fails e.g. we don't need to run the remaining steps
+ buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '5'))
+ disableConcurrentBuilds()
+ }
+
+ parameters {
+ choice(name: 'nodeLabel', choices: ['ubuntu', 'arm', 'Windows'])
+ choice(name: 'jdkVersion', choices: ['jdk_11_latest', 'jdk_17_latest', 'jdk_21_latest', 'jdk_22_latest', 'jdk_11_latest_windows', 'jdk_17_latest_windows', 'jdk_21_latest_windows', 'jdk_22_latest_windows'])
+ booleanParam(name: 'deployEnabled', defaultValue: false)
+ booleanParam(name: 'sonarEnabled', defaultValue: false)
+ booleanParam(name: 'testsEnabled', defaultValue: true)
+ }
+
+ triggers {
+ cron('@weekly')
+ pollSCM('@daily')
+ }
+
+ stages {
+ stage('Initialization') {
+ steps {
+ echo "running on ${env.NODE_NAME}"
+ echo 'Building branch ' + env.BRANCH_NAME
+ echo 'Using PATH ' + env.PATH
+ }
+ }
+
+ stage('Cleanup') {
+ steps {
+ echo 'Cleaning up the workspace'
+ deleteDir()
+ }
+ }
+
+ stage('Checkout') {
+ steps {
+ echo 'Checking out branch ' + env.BRANCH_NAME
+ checkout scm
+ }
+ }
+
+ stage('Build JDK 22 Linux') {
+ tools {
+ jdk "jdk_22_latest"
+ }
+ steps {
+ echo 'Building JDK 22 Linux'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 21 Linux') {
+ tools {
+ jdk "jdk_21_latest"
+ }
+ steps {
+ echo 'Building JDK 21 Linux'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 17 Linux') {
+ tools {
+ jdk "jdk_17_latest"
+ }
+ steps {
+ echo 'Building JDK 17 Linux'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 11 Linux') {
+ tools {
+ jdk "jdk_11_latest"
+ }
+ steps {
+ echo 'Building JDK 11 Linux'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ /*--- Comment out Windows builds for the moment ---*/
+ /*
+ stage('Build JDK 22 Windows') {
+ tools {
+ jdk "jdk_22_latest_windows"
+ }
+ steps {
+ echo 'Building JDK 22 Windows'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 21 Windows') {
+ tools {
+ jdk "jdk_21_latest_windows"
+ }
+ steps {
+ echo 'Building JDK 21 Windows'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 17 Windows') {
+ tools {
+ jdk "jdk_17_latest_windows"
+ }
+ steps {
+ echo 'Building JDK 17 Windows'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 11 Windows') {
+ tools {
+ jdk "jdk_11_latest_windows"
+ }
+ steps {
+ echo 'Building JDK 11 Windows'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+
+ stage('Build JDK 8 Windows') {
+ tools {
+ jdk "jdk_1.8_latest_windows"
+ }
+ steps {
+ echo 'Building JDK 8 Windows'
+ sh 'java -version'
+ sh 'mvn -version'
+ sh 'mvn clean install -Pserial'
+ }
+ }
+ ---*/
+ }
+}
diff --git a/LICENSE.jzlib.txt b/LICENSE.jzlib.txt
index cdce5007d0..6859c59dee 100644
--- a/LICENSE.jzlib.txt
+++ b/LICENSE.jzlib.txt
@@ -2,7 +2,7 @@ JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched
over to a BSD-style license.
------------------------------------------------------------------------------
-Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
diff --git a/LICENSE.ognl.txt b/LICENSE.ognl.txt
deleted file mode 100644
index 947f642c79..0000000000
--- a/LICENSE.ognl.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-OGNL is the creation of Luke Blanshard and Drew Davidson.
-
-Copyright © 1997-2003, Drew Davidson and Luke Blanshard. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Drew Davidson nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/LICENSE.slf4j.txt b/LICENSE.slf4j.txt
index e663b1d7f0..a51675a21c 100644
--- a/LICENSE.slf4j.txt
+++ b/LICENSE.slf4j.txt
@@ -1,28 +1,23 @@
-Copyright (c) 2004-2007 QOS.ch
+Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland)
All rights reserved.
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, and/or sell copies of the Software, and to permit persons
-to whom the Software is furnished to do so, provided that the above
-copyright notice(s) and this permission notice appear in all copies of
-the Software and that both the above copyright notice(s) and this
-permission notice appear in supporting documentation.
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
-SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
-RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
-CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-of the copyright holder.
diff --git a/NOTICE-bin.txt b/NOTICE-bin.txt
new file mode 100644
index 0000000000..39d01a3a27
--- /dev/null
+++ b/NOTICE-bin.txt
@@ -0,0 +1,36 @@
+Apache MINA
+Copyright 2007-2026 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Please refer to each LICENSE.TRUE if all the {@link IoFuture} have been completed, FALSE if
+ * at least one {@link IoFuture} haas been interrupted
+ * @throws InterruptedException If one of the {@link IoFuture} is interrupted
+ */
+ public static boolean await(Iterable extends IoFuture> futures, long timeout, TimeUnit unit)
+ throws InterruptedException {
return await(futures, unit.toMillis(timeout));
}
+ /**
+ * Wait on all the {@link IoFuture}s we get, or until one of the {@link IoFuture}s is interrupted
+ *
+ * @param futures The {@link IoFuture}s we are waiting on
+ * @param timeoutMillis The maximum milliseconds we wait for the {@link IoFuture}s to complete
+ * @return TRUE if all the {@link IoFuture} have been completed, FALSE if
+ * at least one {@link IoFuture} has been interrupted
+ * @throws InterruptedException If one of the {@link IoFuture} is interrupted
+ */
public static boolean await(Iterable extends IoFuture> futures, long timeoutMillis) throws InterruptedException {
return await0(futures, timeoutMillis, true);
}
+ /**
+ * Wait on all the {@link IoFuture}s we get.
+ *
+ * @param futures The {@link IoFuture}s we are waiting on
+ * @param timeout The maximum time we wait for the {@link IoFuture}s to complete
+ * @param unit The Time unit to use for the timeout
+ * @return TRUE if all the {@link IoFuture} have been completed, FALSE if
+ * at least one {@link IoFuture} has been interrupted
+ */
public static boolean awaitUninterruptibly(Iterable extends IoFuture> futures, long timeout, TimeUnit unit) {
return awaitUninterruptibly(futures, unit.toMillis(timeout));
}
+ /**
+ * Wait on all the {@link IoFuture}s we get.
+ *
+ * @param futures The {@link IoFuture}s we are waiting on
+ * @param timeoutMillis The maximum milliseconds we wait for the {@link IoFuture}s to complete
+ * @return TRUE if all the {@link IoFuture} have been completed, FALSE if
+ * at least one {@link IoFuture} has been interrupted
+ */
public static boolean awaitUninterruptibly(Iterable extends IoFuture> futures, long timeoutMillis) {
try {
return await0(futures, timeoutMillis, false);
} catch (InterruptedException e) {
- throw new InternalError();
+ throw new IllegalStateException(e);
}
}
- private static boolean await0(Iterable extends IoFuture> futures, long timeoutMillis, boolean interruptable) throws InterruptedException {
+ private static boolean await0(Iterable extends IoFuture> futures, long timeoutMillis, boolean interruptable)
+ throws InterruptedException {
long startTime = timeoutMillis <= 0 ? 0 : System.currentTimeMillis();
long waitTime = timeoutMillis;
-
+
boolean lastComplete = true;
Iterator extends IoFuture> i = futures.iterator();
+
while (i.hasNext()) {
IoFuture f = i.next();
+
do {
if (interruptable) {
lastComplete = f.await(waitTime);
} else {
lastComplete = f.awaitUninterruptibly(waitTime);
}
-
+
waitTime = timeoutMillis - (System.currentTimeMillis() - startTime);
- if (lastComplete || waitTime <= 0) {
+ if (waitTime <= 0) {
break;
}
} while (!lastComplete);
-
+
if (waitTime <= 0) {
break;
}
}
-
- return lastComplete && !i.hasNext();
- }
- private IoUtil() {
- // Do nothing
+ return lastComplete && !i.hasNext();
}
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/RuntimeIoException.java b/mina-core/src/main/java/org/apache/mina/core/RuntimeIoException.java
index b014b24f72..88a4b3d6dd 100644
--- a/mina-core/src/main/java/org/apache/mina/core/RuntimeIoException.java
+++ b/mina-core/src/main/java/org/apache/mina/core/RuntimeIoException.java
@@ -33,18 +33,37 @@
public class RuntimeIoException extends RuntimeException {
private static final long serialVersionUID = 9029092241311939548L;
+ /**
+ * Create a new RuntimeIoException instance
+ */
public RuntimeIoException() {
super();
}
+ /**
+ * Create a new RuntimeIoException instance
+ *
+ * @param message The error message
+ */
public RuntimeIoException(String message) {
super(message);
}
+ /**
+ * Create a new RuntimeIoException instance
+ *
+ * @param message The error message
+ * @param cause The original exception
+ */
public RuntimeIoException(String message, Throwable cause) {
super(message, cause);
}
+ /**
+ * Create a new RuntimeIoException instance
+ *
+ * @param cause The original exception
+ */
public RuntimeIoException(Throwable cause) {
super(cause);
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
index 0d6da9e1e2..957f808d70 100644
--- a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
+++ b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
@@ -26,7 +26,9 @@
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
+import java.io.Serializable;
import java.io.StreamCorruptedException;
+import java.lang.reflect.Proxy;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@@ -41,14 +43,24 @@
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.EnumSet;
+import java.util.List;
import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.mina.core.buffer.matcher.ClassNameMatcher;
+import org.apache.mina.core.buffer.matcher.FullClassNameMatcher;
+import org.apache.mina.core.buffer.matcher.RegexpClassNameMatcher;
+import org.apache.mina.core.buffer.matcher.WildcardClassNameMatcher;
+
/**
- * A base implementation of {@link IoBuffer}. This implementation
- * assumes that {@link IoBuffer#buf()} always returns a correct NIO
- * {@link ByteBuffer} instance. Most implementations could
- * extend this class and implement their own buffer management mechanism.
+ * A base implementation of {@link IoBuffer}. This implementation assumes that
+ * {@link IoBuffer#buf()} always returns a correct NIO {@link ByteBuffer}
+ * instance. Most implementations could extend this class and implement their
+ * own buffer management mechanism.
*
* @author Apache MINA Project
* @see IoBufferAllocator
@@ -78,6 +90,8 @@ public abstract class AbstractIoBuffer extends IoBuffer {
/** A mask for an int */
private static final long INT_MASK = 0xFFFFFFFFL;
+ private final Listdecoder and returns it.
+ * Reads a string which has a length field before the actual encoded string,
+ * using the specified decoder and returns it.
*
* @param prefixLength the length of the length field (1, 2, or 4)
- * @param decoder the decoder to use for decoding the string
+ * @param decoder the decoder to use for decoding the string
* @return the prefixed string
* @throws CharacterCodingException when decoding fails
* @throws BufferUnderflowException when there is not enough data available
*/
@Override
- public String getPrefixedString(int prefixLength, CharsetDecoder decoder)
- throws CharacterCodingException {
+ public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException {
if (!prefixedDataAvailable(prefixLength)) {
throw new BufferUnderflowException();
}
@@ -1719,11 +1955,12 @@ public String getPrefixedString(int prefixLength, CharsetDecoder decoder)
return "";
}
- boolean utf16 = decoder.charset().name().startsWith("UTF-16");
+ boolean utf16 = decoder.charset().equals(StandardCharsets.UTF_16)
+ || decoder.charset().equals(StandardCharsets.UTF_16BE)
+ || decoder.charset().equals(StandardCharsets.UTF_16LE);
if (utf16 && (fieldSize & 1) != 0) {
- throw new BufferDataException(
- "fieldSize is not even for a UTF-16 string.");
+ throw new BufferDataException("fieldSize is not even for a UTF-16 string.");
}
int oldLimit = limit();
@@ -1751,8 +1988,7 @@ public String getPrefixedString(int prefixLength, CharsetDecoder decoder)
}
if (cr.isOverflow()) {
- CharBuffer o = CharBuffer.allocate(out.capacity()
- + expectedLength);
+ CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
out.flip();
o.put(out);
out = o;
@@ -1771,8 +2007,7 @@ public String getPrefixedString(int prefixLength, CharsetDecoder decoder)
* {@inheritDoc}
*/
@Override
- public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder)
- throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
return putPrefixedString(in, 2, 0, encoder);
}
@@ -1780,8 +2015,8 @@ public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder)
* {@inheritDoc}
*/
@Override
- public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
- CharsetEncoder encoder) throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder)
+ throws CharacterCodingException {
return putPrefixedString(in, prefixLength, 0, encoder);
}
@@ -1789,8 +2024,7 @@ public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
* {@inheritDoc}
*/
@Override
- public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
- int padding, CharsetEncoder encoder)
+ public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
throws CharacterCodingException {
return putPrefixedString(in, prefixLength, padding, (byte) 0, encoder);
}
@@ -1799,9 +2033,8 @@ public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
* {@inheritDoc}
*/
@Override
- public IoBuffer putPrefixedString(CharSequence val, int prefixLength,
- int padding, byte padValue, CharsetEncoder encoder)
- throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue,
+ CharsetEncoder encoder) throws CharacterCodingException {
int maxLength;
switch (prefixLength) {
case 1:
@@ -1818,8 +2051,7 @@ public IoBuffer putPrefixedString(CharSequence val, int prefixLength,
}
if (val.length() > maxLength) {
- throw new IllegalArgumentException(
- "The specified string is too long.");
+ throw new IllegalArgumentException("The specified string is too long.");
}
if (val.length() == 0) {
switch (prefixLength) {
@@ -1868,8 +2100,7 @@ public IoBuffer putPrefixedString(CharSequence val, int prefixLength,
}
if (position() - oldPos > maxLength) {
- throw new IllegalArgumentException(
- "The specified string is too long.");
+ throw new IllegalArgumentException("The specified string is too long.");
}
if (cr.isUnderflow()) {
@@ -1879,20 +2110,17 @@ public IoBuffer putPrefixedString(CharSequence val, int prefixLength,
if (isAutoExpand()) {
switch (expandedState) {
case 0:
- autoExpand((int) Math.ceil(in.remaining()
- * encoder.averageBytesPerChar()));
+ autoExpand((int) Math.ceil(in.remaining() * encoder.averageBytesPerChar()));
expandedState++;
break;
case 1:
- autoExpand((int) Math.ceil(in.remaining()
- * encoder.maxBytesPerChar()));
+ autoExpand((int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()));
expandedState++;
break;
default:
- throw new RuntimeException("Expanded by "
- + (int) Math.ceil(in.remaining()
- * encoder.maxBytesPerChar())
- + " but that wasn't enough for '" + val + "'");
+ throw new IllegalArgumentException(
+ "Expanded by " + (int) Math.ceil(in.remaining() * encoder.maxBytesPerChar())
+ + " but that wasn't enough for '" + val + "'");
}
continue;
}
@@ -1931,54 +2159,91 @@ public Object getObject() throws ClassNotFoundException {
* {@inheritDoc}
*/
@Override
- public Object getObject(final ClassLoader classLoader)
- throws ClassNotFoundException {
+ public Object getObject(final ClassLoader classLoader) throws ClassNotFoundException {
if (!prefixedDataAvailable(4)) {
throw new BufferUnderflowException();
}
int length = getInt();
if (length <= 4) {
- throw new BufferDataException(
- "Object length should be greater than 4: " + length);
+ throw new BufferDataException("Object length should be greater than 4: " + length);
}
int oldLimit = limit();
limit(position() + length);
- try {
- ObjectInputStream in = new ObjectInputStream(asInputStream()) {
- @Override
- protected ObjectStreamClass readClassDescriptor()
- throws IOException, ClassNotFoundException {
- int type = read();
- if (type < 0) {
- throw new EOFException();
- }
- switch (type) {
- case 0: // Primitive types
+
+ try (ObjectInputStream in = new ObjectInputStream(asInputStream()) {
+ @Override
+ protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
+ int type = read();
+
+ if (type < 0) {
+ throw new EOFException();
+ }
+
+ switch (type) {
+ case 0: // NON-Serializable class or Primitive types
return super.readClassDescriptor();
- case 1: // Non-primitive types
+
+ case 1: // Serializable class
String className = readUTF();
- Class> clazz = Class.forName(className, true,
- classLoader);
- return ObjectStreamClass.lookup(clazz);
+
+ // Only accept classes that are listed as acceptable
+ // Apply class filter BEFORE calling Class.forName
+ if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
+ throw new ClassNotFoundException("Class not in accept list " + className);
+ }
+
+ // Use initialize=false to prevent static block execution during class loading
+ return super.readClassDescriptor();
+
default:
- throw new StreamCorruptedException(
- "Unexpected class descriptor type: " + type);
- }
+ throw new StreamCorruptedException("Unexpected class descriptor type: " + type);
}
+ }
+
+ @Override
+ protected Class> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ String className = desc.getName();
+
+ // apply acceptMatchers filter before any Class.forName() call,
+ // regardless of whether forClass() is null or not
+ if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
+ throw new ClassNotFoundException("Class not in accept list " + className);
+ }
+
+ Class> clazz = desc.forClass();
+
+ if (clazz != null) {
+ return clazz;
+ }
+
+ try {
+ return Class.forName(className, false, classLoader);
+ } catch (ClassNotFoundException ex) {
+ return super.resolveClass(desc);
+ }
+ }
+
+ @Override
+ protected Class> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
+ Class>[] classes = new Class>[interfaces.length];
+ int i=0;
- @Override
- protected Class> resolveClass(ObjectStreamClass desc)
- throws IOException, ClassNotFoundException {
- String name = desc.getName();
- try {
- return Class.forName(name, false, classLoader);
- } catch (ClassNotFoundException ex) {
- return super.resolveClass(desc);
+ for (String interfaceName : interfaces) {
+ if (!acceptMatchers.stream().anyMatch(m -> m.matches(interfaceName))) {
+ throw new ClassNotFoundException("Interface not in accept list " + interfaceName);
}
+
+ // Use Class.forName(name, false, loader) — initialize=false — and load via
+ // the configured classLoader, NOT latestUserDefinedLoader().
+ classes[i++] = Class.forName(interfaceName, false, classLoader);
}
- };
+
+
+ return Proxy.getProxyClass(classLoader, classes);
+ }
+ }) {
return in.readObject();
} catch (IOException e) {
throw new BufferDataException(e);
@@ -1994,20 +2259,23 @@ protected Class> resolveClass(ObjectStreamClass desc)
public IoBuffer putObject(Object o) {
int oldPos = position();
skip(4); // Make a room for the length field.
- try {
- ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {
- @Override
- protected void writeClassDescriptor(ObjectStreamClass desc)
- throws IOException {
- if (desc.forClass().isPrimitive()) {
- write(0);
- super.writeClassDescriptor(desc);
- } else {
- write(1);
- writeUTF(desc.getName());
- }
+
+ try (ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {
+ @Override
+ protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
+ Class> clazz = desc.forClass();
+
+ if (clazz.isArray() || clazz.isPrimitive() || !Serializable.class.isAssignableFrom(clazz)) {
+ write(0);
+ } else {
+ // Serializable class
+ write(1);
+ writeUTF(desc.getName());
}
- };
+
+ super.writeClassDescriptor(desc);
+ }
+ }) {
out.writeObject(o);
out.flush();
} catch (IOException e) {
@@ -2110,10 +2378,8 @@ public IoBuffer fill(byte value, int size) {
int r = size & 7;
if (q > 0) {
- int intValue = value | value << 8 | value << 16 | value << 24;
- long longValue = intValue;
- longValue <<= 32;
- longValue |= intValue;
+ int intValue = value & 0x000000FF | (value << 8) & 0x0000FF00 | (value << 16) & 0x00FF0000 | value << 24;
+ long longValue = intValue & 0x00000000FFFFFFFFL | (long) intValue << 32;
for (int i = q; i > 0; i--) {
putLong(longValue);
@@ -2124,7 +2390,7 @@ public IoBuffer fill(byte value, int size) {
r = r & 3;
if (q > 0) {
- int intValue = value | value << 8 | value << 16 | value << 24;
+ int intValue = value & 0x000000FF | (value << 8) & 0x0000FF00 | (value << 16) & 0x00FF0000 | value << 24;
putInt(intValue);
}
@@ -2132,7 +2398,7 @@ public IoBuffer fill(byte value, int size) {
r = r & 1;
if (q > 0) {
- short shortValue = (short) (value | value << 8);
+ short shortValue = (short) (value & 0x000FF | value << 8);
putShort(shortValue);
}
@@ -2251,6 +2517,7 @@ public autoExpand property is true.
*/
private IoBuffer autoExpand(int expectedRemaining) {
if (isAutoExpand()) {
@@ -2534,7 +2783,7 @@ private IoBuffer autoExpand(int expectedRemaining) {
/**
* This method forwards the call to {@link #expand(int)} only when
- * autoExpand property is true.
+ * autoExpand property is true.
*/
private IoBuffer autoExpand(int pos, int expectedRemaining) {
if (isAutoExpand()) {
@@ -2545,8 +2794,65 @@ private IoBuffer autoExpand(int pos, int expectedRemaining) {
private static void checkFieldSize(int fieldSize) {
if (fieldSize < 0) {
- throw new IllegalArgumentException("fieldSize cannot be negative: "
- + fieldSize);
+ throw new IllegalArgumentException("fieldSize cannot be negative: " + fieldSize);
+ }
+ }
+
+ /**
+ * Accept the specified classes for deserialization, unless they
+ * are otherwise rejected.
+ *
+ * @param classes Classes to accept
+ * @return this object
+ */
+ public IoBuffer accept(Class>... classes) {
+ for (Class> clazz:classes) {
+ acceptMatchers.add(new FullClassNameMatcher(clazz.getName()));
+ }
+
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer accept(ClassNameMatcher m) {
+ acceptMatchers.add(m);
+
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer accept(Pattern pattern) {
+ acceptMatchers.add(new RegexpClassNameMatcher(pattern));
+
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer accept(String... patterns) {
+ for (String pattern:patterns) {
+ acceptMatchers.add(new WildcardClassNameMatcher(pattern));
+ }
+
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setMatchers(List
@@ -61,7 +63,7 @@ * IoBuffer buf = IoBuffer.allocate(1024, false); * * - * you can also allocate a new direct buffer: + * You can also allocate a new direct buffer: * *
* IoBuffer buf = IoBuffer.allocate(1024, true); @@ -72,25 +74,24 @@ ** // Allocate heap buffer by default. * IoBuffer.setUseDirectBuffer(false); + * * // A new heap buffer is returned. * IoBuffer buf = IoBuffer.allocate(1024); ** - * - * *Wrapping existing NIO buffers and arrays
*- * This class provides a few wrap(...) methods that wraps any NIO + * This class provides a few
wrap(...)methods that wraps any NIO * buffers and byte arrays. * *AutoExpand
*- * Writing variable-length data using NIO ByteBuffers is not really - * easy, and it is because its size is fixed. {@link IoBuffer} introduces - * autoExpand property. If autoExpand property is true, you - * never get {@link BufferOverflowException} or + * Writing variable-length data using NIO
ByteBuffersis not really + * easy, and it is because its size is fixed at allocation. {@link IoBuffer} + * introduces theautoExpandproperty. IfautoExpandproperty + * is set to true, you never get a {@link BufferOverflowException} or an * {@link IndexOutOfBoundsException} (except when index is negative). It - * automatically expands its capacity and limit value. For example: + * automatically expands its capacity. For instance: * ** String greeting = messageBundle.getMessage("hello"); @@ -104,40 +105,39 @@ * the scene if the encoded data is larger than 16 bytes in the example above. * Its capacity will double, and its limit will increase to the last position * the string is written. - * * *AutoShrink
** You might also want to decrease the capacity of the buffer when most of the * allocated memory area is not being used. {@link IoBuffer} provides - * autoShrink property to take care of this issue. If - * autoShrink is turned on, {@link IoBuffer} halves the capacity of the + *
autoShrinkproperty to take care of this issue. If + *autoShrinkis turned on, {@link IoBuffer} halves the capacity of the * buffer when {@link #compact()} is invoked and only 1/4 or less of the current * capacity is being used. *- * You can also {@link #shrink()} method manually to shrink the capacity of the - * buffer. + * You can also call the {@link #shrink()} method manually to shrink the + * capacity of the buffer. *
- * The underlying {@link ByteBuffer} is reallocated by {@link IoBuffer} behind - * the scene, and therefore {@link #buf()} will return a different - * {@link ByteBuffer} instance once capacity changes. Please also note - * {@link #compact()} or {@link #shrink()} will not decrease the capacity if the - * new capacity is less than the {@link #minimumCapacity()} of the buffer. + * The underlying {@link ByteBuffer} is reallocated by the {@link IoBuffer} + * behind the scene, and therefore {@link #buf()} will return a different + * {@link ByteBuffer} instance once capacity changes. Please also note that the + * {@link #compact()} method or the {@link #shrink()} method will not decrease + * the capacity if the new capacity is less than the {@link #minimumCapacity()} + * of the buffer. * *
Derived Buffers
*- * Derived buffers are the buffers which were created by {@link #duplicate()}, - * {@link #slice()}, or {@link #asReadOnlyBuffer()}. They are useful especially - * when you broadcast the same messages to multiple {@link IoSession}s. Please - * note that the buffer derived from and its derived buffers are not both - * auto-expandable neither auto-shrinkable. Trying to call + * Derived buffers are the buffers which were created by the + * {@link #duplicate()}, {@link #slice()}, or {@link #asReadOnlyBuffer()} + * methods. They are useful especially when you broadcast the same messages to + * multiple {@link IoSession}s. Please note that the buffer derived from and its + * derived buffers are not auto-expandable nor auto-shrinkable. Trying to call * {@link #setAutoExpand(boolean)} or {@link #setAutoShrink(boolean)} with - * true parameter will raise an {@link IllegalStateException}. - *
+ *trueparameter will raise an {@link java.lang.IllegalStateException}. * *Changing Buffer Allocation Policy
*- * {@link IoBufferAllocator} interface lets you override the default buffer + * The {@link IoBufferAllocator} interface lets you override the default buffer * management behavior. There are two allocators provided out-of-the-box: *
true if and only if a direct buffer is allocated by default
+ * when the type of the new buffer is not specified. The default value
+ * is false.
*/
public static boolean isUseDirectBuffer() {
return useDirectBuffer;
}
/**
- * Sets if a direct buffer should be allocated by default when the type of
- * the new buffer is not specified. The default value is false.
+ * Sets if a direct buffer should be allocated by default when the type of the
+ * new buffer is not specified. The default value is false.
+ *
+ * @param useDirectBuffer Tells if direct buffers should be allocated
*/
public static void setUseDirectBuffer(boolean useDirectBuffer) {
IoBuffer.useDirectBuffer = useDirectBuffer;
@@ -201,8 +212,8 @@ public static void setUseDirectBuffer(boolean useDirectBuffer) {
* Returns the direct or heap buffer which is capable to store the specified
* amount of bytes.
*
- * @param capacity
- * the capacity of the buffer
+ * @param capacity the capacity of the buffer
+ * @return a IoBuffer which can hold up to capacity bytes
*
* @see #setUseDirectBuffer(boolean)
*/
@@ -211,48 +222,67 @@ public static IoBuffer allocate(int capacity) {
}
/**
- * Returns the buffer which is capable of the specified size.
+ * Returns a direct or heap IoBuffer which can contain the specified number of
+ * bytes.
*
- * @param capacity
- * the capacity of the buffer
- * @param direct
- * true to get a direct buffer, false to get a
- * heap buffer.
+ * @param capacity the capacity of the buffer
+ * @param useDirectBuffer true to get a direct buffer, false
+ * to get a heap buffer.
+ * @return a direct or heap IoBuffer which can hold up to capacity bytes
*/
- public static IoBuffer allocate(int capacity, boolean direct) {
+ public static IoBuffer allocate(int capacity, boolean useDirectBuffer) {
if (capacity < 0) {
throw new IllegalArgumentException("capacity: " + capacity);
}
- return allocator.allocate(capacity, direct);
+ return allocator.allocate(capacity, useDirectBuffer);
}
/**
- * Wraps the specified NIO {@link ByteBuffer} into MINA buffer.
+ * Wraps the specified NIO {@link ByteBuffer} into a MINA buffer (either direct
+ * or heap).
+ *
+ * @param nioBuffer The {@link ByteBuffer} to wrap
+ * @return a IoBuffer containing the bytes stored in the {@link ByteBuffer}
*/
public static IoBuffer wrap(ByteBuffer nioBuffer) {
return allocator.wrap(nioBuffer);
}
/**
- * Wraps the specified byte array into MINA heap buffer.
+ * Wraps the specified byte array into a MINA heap buffer. Note that the byte
+ * array is not copied, so any modification done on it will be visible by both
+ * sides.
+ *
+ * @param byteArray The byte array to wrap
+ * @return a heap IoBuffer containing the byte array
*/
public static IoBuffer wrap(byte[] byteArray) {
return wrap(ByteBuffer.wrap(byteArray));
}
/**
- * Wraps the specified byte array into MINA heap buffer.
+ * Wraps the specified byte array into MINA heap buffer. We just wrap the bytes
+ * starting from offset up to offset + length. Note that the byte array is not
+ * copied, so any modification done on it will be visible by both sides.
+ *
+ * @param byteArray The byte array to wrap
+ * @param offset The starting point in the byte array
+ * @param length The number of bytes to store
+ * @return a heap IoBuffer containing the selected part of the byte array
*/
public static IoBuffer wrap(byte[] byteArray, int offset, int length) {
return wrap(ByteBuffer.wrap(byteArray, offset, length));
}
/**
- * Normalizes the specified capacity of the buffer to power of 2, which is
- * often helpful for optimal memory usage and performance. If it is greater
- * than or equal to {@link Integer#MAX_VALUE}, it returns
- * {@link Integer#MAX_VALUE}. If it is zero, it returns zero.
+ * Normalizes the specified capacity of the buffer to power of 2, which is often
+ * helpful for optimal memory usage and performance. If it is greater than or
+ * equal to {@link Integer#MAX_VALUE}, it returns {@link Integer#MAX_VALUE}. If
+ * it is zero, it returns zero.
+ *
+ * @param requestedCapacity The IoBuffer capacity we want to be able to store
+ * @return The power of 2 strictly superior to the requested capacity
*/
protected static int normalizeCapacity(int requestedCapacity) {
if (requestedCapacity < 0) {
@@ -261,377 +291,733 @@ protected static int normalizeCapacity(int requestedCapacity) {
int newCapacity = Integer.highestOneBit(requestedCapacity);
newCapacity <<= (newCapacity < requestedCapacity ? 1 : 0);
- return newCapacity < 0 ? Integer.MAX_VALUE : newCapacity;
- }
- /**
- * Creates a new instance. This is an empty constructor.
- */
- protected IoBuffer() {
- // Do nothing
+ return newCapacity < 0 ? Integer.MAX_VALUE : newCapacity;
}
/**
- * Declares this buffer and all its derived buffers are not used anymore so
- * that it can be reused by some {@link IoBufferAllocator} implementations.
- * It is not mandatory to call this method, but you might want to invoke
- * this method for maximum performance.
+ * Declares this buffer and all its derived buffers are not used anymore so that
+ * it can be reused by some {@link IoBufferAllocator} implementations. It is not
+ * mandatory to call this method, but you might want to invoke this method for
+ * maximum performance.
*/
public abstract void free();
/**
- * Returns the underlying NIO buffer instance.
+ * @return the underlying NIO {@link ByteBuffer} instance.
*/
public abstract ByteBuffer buf();
/**
* @see ByteBuffer#isDirect()
+ *
+ * @return True if this is a direct buffer
*/
public abstract boolean isDirect();
/**
- * returns true if and only if this buffer is derived from other
- * buffer via {@link #duplicate()}, {@link #slice()} or
- * {@link #asReadOnlyBuffer()}.
+ * @return true if and only if this buffer is derived from another
+ * buffer via one of the {@link #duplicate()}, {@link #slice()} or
+ * {@link #asReadOnlyBuffer()} methods.
*/
public abstract boolean isDerived();
/**
* @see ByteBuffer#isReadOnly()
+ *
+ * @return true if the buffer is readOnly
*/
public abstract boolean isReadOnly();
/**
- * Returns the minimum capacity of this buffer which is used to determine
- * the new capacity of the buffer shrunk by {@link #compact()} and
- * {@link #shrink()} operation. The default value is the initial capacity of
- * the buffer.
+ * @return the minimum capacity of this buffer which is used to determine the
+ * new capacity of the buffer shrunk by the {@link #compact()} and
+ * {@link #shrink()} operation. The default value is the initial
+ * capacity of the buffer.
*/
public abstract int minimumCapacity();
/**
- * Sets the minimum capacity of this buffer which is used to determine the
- * new capacity of the buffer shrunk by {@link #compact()} and
- * {@link #shrink()} operation. The default value is the initial capacity of
- * the buffer.
+ * Sets the minimum capacity of this buffer which is used to determine the new
+ * capacity of the buffer shrunk by {@link #compact()} and {@link #shrink()}
+ * operation. The default value is the initial capacity of the buffer.
+ *
+ * @param minimumCapacity the wanted minimum capacity
+ * @return the underlying NIO {@link ByteBuffer} instance.
*/
public abstract IoBuffer minimumCapacity(int minimumCapacity);
/**
* @see ByteBuffer#capacity()
+ *
+ * @return the buffer capacity
*/
public abstract int capacity();
/**
- * Increases the capacity of this buffer. If the new capacity is less than
- * or equal to the current capacity, this method returns silently. If the
- * new capacity is greater than the current capacity, the buffer is
- * reallocated while retaining the position, limit, mark and the content of
- * the buffer.
+ * Increases the capacity of this buffer. If the new capacity is less than or
+ * equal to the current capacity, this method returns the original buffer. If
+ * the new capacity is greater than the current capacity, the buffer is
+ * reallocated while retaining the position, limit, mark and the content of the
+ * buffer. + * Initial buffer : + * + * 0 L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit capacity + * + * V <= C : + * + * 0 L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit newCapacity + * + * V > C : + * + * 0 L C V + * +--------+-----------------------+ + * |XXXXXXXX| : | + * +--------+-----------------------+ + * ^ ^ ^ ^ + * | | | | + * pos limit oldCapacity newCapacity + * + * The buffer has been increased. + * + *+ * + * @param newCapacity the wanted capacity + * @return the underlying NIO {@link ByteBuffer} instance. */ public abstract IoBuffer capacity(int newCapacity); /** - * Returns true if and only if autoExpand is turned on. + * @return
true if and only if autoExpand is turned on.
*/
public abstract boolean isAutoExpand();
/**
- * Turns on or off autoExpand.
+ * Turns on or off autoExpand.
+ *
+ * @param autoExpand The flag value to set
+ * @return The modified IoBuffer instance
*/
public abstract IoBuffer setAutoExpand(boolean autoExpand);
/**
- * Returns true if and only if autoShrink is turned on.
+ * @return true if and only if autoShrink is turned on.
*/
public abstract boolean isAutoShrink();
/**
- * Turns on or off autoShrink.
+ * Turns on or off autoShrink.
+ *
+ * @param autoShrink The flag value to set
+ * @return The modified IoBuffer instance
*/
public abstract IoBuffer setAutoShrink(boolean autoShrink);
/**
* Changes the capacity and limit of this buffer so this buffer get the
- * specified expectedRemaining room from the current position. This
- * method works even if you didn't set autoExpand to true.
+ * specified expectedRemaining room from the current position. This
+ * method works even if you didn't set autoExpand to true.
+ * + * Initial buffer : + * + * 0 L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit capacity + * + * ( pos + V ) <= L, no change : + * + * 0 L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit newCapacity + * + * You can still put ( L - pos ) bytes in the buffer + * + * ( pos + V ) > L & ( pos + V ) <= C : + * + * 0 L C + * +------------+------+ + * |XXXXXXXX:...| | + * +------------+------+ + * ^ ^ ^ + * | | | + * pos newlimit newCapacity + * + * You can now put ( L - pos + V ) bytes in the buffer. + * + * + * ( pos + V ) > C + * + * 0 L C + * +-------------------+----+ + * |XXXXXXXX:..........:....| + * +------------------------+ + * ^ ^ + * | | + * pos +-- newlimit + * | + * +-- newCapacity + * + * You can now put ( L - pos + V ) bytes in the buffer, which limit is now + * equals to the capacity. + *+ * + * Note that the expecting remaining bytes starts at the current position. In + * all those examples, the position is 0. + * + * @param expectedRemaining The expected remaining bytes in the buffer + * @return The modified IoBuffer instance */ public abstract IoBuffer expand(int expectedRemaining); /** * Changes the capacity and limit of this buffer so this buffer get the - * specified expectedRemaining room from the specified - * position. This method works even if you didn't set - * autoExpand to true. + * specified
expectedRemaining room from the specified
+ * position. This method works even if you didn't set
+ * autoExpand to true. Assuming a buffer contains N bytes, its
+ * position is P and its current capacity is C, here are the resulting buffer if
+ * we call the expand method with a expectedRemaining value V :
+ *
+ * + * Initial buffer : + * + * P L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit capacity + * + * ( pos + V ) <= L, no change : + * + * P L C + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ + * | | | + * pos limit newCapacity + * + * You can still put ( L - pos ) bytes in the buffer + * + * ( pos + V ) > L & ( pos + V ) <= C : + * + * P L C + * +------------+------+ + * |XXXXXXXX:...| | + * +------------+------+ + * ^ ^ ^ + * | | | + * pos newlimit newCapacity + * + * You can now put ( L - pos + V) bytes in the buffer. + * + * + * ( pos + V ) > C + * + * P L C + * +-------------------+----+ + * |XXXXXXXX:..........:....| + * +------------------------+ + * ^ ^ + * | | + * pos +-- newlimit + * | + * +-- newCapacity + * + * You can now put ( L - pos + V ) bytes in the buffer, which limit is now + * equals to the capacity. + *+ * + * Note that the expecting remaining bytes starts at the current position. In + * all those examples, the position is P. + * + * @param position The starting position from which we want to define a + * remaining number of bytes + * @param expectedRemaining The expected remaining bytes in the buffer + * @return The modified IoBuffer instance */ public abstract IoBuffer expand(int position, int expectedRemaining); /** - * Changes the capacity of this buffer so this buffer occupies as less - * memory as possible while retaining the position, limit and the buffer - * content between the position and limit. The capacity of the buffer never - * becomes less than {@link #minimumCapacity()}. The mark is discarded once - * the capacity changes. + * Changes the capacity of this buffer so this buffer occupies as less memory as + * possible while retaining the position, limit and the buffer content between + * the position and limit.
+ * Initial buffer : + * + * +--------+----------+ + * |XXXXXXXX| | + * +--------+----------+ + * ^ ^ ^ ^ + * | | | | + * pos | | capacity + * | | + * | +-- minimumCapacity + * | + * +-- limit + * + * Resulting buffer : + * + * +--------+--+-+ + * |XXXXXXXX| | | + * +--------+--+-+ + * ^ ^ ^ ^ + * | | | | + * | | | +-- new capacity + * | | | + * pos | +-- minimum capacity + * | + * +-- limit + *+ * + * @return The modified IoBuffer instance */ public abstract IoBuffer shrink(); /** * @see java.nio.Buffer#position() + * @return The current position in the buffer */ public abstract int position(); /** * @see java.nio.Buffer#position(int) + * + * @param newPosition Sets the new position in the buffer + * @return the modified IoBuffer + * */ public abstract IoBuffer position(int newPosition); /** * @see java.nio.Buffer#limit() + * + * @return the modified IoBuffer 's limit */ public abstract int limit(); /** * @see java.nio.Buffer#limit(int) + * + * @param newLimit The new buffer's limit + * @return the modified IoBuffer + * */ public abstract IoBuffer limit(int newLimit); /** * @see java.nio.Buffer#mark() + * + * @return the modified IoBuffer + * */ public abstract IoBuffer mark(); /** - * Returns the position of the current mark. This method returns -1 - * if no mark is set. + * @return the position of the current mark. This method returns
-1 if
+ * no mark is set.
*/
public abstract int markValue();
/**
* @see java.nio.Buffer#reset()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer reset();
/**
* @see java.nio.Buffer#clear()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer clear();
/**
- * Clears this buffer and fills its content with NUL. The position
- * is set to zero, the limit is set to the capacity, and the mark is
- * discarded.
+ * Clears this buffer and fills its content with NUL. The position is
+ * set to zero, the limit is set to the capacity, and the mark is discarded.
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer sweep();
/**
- * double Clears this buffer and fills its content with value. The
- * position is set to zero, the limit is set to the capacity, and the mark
- * is discarded.
+ * double Clears this buffer and fills its content with value. The
+ * position is set to zero, the limit is set to the capacity, and the mark is
+ * discarded.
+ *
+ * @param value The value to put in the buffer
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer sweep(byte value);
/**
* @see java.nio.Buffer#flip()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer flip();
/**
* @see java.nio.Buffer#rewind()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer rewind();
/**
* @see java.nio.Buffer#remaining()
+ *
+ * @return The remaining bytes in the buffer
*/
public abstract int remaining();
/**
* @see java.nio.Buffer#hasRemaining()
+ *
+ * @return true if there are some remaining bytes in the buffer
*/
public abstract boolean hasRemaining();
/**
* @see ByteBuffer#duplicate()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer duplicate();
/**
* @see ByteBuffer#slice()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer slice();
/**
* @see ByteBuffer#asReadOnlyBuffer()
+ *
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer asReadOnlyBuffer();
/**
* @see ByteBuffer#hasArray()
+ *
+ * @return true if the {@link #array()} method will return a byte[]
*/
public abstract boolean hasArray();
/**
* @see ByteBuffer#array()
+ *
+ * @return A byte[] if this IoBuffer supports it
*/
public abstract byte[] array();
/**
* @see ByteBuffer#arrayOffset()
+ *
+ * @return The offset in the returned byte[] when the {@link #array()} method is
+ * called
*/
public abstract int arrayOffset();
/**
* @see ByteBuffer#get()
+ *
+ * @return The byte at the current position
*/
public abstract byte get();
/**
* Reads one unsigned byte as a short integer.
+ *
+ * @return the unsigned short at the current position
*/
public abstract short getUnsigned();
/**
* @see ByteBuffer#put(byte)
+ *
+ * @param b The byte to put in the buffer
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer put(byte b);
/**
* @see ByteBuffer#get(int)
+ *
+ * @param index The position for which we want to read a byte
+ * @return the byte at the given position
*/
public abstract byte get(int index);
/**
* Reads one byte as an unsigned short integer.
+ *
+ * @param index The position for which we want to read an unsigned byte
+ * @return the unsigned byte at the given position
*/
public abstract short getUnsigned(int index);
/**
* @see ByteBuffer#put(int, byte)
+ *
+ * @param index The position where the byte will be put
+ * @param b The byte to put
+ * @return the modified IoBuffer
+ *
*/
public abstract IoBuffer put(int index, byte b);
/**
* @see ByteBuffer#get(byte[], int, int)
+ *
+ * @param dst The destination buffer
+ * @param offset The position in the original buffer
+ * @param length The number of bytes to copy
+ * @return the modified IoBuffer
*/
public abstract IoBuffer get(byte[] dst, int offset, int length);
/**
* @see ByteBuffer#get(byte[])
+ *
+ * @param dst The byte[] that will contain the read bytes
+ * @return the IoBuffer
*/
public abstract IoBuffer get(byte[] dst);
/**
- * TODO document me.
+ * Get a new IoBuffer containing a slice of the current buffer
+ *
+ * @param index The position in the buffer
+ * @param length The number of bytes to copy
+ * @return the new IoBuffer
*/
public abstract IoBuffer getSlice(int index, int length);
/**
- * TODO document me.
+ * Get a new IoBuffer containing a slice of the current buffer
+ *
+ * @param length The number of bytes to copy
+ * @return the new IoBuffer
*/
public abstract IoBuffer getSlice(int length);
/**
- * Writes the content of the specified src into this buffer.
+ * Writes the content of the specified src into this buffer.
+ *
+ * @param src The source ByteBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer put(ByteBuffer src);
/**
- * Writes the content of the specified src into this buffer.
+ * Writes the content of the specified src into this buffer.
+ *
+ * @param src The source IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer put(IoBuffer src);
/**
* @see ByteBuffer#put(byte[], int, int)
+ *
+ * @param src The byte[] to put
+ * @param offset The position in the source
+ * @param length The number of bytes to copy
+ * @return the modified IoBuffer
*/
public abstract IoBuffer put(byte[] src, int offset, int length);
/**
* @see ByteBuffer#put(byte[])
+ *
+ * @param src The byte[] to put
+ * @return the modified IoBuffer
*/
public abstract IoBuffer put(byte[] src);
/**
* @see ByteBuffer#compact()
+ *
+ * @return the modified IoBuffer
*/
public abstract IoBuffer compact();
/**
* @see ByteBuffer#order()
+ *
+ * @return the IoBuffer ByteOrder
*/
public abstract ByteOrder order();
/**
* @see ByteBuffer#order(ByteOrder)
+ *
+ * @param bo The new ByteBuffer to use for this IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer order(ByteOrder bo);
/**
* @see ByteBuffer#getChar()
+ *
+ * @return The char at the current position
*/
public abstract char getChar();
/**
* @see ByteBuffer#putChar(char)
+ *
+ * @param value The char to put at the current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putChar(char value);
/**
* @see ByteBuffer#getChar(int)
+ *
+ * @param index The index in the IoBuffer where we will read a char from
+ * @return the char at 'index' position
*/
public abstract char getChar(int index);
/**
* @see ByteBuffer#putChar(int, char)
+ *
+ * @param index The index in the IoBuffer where we will put a char in
+ * @param value The char to put at the current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putChar(int index, char value);
/**
* @see ByteBuffer#asCharBuffer()
+ *
+ * @return a new CharBuffer
*/
public abstract CharBuffer asCharBuffer();
/**
* @see ByteBuffer#getShort()
+ *
+ * @return The read short
*/
public abstract short getShort();
/**
* Reads two bytes unsigned integer.
+ *
+ * @return The read unsigned short
*/
public abstract int getUnsignedShort();
/**
* @see ByteBuffer#putShort(short)
+ *
+ * @param value The short to put at the current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putShort(short value);
/**
* @see ByteBuffer#getShort()
+ *
+ * @param index The index in the IoBuffer where we will read a short from
+ * @return The read short
*/
public abstract short getShort(int index);
/**
* Reads two bytes unsigned integer.
+ *
+ * @param index The index in the IoBuffer where we will read an unsigned short
+ * from
+ * @return the unsigned short at the given position
*/
public abstract int getUnsignedShort(int index);
/**
* @see ByteBuffer#putShort(int, short)
+ *
+ * @param index The position at which the short should be written
+ * @param value The short to put at the current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putShort(int index, short value);
/**
* @see ByteBuffer#asShortBuffer()
+ *
+ * @return A ShortBuffer from this IoBuffer
*/
public abstract ShortBuffer asShortBuffer();
/**
* @see ByteBuffer#getInt()
+ *
+ * @return The int read
*/
public abstract int getInt();
/**
* Reads four bytes unsigned integer.
+ *
+ * @return The unsigned int read
*/
public abstract long getUnsignedInt();
@@ -639,10 +1025,9 @@ protected IoBuffer() {
* Relative get method for reading a medium int value.
*
* - * Reads the next three bytes at this buffer's current position, composing - * them into an int value according to the current byte order, and then - * increments the position by three. - *
+ * Reads the next three bytes at this buffer's current position, composing them + * into an int value according to the current byte order, and then increments + * the position by three. * * @return The medium int value at the buffer's current position */ @@ -652,10 +1037,9 @@ protected IoBuffer() { * Relative get method for reading an unsigned medium int value. * *- * Reads the next three bytes at this buffer's current position, composing - * them into an int value according to the current byte order, and then - * increments the position by three. - *
+ * Reads the next three bytes at this buffer's current position, composing them + * into an int value according to the current byte order, and then increments + * the position by three. * * @return The unsigned medium int value at the buffer's current position */ @@ -665,17 +1049,14 @@ protected IoBuffer() { * Absolute get method for reading a medium int value. * *- * Reads the next three bytes at this buffer's current position, composing - * them into an int value according to the current byte order. - *
+ * Reads the next three bytes at this buffer's current position, composing them + * into an int value according to the current byte order. * - * @param index - * The index from which the medium int will be read + * @param index The index from which the medium int will be read * @return The medium int value at the given index * - * @throws IndexOutOfBoundsException - * If index is negative or not smaller than the - * buffer's limit + * @throws IndexOutOfBoundsException Ifindex is negative or not
+ * smaller than the buffer's limit
*/
public abstract int getMediumInt(int index);
@@ -683,17 +1064,14 @@ protected IoBuffer() {
* Absolute get method for reading an unsigned medium int value.
*
* - * Reads the next three bytes at this buffer's current position, composing - * them into an int value according to the current byte order. - *
+ * Reads the next three bytes at this buffer's current position, composing them + * into an int value according to the current byte order. * - * @param index - * The index from which the unsigned medium int will be read + * @param index The index from which the unsigned medium int will be read * @return The unsigned medium int value at the given index * - * @throws IndexOutOfBoundsException - * If index is negative or not smaller than the - * buffer's limit + * @throws IndexOutOfBoundsException Ifindex is negative or not
+ * smaller than the buffer's limit
*/
public abstract int getUnsignedMediumInt(int index);
@@ -701,21 +1079,13 @@ protected IoBuffer() {
* Relative put method for writing a medium int value.
*
* - * Writes three bytes containing the given int value, in the current byte - * order, into this buffer at the current position, and then increments the - * position by three. - *
- * - * @param value - * The medium int value to be written + * Writes three bytes containing the given int value, in the current byte order, + * into this buffer at the current position, and then increments the position by + * three. * - * @return This buffer + * @param value The medium int value to be written * - * @throws BufferOverflowException - * If there are fewer than three bytes remaining in this buffer - * - * @throws ReadOnlyBufferException - * If this buffer is read-only + * @return the modified IoBuffer */ public abstract IoBuffer putMediumInt(int value); @@ -723,141 +1093,419 @@ protected IoBuffer() { * Absolute put method for writing a medium int value. * *- * Writes three bytes containing the given int value, in the current byte - * order, into this buffer at the given index. - *
- * - * @param index - * The index at which the bytes will be written + * Writes three bytes containing the given int value, in the current byte order, + * into this buffer at the given index. * - * @param value - * The medium int value to be written + * @param index The index at which the bytes will be written * - * @return This buffer + * @param value The medium int value to be written * - * @throws IndexOutOfBoundsException - * If index is negative or not smaller than the - * buffer's limit, minus three + * @return the modified IoBuffer * - * @throws ReadOnlyBufferException - * If this buffer is read-only + * @throws IndexOutOfBoundsException Ifindex is negative or not
+ * smaller than the buffer's limit, minus
+ * three
*/
public abstract IoBuffer putMediumInt(int index, int value);
/**
* @see ByteBuffer#putInt(int)
+ *
+ * @param value The int to put at the current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putInt(int value);
+ /**
+ * Writes an unsigned byte into the ByteBuffer
+ *
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(byte value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(int index, byte value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer
+ *
+ * @param value the short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(short value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(int index, short value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer
+ *
+ * @param value the int to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(int value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the int to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(int index, int value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer
+ *
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(long value);
+
+ /**
+ * Writes an unsigned byte into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsigned(int index, long value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer
+ *
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(byte value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(int index, byte value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer
+ *
+ * @param value the short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(short value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(int index, short value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer
+ *
+ * @param value the int to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(int value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the int to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(int index, int value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer
+ *
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(long value);
+
+ /**
+ * Writes an unsigned int into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedInt(int index, long value);
+
+ /**
+ * Writes an unsigned short into the ByteBuffer
+ *
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(byte value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the byte to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(int index, byte value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer
+ *
+ * @param value the short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(short value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the unsigned short
+ * @param value the unsigned short to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(int index, short value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer
+ *
+ * @param value the int to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(int value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the value
+ * @param value the int to write
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(int index, int value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer
+ *
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(long value);
+
+ /**
+ * Writes an unsigned Short into the ByteBuffer at a specified position
+ *
+ * @param index the position in the buffer to write the short
+ * @param value the long to write
+ *
+ * @return the modified IoBuffer
+ */
+ public abstract IoBuffer putUnsignedShort(int index, long value);
+
/**
* @see ByteBuffer#getInt(int)
+ * @param index The index in the IoBuffer where we will read an int from
+ * @return the int at the given position
*/
public abstract int getInt(int index);
/**
* Reads four bytes unsigned integer.
+ *
+ * @param index The index in the IoBuffer where we will read an unsigned int
+ * from
+ * @return The long at the given position
*/
public abstract long getUnsignedInt(int index);
/**
* @see ByteBuffer#putInt(int, int)
+ *
+ * @param index The position where to put the int
+ * @param value The int to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putInt(int index, int value);
/**
* @see ByteBuffer#asIntBuffer()
+ *
+ * @return the modified IoBuffer
*/
public abstract IntBuffer asIntBuffer();
/**
* @see ByteBuffer#getLong()
+ *
+ * @return The long at the current position
*/
public abstract long getLong();
/**
* @see ByteBuffer#putLong(int, long)
+ *
+ * @param value The log to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putLong(long value);
/**
* @see ByteBuffer#getLong(int)
+ *
+ * @param index The index in the IoBuffer where we will read a long from
+ * @return the long at the given position
*/
public abstract long getLong(int index);
/**
* @see ByteBuffer#putLong(int, long)
+ *
+ * @param index The position where to put the long
+ * @param value The long to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putLong(int index, long value);
/**
* @see ByteBuffer#asLongBuffer()
+ *
+ * @return a LongBuffer from this IoBffer
*/
public abstract LongBuffer asLongBuffer();
/**
* @see ByteBuffer#getFloat()
+ *
+ * @return the float at the current position
*/
public abstract float getFloat();
/**
* @see ByteBuffer#putFloat(float)
+ *
+ * @param value The float to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putFloat(float value);
/**
* @see ByteBuffer#getFloat(int)
+ *
+ * @param index The index in the IoBuffer where we will read a float from
+ * @return The float at the given position
*/
public abstract float getFloat(int index);
/**
* @see ByteBuffer#putFloat(int, float)
+ *
+ * @param index The position where to put the float
+ * @param value The float to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putFloat(int index, float value);
/**
* @see ByteBuffer#asFloatBuffer()
+ *
+ * @return A FloatBuffer from this IoBuffer
*/
public abstract FloatBuffer asFloatBuffer();
/**
* @see ByteBuffer#getDouble()
+ *
+ * @return the double at the current position
*/
public abstract double getDouble();
/**
* @see ByteBuffer#putDouble(double)
+ *
+ * @param value The double to put at the IoBuffer current position
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putDouble(double value);
/**
* @see ByteBuffer#getDouble(int)
+ *
+ * @param index The position where to get the double from
+ * @return The double at the given position
*/
public abstract double getDouble(int index);
/**
* @see ByteBuffer#putDouble(int, double)
+ *
+ * @param index The position where to put the double
+ * @param value The double to put in the IoBuffer
+ * @return the modified IoBuffer
*/
public abstract IoBuffer putDouble(int index, double value);
/**
* @see ByteBuffer#asDoubleBuffer()
+ *
+ * @return A buffer containing Double
*/
public abstract DoubleBuffer asDoubleBuffer();
/**
- * Returns an {@link InputStream} that reads the data from this buffer.
- * {@link InputStream#read()} returns -1 if the buffer position
- * reaches to the limit.
+ * @return an {@link InputStream} that reads the data from this buffer.
+ * {@link InputStream#read()} returns -1 if the buffer position
+ * reaches to the limit.
*/
public abstract InputStream asInputStream();
/**
- * Returns an {@link OutputStream} that appends the data into this buffer.
- * Please note that the {@link OutputStream#write(int)} will throw a
- * {@link BufferOverflowException} instead of an {@link IOException} in case
- * of buffer overflow. Please set autoExpand property by calling
- * {@link #setAutoExpand(boolean)} to prevent the unexpected runtime
- * exception.
+ * @return an {@link OutputStream} that appends the data into this buffer.
+ * Please note that the {@link OutputStream#write(int)} will throw a
+ * {@link BufferOverflowException} instead of an {@link IOException} in
+ * case of buffer overflow. Please set autoExpand property by
+ * calling {@link #setAutoExpand(boolean)} to prevent the unexpected
+ * runtime exception.
*/
public abstract OutputStream asOutputStream();
@@ -867,17 +1515,43 @@ protected IoBuffer() {
*
* @return hexidecimal representation of this buffer
*/
- public abstract String getHexDump();
+ public String getHexDump() {
+ return this.getHexDump(this.remaining(), false);
+ }
+
+ /**
+ * Returns hexdump of this buffer. The data and pointer are not changed as a
+ * result of this method call.
+ *
+ * @param pretty tells if the ourput should be verbose or not
+ * @return hexidecimal representation of this buffer
+ */
+ public String getHexDump(boolean pretty) {
+ return getHexDump(this.remaining(), pretty);
+ }
/**
* Return hexdump of this buffer with limited length.
*
- * @param lengthLimit
- * The maximum number of bytes to dump from the current buffer
- * position.
+ * @param length The maximum number of bytes to dump from the current buffer
+ * position.
* @return hexidecimal representation of this buffer
*/
- public abstract String getHexDump(int lengthLimit);
+ public String getHexDump(int length) {
+ return getHexDump(length, false);
+ }
+
+ /**
+ * Return hexdump of this buffer with limited length.
+ *
+ * @param length The maximum number of bytes to dump from the current buffer position.
+ * @param pretty tells if the output should be verbose or not
+ * @return hexadecimal representation of this buffer
+ */
+ public String getHexDump(int length, boolean pretty) {
+ return (pretty) ? IoBufferHexDumper.getPrettyHexDumpSlice(this, this.position(), Math.min(this.remaining(), length))
+ : IoBufferHexDumper.getHexDumpSlice(this, this.position(), Math.min(this.remaining(), length));
+ }
// //////////////////////////////
// String getters and putters //
@@ -885,8 +1559,13 @@ protected IoBuffer() {
/**
* Reads a NUL-terminated string from this buffer using the
- * specified decoder and returns it. This method reads until
- * the limit of this buffer if no NUL is found.
+ * specified decoder and returns it. This method reads until the
+ * limit of this buffer if no NUL is found.
+ *
+ * @param decoder The {@link CharsetDecoder} to use
+ * @return the read String
+ * @exception CharacterCodingException Thrown when an error occurred while
+ * decoding the buffer
*/
public abstract String getString(CharsetDecoder decoder) throws CharacterCodingException;
@@ -894,42 +1573,58 @@ protected IoBuffer() {
* Reads a NUL-terminated string from this buffer using the
* specified decoder and returns it.
*
- * @param fieldSize
- * the maximum number of bytes to read
+ * @param fieldSize the maximum number of bytes to read
+ * @param decoder The {@link CharsetDecoder} to use
+ * @return the read String
+ * @exception CharacterCodingException Thrown when an error occurred while
+ * decoding the buffer
*/
public abstract String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException;
/**
- * Writes the content of in into this buffer using the
- * specified encoder. This method doesn't terminate string with
- * NUL. You have to do it by yourself.
+ * Writes the content of in into this buffer using the specified
+ * encoder. This method doesn't terminate string with NUL.
+ * You have to do it by yourself.
*
- * @throws BufferOverflowException
- * if the specified string doesn't fit
+ * @param val The CharSequence to put in the IoBuffer
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
+ * @throws CharacterCodingException When we have an error while decoding the
+ * String
*/
public abstract IoBuffer putString(CharSequence val, CharsetEncoder encoder) throws CharacterCodingException;
/**
* Writes the content of in into this buffer as a
- * NUL-terminated string using the specified
- * encoder.
+ * NUL-terminated string using the specified encoder.
*
* If the charset name of the encoder is UTF-16, you cannot specify odd
- * fieldSize, and this method will append two NULs
- * as a terminator.
+ * fieldSize, and this method will append two NULs as
+ * a terminator.
*
- * Please note that this method doesn't terminate with NUL if
- * the input string is longer than fieldSize.
+ * Please note that this method doesn't terminate with NUL if the
+ * input string is longer than fieldSize.
*
- * @param fieldSize
- * the maximum number of bytes to write
+ * @param val The CharSequence to put in the IoBuffer
+ * @param fieldSize the maximum number of bytes to write
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
+ * @throws CharacterCodingException When we have an error while decoding the
+ * String
*/
- public abstract IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException;
+ public abstract IoBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder)
+ throws CharacterCodingException;
/**
* Reads a string which has a 16-bit length field before the actual encoded
- * string, using the specified decoder and returns it. This
- * method is a shortcut for getPrefixedString(2, decoder).
+ * string, using the specified decoder and returns it. This method
+ * is a shortcut for getPrefixedString(2, decoder).
+ *
+ * @param decoder The CharsetDecoder to use
+ * @return The read String
+ *
+ * @throws CharacterCodingException When we have an error while decoding the
+ * String
*/
public abstract String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException;
@@ -937,124 +1632,145 @@ protected IoBuffer() {
* Reads a string which has a length field before the actual encoded string,
* using the specified decoder and returns it.
*
- * @param prefixLength
- * the length of the length field (1, 2, or 4)
+ * @param prefixLength the length of the length field (1, 2, or 4)
+ * @param decoder The CharsetDecoder to use
+ * @return The read String
+ *
+ * @throws CharacterCodingException When we have an error while decoding the
+ * String
*/
public abstract String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException;
/**
- * Writes the content of in into this buffer as a string which
- * has a 16-bit length field before the actual encoded string, using the
- * specified encoder. This method is a shortcut for
- * putPrefixedString(in, 2, 0, encoder).
+ * Writes the content of in into this buffer as a string which has
+ * a 16-bit length field before the actual encoded string, using the specified
+ * encoder. This method is a shortcut for
+ * putPrefixedString(in, 2, 0, encoder).
+ *
+ * @param in The CharSequence to put in the IoBuffer
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
*
- * @throws BufferOverflowException
- * if the specified string doesn't fit
+ * @throws CharacterCodingException When we have an error while decoding the
+ * CharSequence
*/
public abstract IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException;
/**
- * Writes the content of in into this buffer as a string which
- * has a 16-bit length field before the actual encoded string, using the
- * specified encoder. This method is a shortcut for
- * putPrefixedString(in, prefixLength, 0, encoder).
+ * Writes the content of in into this buffer as a string which has
+ * a 16-bit length field before the actual encoded string, using the specified
+ * encoder. This method is a shortcut for
+ * putPrefixedString(in, prefixLength, 0, encoder).
*
- * @param prefixLength
- * the length of the length field (1, 2, or 4)
+ * @param in The CharSequence to put in the IoBuffer
+ * @param prefixLength the length of the length field (1, 2, or 4)
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
*
- * @throws BufferOverflowException
- * if the specified string doesn't fit
+ * @throws CharacterCodingException When we have an error while decoding the
+ * CharSequence
*/
public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder)
throws CharacterCodingException;
/**
- * Writes the content of in into this buffer as a string which
- * has a 16-bit length field before the actual encoded string, using the
- * specified encoder. This method is a shortcut for
- * putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)
- * .
+ * Writes the content of in into this buffer as a string which has
+ * a 16-bit length field before the actual encoded string, using the specified
+ * encoder. This method is a shortcut for
+ * putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)
*
- * @param prefixLength
- * the length of the length field (1, 2, or 4)
- * @param padding
- * the number of padded NULs (1 (or 0), 2, or 4)
+ * @param in The CharSequence to put in the IoBuffer
+ * @param prefixLength the length of the length field (1, 2, or 4)
+ * @param padding the number of padded NULs (1 (or 0), 2, or 4)
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
*
- * @throws BufferOverflowException
- * if the specified string doesn't fit
+ * @throws CharacterCodingException When we have an error while decoding the
+ * CharSequence
*/
public abstract IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
throws CharacterCodingException;
/**
- * Writes the content of in into this buffer as a string which
- * has a 16-bit length field before the actual encoded string, using the
- * specified encoder.
- *
- * @param prefixLength
- * the length of the length field (1, 2, or 4)
- * @param padding
- * the number of padded bytes (1 (or 0), 2, or 4)
- * @param padValue
- * the value of padded bytes
+ * Writes the content of val into this buffer as a string which has
+ * a 16-bit length field before the actual encoded string, using the specified
+ * encoder.
*
- * @throws BufferOverflowException
- * if the specified string doesn't fit
+ * @param val The CharSequence to put in teh IoBuffer
+ * @param prefixLength the length of the length field (1, 2, or 4)
+ * @param padding the number of padded bytes (1 (or 0), 2, or 4)
+ * @param padValue the value of padded bytes
+ * @param encoder The CharsetEncoder to use
+ * @return The modified IoBuffer
+ * @throws CharacterCodingException When we have an error while decoding the
+ * CharSequence
*/
public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue,
CharsetEncoder encoder) throws CharacterCodingException;
/**
- * Reads a Java object from the buffer using the context {@link ClassLoader}
- * of the current thread.
+ * Reads a Java object from the buffer using the context {@link ClassLoader} of
+ * the current thread.
+ *
+ * See {@link #putObject(Object)} for how the serialized form differs
+ * across MINA versions.
+ *
+ * @return The read Object
+ * @throws ClassNotFoundException thrown when we can't find the Class to use
*/
public abstract Object getObject() throws ClassNotFoundException;
/**
- * Reads a Java object from the buffer using the specified
- * classLoader.
+ * Reads a Java object from the buffer using the specified classLoader.
+ *
+ * See {@link #putObject(Object)} for how the serialized form differs + * across MINA versions. + * + * @param classLoader The classLoader to use to read an Object from the IoBuffer + * @return The read Object + * @throws ClassNotFoundException thrown when we can't find the Class to use */ public abstract Object getObject(final ClassLoader classLoader) throws ClassNotFoundException; /** * Writes the specified Java object to the buffer. + * + *
+ * The serialized form of Serializable objects changed in MINA 2.2.8, as
+ * part of the CVE-2026-47065 fix: a stream produced by MINA 2.2.7 or
+ * earlier cannot be read by MINA 2.2.8 or later, and a stream produced by
+ * MINA 2.2.8 or later cannot be read by MINA 2.2.7 or earlier. Arrays and
+ * primitives are not affected.
+ *
+ * @param o The Object to write in the IoBuffer
+ * @return The modified IoBuffer
*/
public abstract IoBuffer putObject(Object o);
/**
- * Returns true if this buffer contains a data which has a data
- * length as a prefix and the buffer has remaining data as enough as
- * specified in the data length field. This method is identical with
- * prefixedDataAvailable( prefixLength, Integer.MAX_VALUE ). Please
- * not that using this method can allow DoS (Denial of Service) attack in
- * case the remote peer sends too big data length value. It is recommended
- * to use {@link #prefixedDataAvailable(int, int)} instead.
- *
- * @param prefixLength
- * the length of the prefix field (1, 2, or 4)
*
- * @throws IllegalArgumentException
- * if prefixLength is wrong
- * @throws BufferDataException
- * if data length is negative
+ * @param prefixLength the length of the prefix field (1, 2, or 4)
+ * @return
- * Each bit is mapped to a value in the specified enum. The least
- * significant bit maps to the first entry in the specified enum and each
- * subsequent bit maps to each subsequent bit as mapped to the subsequent
- * enum value.
- *
- * You can think this class like a {@link FilterOutputStream}. All operations
- * are proxied by default so that you can extend this class and override existing
- * operations selectively. You can introduce new operations, too.
+ * You can think this class like a {@link FileOutputStream}. All operations are
+ * proxied by default so that you can extend this class and override existing
+ * operations selectively. You can introduce new operations, too.
*
* @author Apache MINA Project
*/
@@ -54,6 +59,7 @@ public class IoBufferWrapper extends IoBuffer {
/**
* Create a new instance.
+ *
* @param buf the buffer to be proxied
*/
protected IoBufferWrapper(IoBuffer buf) {
@@ -62,730 +68,1242 @@ protected IoBufferWrapper(IoBuffer buf) {
}
this.buf = buf;
}
-
+
/**
- * Returns the parent buffer that this buffer wrapped.
+ * @return the parent buffer that this buffer wrapped.
*/
public IoBuffer getParentBuffer() {
return buf;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isDirect() {
return buf.isDirect();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public ByteBuffer buf() {
return buf.buf();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int capacity() {
return buf.capacity();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int position() {
return buf.position();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer position(int newPosition) {
buf.position(newPosition);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int limit() {
return buf.limit();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer limit(int newLimit) {
buf.limit(newLimit);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer mark() {
buf.mark();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer reset() {
buf.reset();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer clear() {
buf.clear();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer sweep() {
buf.sweep();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer sweep(byte value) {
buf.sweep(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer flip() {
buf.flip();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer rewind() {
buf.rewind();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int remaining() {
return buf.remaining();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean hasRemaining() {
return buf.hasRemaining();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public byte get() {
return buf.get();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public short getUnsigned() {
return buf.getUnsigned();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(byte b) {
buf.put(b);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public byte get(int index) {
return buf.get(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public short getUnsigned(int index) {
return buf.getUnsigned(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(int index, byte b) {
buf.put(index, b);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer get(byte[] dst, int offset, int length) {
buf.get(dst, offset, length);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer getSlice(int index, int length) {
return buf.getSlice(index, length);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer getSlice(int length) {
return buf.getSlice(length);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer get(byte[] dst) {
buf.get(dst);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(IoBuffer src) {
buf.put(src);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(ByteBuffer src) {
buf.put(src);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(byte[] src, int offset, int length) {
buf.put(src, offset, length);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer put(byte[] src) {
buf.put(src);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer compact() {
buf.compact();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String toString() {
return buf.toString();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int hashCode() {
return buf.hashCode();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean equals(Object ob) {
return buf.equals(ob);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public int compareTo(IoBuffer that) {
return buf.compareTo(that);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public ByteOrder order() {
return buf.order();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer order(ByteOrder bo) {
buf.order(bo);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public char getChar() {
return buf.getChar();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putChar(char value) {
buf.putChar(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public char getChar(int index) {
return buf.getChar(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putChar(int index, char value) {
buf.putChar(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public CharBuffer asCharBuffer() {
return buf.asCharBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public short getShort() {
return buf.getShort();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getUnsignedShort() {
return buf.getUnsignedShort();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putShort(short value) {
buf.putShort(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public short getShort(int index) {
return buf.getShort(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getUnsignedShort(int index) {
return buf.getUnsignedShort(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putShort(int index, short value) {
buf.putShort(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public ShortBuffer asShortBuffer() {
return buf.asShortBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getInt() {
return buf.getInt();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getUnsignedInt() {
return buf.getUnsignedInt();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putInt(int value) {
buf.putInt(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(byte value) {
+ buf.putUnsignedInt(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(int index, byte value) {
+ buf.putUnsignedInt(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(short value) {
+ buf.putUnsignedInt(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(int index, short value) {
+ buf.putUnsignedInt(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(int value) {
+ buf.putUnsignedInt(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(int index, int value) {
+ buf.putUnsignedInt(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(long value) {
+ buf.putUnsignedInt(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedInt(int index, long value) {
+ buf.putUnsignedInt(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(byte value) {
+ buf.putUnsignedShort(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(int index, byte value) {
+ buf.putUnsignedShort(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(short value) {
+ buf.putUnsignedShort(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(int index, short value) {
+ buf.putUnsignedShort(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(int value) {
+ buf.putUnsignedShort(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(int index, int value) {
+ buf.putUnsignedShort(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(long value) {
+ buf.putUnsignedShort(value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IoBuffer putUnsignedShort(int index, long value) {
+ buf.putUnsignedShort(index, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getInt(int index) {
return buf.getInt(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getUnsignedInt(int index) {
return buf.getUnsignedInt(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putInt(int index, int value) {
buf.putInt(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IntBuffer asIntBuffer() {
return buf.asIntBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getLong() {
return buf.getLong();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putLong(long value) {
buf.putLong(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getLong(int index) {
return buf.getLong(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putLong(int index, long value) {
buf.putLong(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public LongBuffer asLongBuffer() {
return buf.asLongBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public float getFloat() {
return buf.getFloat();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putFloat(float value) {
buf.putFloat(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public float getFloat(int index) {
return buf.getFloat(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putFloat(int index, float value) {
buf.putFloat(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public FloatBuffer asFloatBuffer() {
return buf.asFloatBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public double getDouble() {
return buf.getDouble();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putDouble(double value) {
buf.putDouble(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public double getDouble(int index) {
return buf.getDouble(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putDouble(int index, double value) {
buf.putDouble(index, value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public DoubleBuffer asDoubleBuffer() {
return buf.asDoubleBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String getHexDump() {
- return buf.getHexDump();
- }
-
- @Override
- public String getString(int fieldSize, CharsetDecoder decoder)
- throws CharacterCodingException {
+ public String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException {
return buf.getString(fieldSize, decoder);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String getString(CharsetDecoder decoder)
- throws CharacterCodingException {
+ public String getString(CharsetDecoder decoder) throws CharacterCodingException {
return buf.getString(decoder);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String getPrefixedString(CharsetDecoder decoder)
- throws CharacterCodingException {
+ public String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException {
return buf.getPrefixedString(decoder);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String getPrefixedString(int prefixLength, CharsetDecoder decoder)
- throws CharacterCodingException {
+ public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException {
return buf.getPrefixedString(prefixLength, decoder);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putString(CharSequence in, int fieldSize,
- CharsetEncoder encoder) throws CharacterCodingException {
+ public IoBuffer putString(CharSequence in, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException {
buf.putString(in, fieldSize, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putString(CharSequence in, CharsetEncoder encoder)
- throws CharacterCodingException {
+ public IoBuffer putString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
buf.putString(in, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder)
- throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
buf.putPrefixedString(in, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
- CharsetEncoder encoder) throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder)
+ throws CharacterCodingException {
buf.putPrefixedString(in, prefixLength, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
- int padding, CharsetEncoder encoder)
+ public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
throws CharacterCodingException {
buf.putPrefixedString(in, prefixLength, padding, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public IoBuffer putPrefixedString(CharSequence in, int prefixLength,
- int padding, byte padValue, CharsetEncoder encoder)
- throws CharacterCodingException {
+ public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, byte padValue,
+ CharsetEncoder encoder) throws CharacterCodingException {
buf.putPrefixedString(in, prefixLength, padding, padValue, encoder);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer skip(int size) {
buf.skip(size);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer fill(byte value, int size) {
buf.fill(value, size);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer fillAndReset(byte value, int size) {
buf.fillAndReset(value, size);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer fill(int size) {
buf.fill(size);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer fillAndReset(int size) {
buf.fillAndReset(size);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isAutoExpand() {
return buf.isAutoExpand();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer setAutoExpand(boolean autoExpand) {
buf.setAutoExpand(autoExpand);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer expand(int pos, int expectedRemaining) {
buf.expand(pos, expectedRemaining);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer expand(int expectedRemaining) {
buf.expand(expectedRemaining);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Object getObject() throws ClassNotFoundException {
return buf.getObject();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public Object getObject(ClassLoader classLoader)
- throws ClassNotFoundException {
+ public Object getObject(ClassLoader classLoader) throws ClassNotFoundException {
return buf.getObject(classLoader);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putObject(Object o) {
buf.putObject(o);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public InputStream asInputStream() {
return buf.asInputStream();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public OutputStream asOutputStream() {
return buf.asOutputStream();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer duplicate() {
return buf.duplicate();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer slice() {
return buf.slice();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer asReadOnlyBuffer() {
return buf.asReadOnlyBuffer();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public byte[] array() {
return buf.array();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int arrayOffset() {
return buf.arrayOffset();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int minimumCapacity() {
return buf.minimumCapacity();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer minimumCapacity(int minimumCapacity) {
buf.minimumCapacity(minimumCapacity);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer capacity(int newCapacity) {
buf.capacity(newCapacity);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isReadOnly() {
return buf.isReadOnly();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int markValue() {
return buf.markValue();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean hasArray() {
return buf.hasArray();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void free() {
buf.free();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isDerived() {
return buf.isDerived();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isAutoShrink() {
return buf.isAutoShrink();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer setAutoShrink(boolean autoShrink) {
buf.setAutoShrink(autoShrink);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer shrink() {
buf.shrink();
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getMediumInt() {
return buf.getMediumInt();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getUnsignedMediumInt() {
return buf.getUnsignedMediumInt();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getMediumInt(int index) {
return buf.getMediumInt(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int getUnsignedMediumInt(int index) {
return buf.getUnsignedMediumInt(index);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putMediumInt(int value) {
buf.putMediumInt(value);
return this;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public IoBuffer putMediumInt(int index, int value) {
buf.putMediumInt(index, value);
return this;
}
- @Override
- public String getHexDump(int lengthLimit) {
- return buf.getHexDump(lengthLimit);
- }
-
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean prefixedDataAvailable(int prefixLength) {
return buf.prefixedDataAvailable(prefixLength);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean prefixedDataAvailable(int prefixLength, int maxDataLength) {
return buf.prefixedDataAvailable(prefixLength, maxDataLength);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int indexOf(byte b) {
return buf.indexOf(b);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public
+ * The starting point of any operation is {@link #getCurrent()} which gets you the enum for the file system that matches
+ * the OS hosting the running JVM.
+ *
+ * The reserved characters are defined in the
+ * Naming Conventions
+ * (microsoft.com).
+ *
+ * Is {@code true} if this is Linux.
+ *
+ * The field will return {@code false} if {@code OS_NAME} is {@code null}.
+ *
+ * Is {@code true} if this is Mac.
+ *
+ * The field will return {@code false} if {@code OS_NAME} is {@code null}.
+ *
+ * Is {@code true} if this is Windows.
+ *
+ * The field will return {@code false} if {@code OS_NAME} is {@code null}.
+ *
+ * Gets a System property, defaulting to {@code null} if the property cannot be read.
+ *
+ * If a {@link SecurityException} is caught, the return value is {@code null} and a message is written to
+ * {@code System.err}.
+ *
+ * If a character with value {@code searchChar} occurs in the
+ * character sequence represented by the {@code cs}
+ * object at an index no smaller than {@code start}, then
+ * the index of the first such occurrence is returned. For values
+ * of {@code searchChar} in the range from 0 to 0xFFFF (inclusive),
+ * this is the smallest value k such that:
+ *
+ * is true. In either case, if no such character occurs inm {@code cs}
+ * at or after position {@code start}, then
+ * {@code -1} is returned.
+ *
+ * There is no restriction on the value of {@code start}. If it
+ * is negative, it has the same effect as if it were zero: the entire
+ * {@link CharSequence} may be searched. If it is greater than
+ * the length of {@code cs}, it has the same effect as if it were
+ * equal to the length of {@code cs}: {@code -1} is returned.
+ * All indices are specified in {@code char} values
+ * (Unicode code units).
+ *
+ * This method is package private instead of private to support unit test invocation.
+ *
+ * Windows supports driver letters as do other operating systems. Whether these other OS's still support Java like
+ * OS/2, is a different matter.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple (zero or more) wildcard characters.
+ * N.B. the sequence "*?" does not work properly at present in match strings.
+ *
+ * @param fileName the fileName to match on
+ * @param wildcardMatcher the wildcard string to match against
+ * @param ioCase what case sensitivity rule to use, null means case-sensitive
+ * @return true if the fileName matches the wildcard string
+ * @since 1.3
+ */
+ public static boolean wildcardMatch(final String fileName, final String wildcardMatcher, IOCase ioCase) {
+ if (fileName == null && wildcardMatcher == null) {
+ return true;
+ }
+ if (fileName == null || wildcardMatcher == null) {
+ return false;
+ }
+ ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
+ final String[] wcs = splitOnTokens(wildcardMatcher);
+ boolean anyChars = false;
+ int textIdx = 0;
+ int wcsIdx = 0;
+ final Deque
+ * This object is immutable and thread-safe.
+ *
+ * Different filing systems have different rules for case-sensitivity.
+ * Windows is case-insensitive, Unix is case-sensitive.
+ *
+ * This class captures that difference, providing an enumeration to
+ * control how file name comparisons should be performed. It also provides
+ * methods that use the enumeration to perform comparisons.
+ *
+ * Wherever possible, you should use the {@code check} methods in this
+ * class to compare file names.
+ *
+ * Note: This only caters for Windows and Unix. Other operating
+ * systems (e.g. OSX and OpenVMS) are treated as case-sensitive if they use the
+ * Unix file separator and case-insensitive if they use the Windows file separator
+ * (see {@link java.io.File#separatorChar}).
+ *
+ * If you serialize this constant on Windows, and deserialize on Unix, or vice
+ * versa, then the value of the case-sensitivity flag will change.
+ *
+ * This method mimics {@link String#compareTo} but takes case-sensitivity
+ * into account.
+ *
+ * This method mimics {@link String#endsWith} but takes case-sensitivity
+ * into account.
+ *
+ * This method mimics {@link String#equals} but takes case-sensitivity
+ * into account.
+ *
+ * This method mimics parts of {@link String#indexOf(String, int)}
+ * but takes case-sensitivity into account.
+ *
+ * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)}
+ * but takes case-sensitivity into account.
+ *
+ * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
+ * into account.
+ *
+ * This object is immutable and thread-safe.
+ *
+ * This object is immutable and thread-safe.
+ *
* When you add an {@link IoFilter} to an {@link IoFilterChain}:
@@ -82,6 +83,8 @@ public interface IoFilter {
* is added to a {@link IoFilterChain} at the first time, so you can
* initialize shared resources. Please note that this method is never
* called if you don't wrap a filter with {@link ReferenceCountingFilter}.
+ *
+ * @throws Exception If an error occurred while processing the event
*/
void init() throws Exception;
@@ -90,11 +93,13 @@ public interface IoFilter {
* is not used by any {@link IoFilterChain} anymore, so you can destroy
* shared resources. Please note that this method is never called if
* you don't wrap a filter with {@link ReferenceCountingFilter}.
+ *
+ * @throws Exception If an error occurred while processing the event
*/
void destroy() throws Exception;
/**
- * Invoked before this filter is added to the specified parent.
+ * Invoked before this filter is added to the specified true if this buffer contains a data which has a data length
+ * as a prefix and the buffer has remaining data as enough as specified
+ * in the data length field. This method is identical with
+ * prefixedDataAvailable( prefixLength, Integer.MAX_VALUE ).
+ * Please not that using this method can allow DoS (Denial of Service)
+ * attack in case the remote peer sends too big data length value. It is
+ * recommended to use {@link #prefixedDataAvailable(int, int)} instead.
+ * @throws IllegalArgumentException if prefixLength is wrong
+ * @throws BufferDataException if data length is negative
*/
public abstract boolean prefixedDataAvailable(int prefixLength);
/**
- * Returns true if this buffer contains a data which has a data
- * length as a prefix and the buffer has remaining data as enough as
- * specified in the data length field.
- *
- * @param prefixLength
- * the length of the prefix field (1, 2, or 4)
- * @param maxDataLength
- * the allowed maximum of the read data length
- *
- * @throws IllegalArgumentException
- * if prefixLength is wrong
- * @throws BufferDataException
- * if data length is negative or greater then
- * maxDataLength
+ * @param prefixLength the length of the prefix field (1, 2, or 4)
+ * @param maxDataLength the allowed maximum of the read data length
+ * @return true if this buffer contains a data which has a data length
+ * as a prefix and the buffer has remaining data as enough as specified
+ * in the data length field.
+ * @throws IllegalArgumentException if prefixLength is wrong
+ * @throws BufferDataException if data length is negative or greater then
+ * maxDataLength
*/
public abstract boolean prefixedDataAvailable(int prefixLength, int maxDataLength);
@@ -1063,10 +1779,11 @@ public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, i
// ///////////////////
/**
- * Returns the first occurence position of the specified byte from the
- * current position to the current limit.
- *
- * @return -1 if the specified byte is not found
+ * Returns the first occurrence position of the specified byte from the current
+ * position to the current limit.
+ *
+ * @param b The byte we are looking for
+ * @return -1 if the specified byte is not found
*/
public abstract int indexOf(byte b);
@@ -1077,30 +1794,47 @@ public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, i
/**
* Forwards the position of this buffer as the specified size
* bytes.
+ *
+ * @param size The added size
+ * @return The modified IoBuffer
*/
public abstract IoBuffer skip(int size);
/**
- * Fills this buffer with the specified value. This method moves buffer
- * position forward.
+ * Fills this buffer with the specified value. This method moves buffer position
+ * forward.
+ *
+ * @param value The value to fill the IoBuffer with
+ * @param size The added size
+ * @return The modified IoBuffer
*/
public abstract IoBuffer fill(byte value, int size);
/**
* Fills this buffer with the specified value. This method does not change
* buffer position.
+ *
+ * @param value The value to fill the IoBuffer with
+ * @param size The added size
+ * @return The modified IoBuffer
*/
public abstract IoBuffer fillAndReset(byte value, int size);
/**
* Fills this buffer with NUL (0x00). This method moves buffer
* position forward.
+ *
+ * @param size The added size
+ * @return The modified IoBuffer
*/
public abstract IoBuffer fill(int size);
/**
- * Fills this buffer with NUL (0x00). This method does not
- * change buffer position.
+ * Fills this buffer with NUL (0x00). This method does not change
+ * buffer position.
+ *
+ * @param size The added size
+ * @return The modified IoBuffer
*/
public abstract IoBuffer fillAndReset(int size);
@@ -1112,10 +1846,9 @@ public abstract IoBuffer putPrefixedString(CharSequence val, int prefixLength, i
* Reads a byte from the buffer and returns the correlating enum constant
* defined by the specified enum type.
*
- * @param true to get a direct buffer,
+ * false to get a heap buffer.
+ * @return The allocated {@link IoBuffer}
*/
IoBuffer allocate(int capacity, boolean direct);
@@ -41,13 +42,17 @@ public interface IoBufferAllocator {
* Returns the NIO buffer which is capable of the specified size.
*
* @param capacity the capacity of the buffer
- * @param direct true to get a direct buffer,
- * false to get a heap buffer.
+ * @param direct true to get a direct buffer,
+ * false to get a heap buffer.
+ * @return The allocated {@link ByteBuffer}
*/
ByteBuffer allocateNioBuffer(int capacity, boolean direct);
/**
* Wraps the specified NIO {@link ByteBuffer} into MINA buffer.
+ *
+ * @param nioBuffer The {@link ByteBuffer} to wrap
+ * @return The {@link IoBuffer} wrapping the {@link ByteBuffer}
*/
IoBuffer wrap(ByteBuffer nioBuffer);
diff --git a/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferHexDumper.java b/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferHexDumper.java
index 843b129062..18683a33a8 100644
--- a/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferHexDumper.java
+++ b/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferHexDumper.java
@@ -19,92 +19,216 @@
*/
package org.apache.mina.core.buffer;
+import java.io.UnsupportedEncodingException;
+
/**
- * Provides utility methods to dump an {@link IoBuffer} into a hex formatted string.
+ * Provides utility methods to dump an {@link IoBuffer} into a hex formatted
+ * string.
*
* @author Apache MINA Project
*/
class IoBufferHexDumper {
/**
- * The high digits lookup table.
+ * Dumps an {@link IoBuffer} to a hex formatted string.
+ *
+ * @param buf the buffer to dump
+ * @param offset the starting position to begin reading the hex dump
+ * @param length the number of bytes to dump
+ * @return a hex formatted string representation of the in
+ * {@link IoBuffer}.
*/
- private static final byte[] highDigits;
+ public static String getHexDumpSlice(final IoBuffer buf, final int offset, final int length) {
+ if (buf == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (length < 0 || offset < 0 || offset + length > buf.limit()) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ int pos = offset;
+ int items = Math.min(offset + length, offset + buf.limit()) - pos;
+
+ if (items <= 0) {
+ return "";
+ }
+
+ int lim = pos + items;
+
+ StringBuilder out = new StringBuilder((items * 3) + 6);
+
+ for (;;) {
+ int byteValue = buf.get(pos++) & 0xFF;
+ out.append((char) hexDigit[(byteValue >> 4) & 0x0F]);
+ out.append((char) hexDigit[byteValue & 0xf]);
+
+ if (pos < lim) {
+ out.append(' ');
+ } else {
+ break;
+ }
+ }
+
+ return out.toString();
+ }
/**
- * The low digits lookup table.
+ * Produces a verbose hex dump
+ *
+ * @param offset initial position which to read bytes
+ *
+ * @param length number of bytes to display
+ *
+ * @return The formatted String representing the content between (offset) and
+ * (offset+count)
*/
- private static final byte[] lowDigits;
+ public static final String getPrettyHexDumpSlice(final IoBuffer buf, final int offset, final int length) {
+ if (buf == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (length < 0 || offset < 0 || offset + length > buf.limit()) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ final int len = Math.min(length, buf.limit() - offset);
+ final byte[] bytes = new byte[len];
+
+ int o = offset;
+
+ for (int i = 0; i < len; i++) {
+ bytes[i] = buf.get(o++);
+ }
+
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("Source ");
+ sb.append("0x").append(Integer.toHexString(buf.hashCode()));
+ sb.append(" showing index ");
+ sb.append(offset);
+ sb.append(" through ");
+ sb.append((offset + length));
+ sb.append("\n");
+ sb.append(toPrettyHexDump(bytes, 0, bytes.length));
+
+ return sb.toString();
+ }
/**
- * Initialize lookup tables.
+ * Generates a hex dump with line numbers, hex, volumes, and ascii
+ * representation
+ *
+ * @param data source data to read for the hex dump
+ *
+ * @param pos index position to begin reading
+ *
+ * @param len number of bytes to read
+ *
+ * @return string hex dump
*/
- static {
- final byte[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
- '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ public static final String toPrettyHexDump(final byte[] data, final int pos, final int len) {
+ if (data == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (len < 0 || pos < 0 || pos + len > data.length) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ final StringBuilder b = new StringBuilder();
+
+ // Process every byte in the data.
+
+ for (int i = pos, c = 0, line = 16; i < len; i += line) {
+ b.append(String.format("%06d", Integer.valueOf(c)) + " ");
+ b.append(toPrettyHexDumpLine(data, i, Math.min((pos + len) - i, line), 8, line));
- int i;
- byte[] high = new byte[256];
- byte[] low = new byte[256];
+ if ((i + line) < len) {
+ b.append("\n");
+ }
- for (i = 0; i < 256; i++) {
- high[i] = digits[i >>> 4];
- low[i] = digits[i & 0x0F];
+ c += line;
}
- highDigits = high;
- lowDigits = low;
+ return b.toString();
+
}
/**
- * Dumps an {@link IoBuffer} to a hex formatted string.
- *
- * @param in the buffer to dump
- * @param lengthLimit the limit at which hex dumping will stop
- * @return a hex formatted string representation of the in {@link Iobuffer}.
+ * Generates the hex dump line with hex values, columns, and ascii
+ * representation
+ *
+ * @param data source data to read for the hex dump
+ *
+ * @param pos index position to begin reading
+ *
+ * @param len number of bytes to read; this can be less than the line
+ * width
+ *
+ * @param col number of bytes in a column
+ *
+ * @param line line width in bytes which pads the output if len is less
+ * than line
+ *
+ * @return string hex dump
*/
- public static String getHexdump(IoBuffer in, int lengthLimit) {
- if (lengthLimit == 0) {
- throw new IllegalArgumentException("lengthLimit: " + lengthLimit
- + " (expected: 1+)");
+ private static final String toPrettyHexDumpLine(final byte[] data, final int pos, final int len, final int col,
+ final int line) {
+ if ((line % 2) != 0) {
+ throw new IllegalArgumentException("length must be multiple of 2");
}
- boolean truncate = in.remaining() > lengthLimit;
- int size;
- if (truncate) {
- size = lengthLimit;
- } else {
- size = in.remaining();
+ final StringBuilder b = new StringBuilder();
+
+ for (int i = pos, t = Math.min(data.length - pos, len) + pos; i < t;) {
+ for (int x = 0; (x < col) && (i < t); i++, x++) {
+ b.append(toHex(data[i]));
+ b.append(" ");
+ }
+
+ b.append(" ");
}
- if (size == 0) {
- return "empty";
+ int cl = (line * 3) + (line / col);
+
+ if (b.length() != cl) // check if we need to pad the output
+ {
+ cl -= b.length();
+
+ while (cl > 0) {
+ b.append(" ");
+ cl--;
+ }
}
- StringBuilder out = new StringBuilder(size * 3 + 3);
+ try {
+ String p = new String(data, pos, Math.min(data.length - pos, len), "Cp1252").replace("\r\n", "..")
+ .replace("\n", ".").replace("\\", ".");
- int mark = in.position();
+ final char[] ch = p.toCharArray();
- // fill the first
- int byteValue = in.get() & 0xFF;
- out.append((char) highDigits[byteValue]);
- out.append((char) lowDigits[byteValue]);
- size--;
+ for (int m = 0; m < ch.length; m++) {
+ if (ch[m] < 32) {
+ ch[m] = (char) 46; // add dots for whitespace chars
+ }
+ }
- // and the others, too
- for (; size > 0; size--) {
- out.append(' ');
- byteValue = in.get() & 0xFF;
- out.append((char) highDigits[byteValue]);
- out.append((char) lowDigits[byteValue]);
+ b.append(ch);
+ } catch (final UnsupportedEncodingException e) {
+ e.printStackTrace();
}
- in.position(mark);
+ return b.toString();
+ }
- if (truncate) {
- out.append("...");
- }
+ private static final char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
+ 'F' };
- return out.toString();
+ public static final String toHex(final byte b) {
+ // Returns hex String representation of byte
+
+ final char[] array = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] };
+ return new String(array);
}
-}
\ No newline at end of file
+}
diff --git a/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferWrapper.java b/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferWrapper.java
index c4d027f85c..c59d42e073 100644
--- a/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferWrapper.java
+++ b/mina-core/src/main/java/org/apache/mina/core/buffer/IoBufferWrapper.java
@@ -19,7 +19,7 @@
*/
package org.apache.mina.core.buffer;
-import java.io.FilterOutputStream;
+import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
@@ -33,15 +33,20 @@
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
-import java.util.EnumSet;
+import java.util.List;
import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.mina.core.buffer.matcher.ClassNameMatcher;
+import org.apache.mina.core.buffer.matcher.RegexpClassNameMatcher;
+import org.apache.mina.core.buffer.matcher.WildcardClassNameMatcher;
/**
* A {@link IoBuffer} that wraps a buffer and proxies any operations to it.
*
+ * is true. For other values of {@code searchChar}, it is the
+ * smallest value k such that:
+ *
+ * (this.charAt(k) == searchChar) && (k >= start)
+ *
+ *
+ * (this.codePointAt(k) == searchChar) && (k >= start)
+ *
FileChannel from which data will be read to send to
* remote host.
*
- * @return An open FileChannel.
+ * @return An open FileChannel.
*/
FileChannel getFileChannel();
@@ -44,12 +44,12 @@ public interface FileRegion {
long getPosition();
/**
- * Updates the current file position based on the specified amount. This
+ * Updates the current file position based on the specified amount. This
* increases the value returned by {@link #getPosition()} and
- * {@link getWrittenBytes} by the given amount and decreases the value
- * returned by {@link #getCount()} by the given {@code amount}.
- *
- * @param amount The new value for the file position.
+ * {@link #getWrittenBytes()} by the given amount and decreases the value
+ * returned by {@link #getRemainingBytes()} by the given {@code amount}.
+ *
+ * @param amount The new value for the file position.
*/
void update(long amount);
@@ -71,7 +71,7 @@ public interface FileRegion {
/**
* Provides an absolute filename for the underlying FileChannel.
*
- * @return the absolute filename, or null if the FileRegion
+ * @return the absolute filename, or null if the FileRegion
* does not know the filename
*/
String getFilename();
diff --git a/mina-core/src/main/java/org/apache/mina/core/file/FilenameFileRegion.java b/mina-core/src/main/java/org/apache/mina/core/file/FilenameFileRegion.java
index af0f876a0f..ce8404b00b 100644
--- a/mina-core/src/main/java/org/apache/mina/core/file/FilenameFileRegion.java
+++ b/mina-core/src/main/java/org/apache/mina/core/file/FilenameFileRegion.java
@@ -20,13 +20,11 @@
package org.apache.mina.core.file;
import java.io.File;
-import java.io.IOException;
import java.nio.channels.FileChannel;
-
/**
- * TODO Add documentation
- *
+ * Manage a File to be sent to a remote host. We keep a track on the current
+ * position, and the number of already written bytes.
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev$, $Date$
@@ -35,20 +33,39 @@ public class FilenameFileRegion extends DefaultFileRegion {
private final File file;
- public FilenameFileRegion(File file, FileChannel channel) throws IOException {
+ /**
+ * Create a new FilenameFileRegion instance
+ *
+ * @param file The file to manage
+ * @param channel The channel over the file
+ */
+ public FilenameFileRegion(File file, FileChannel channel) {
this(file, channel, 0, file.length());
}
-
+
+ /**
+ * Create a new FilenameFileRegion instance
+ *
+ * @param file The file to manage
+ * @param channel The channel over the file
+ * @param position The position in teh file
+ * @param remainingBytes The remaining bytes
+ */
public FilenameFileRegion(File file, FileChannel channel, long position, long remainingBytes) {
- super(channel, position, remainingBytes);
-
+ super(channel, position, remainingBytes);
+
if (file == null) {
throw new IllegalArgumentException("file can not be null");
}
+
this.file = file;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String getFilename() {
- return file.getAbsolutePath();
+ return file.getAbsolutePath();
}
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFilterChain.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFilterChain.java
index 08aee67e43..5b76e52bfc 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFilterChain.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/DefaultIoFilterChain.java
@@ -28,11 +28,15 @@
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFuture;
+import org.apache.mina.core.service.AbstractIoService;
import org.apache.mina.core.session.AbstractIoSession;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;
+import org.apache.mina.core.write.WriteRequestQueue;
+import org.apache.mina.filter.FilterEvent;
+import org.apache.mina.filter.ssl.EncryptedWriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,13 +54,14 @@ public class DefaultIoFilterChain implements IoFilterChain {
* attribute and notifies the future when {@link #fireSessionCreated()}
* or {@link #fireExceptionCaught(Throwable)} is invoked.
*/
- public static final AttributeKey SESSION_CREATED_FUTURE = new AttributeKey(
- DefaultIoFilterChain.class, "connectFuture");
+ public static final AttributeKey SESSION_CREATED_FUTURE = new AttributeKey(DefaultIoFilterChain.class,
+ "connectFuture");
/** The associated session */
private final AbstractIoSession session;
- private final Maptrue if the chain contains the given filter name
*/
public boolean contains(String name) {
return getEntry(name) != null;
@@ -170,6 +198,9 @@ public boolean contains(String name) {
/**
* @see IoFilterChain#contains(IoFilter)
+ *
+ * @param filter The Filter we want to check if it's in the chain
+ * @return true if the chain contains the given filter
*/
public boolean contains(IoFilter filter) {
return getEntry(filter) != null;
@@ -177,6 +208,9 @@ public boolean contains(IoFilter filter) {
/**
* @see IoFilterChain#contains(Class)
+ *
+ * @param filterType The FilterType we want to check if it's in the chain
+ * @return true if the chain contains the given filterType
*/
public boolean contains(Class extends IoFilter> filterType) {
return getEntry(filterType) != null;
@@ -184,6 +218,9 @@ public boolean contains(Class extends IoFilter> filterType) {
/**
* @see IoFilterChain#addFirst(String, IoFilter)
+ *
+ * @param name The filter's name
+ * @param filter The filter to add
*/
public synchronized void addFirst(String name, IoFilter filter) {
register(0, new EntryImpl(name, filter));
@@ -191,6 +228,9 @@ public synchronized void addFirst(String name, IoFilter filter) {
/**
* @see IoFilterChain#addLast(String, IoFilter)
+ *
+ * @param name The filter's name
+ * @param filter The filter to add
*/
public synchronized void addLast(String name, IoFilter filter) {
register(entries.size(), new EntryImpl(name, filter));
@@ -198,13 +238,17 @@ public synchronized void addLast(String name, IoFilter filter) {
/**
* @see IoFilterChain#addBefore(String, String, IoFilter)
+ *
+ * @param baseName The filter baseName
+ * @param name The filter's name
+ * @param filter The filter to add
*/
- public synchronized void addBefore(String baseName, String name,
- IoFilter filter) {
+ public synchronized void addBefore(String baseName, String name, IoFilter filter) {
checkBaseName(baseName);
for (ListIteratorThe Life Cycle
+ * The Life Cycle
* {@link IoFilter}s are activated only when they are inside {@link IoFilterChain}.
* parent.
* Please note that this method can be invoked more than once if
* this filter is added to more than one parents. This method is not
* invoked before {@link #init()} is invoked.
@@ -103,12 +108,12 @@ public interface IoFilter {
* @param name the name assigned to this filter
* @param nextFilter the {@link NextFilter} for this filter. You can reuse
* this object until this filter is removed from the chain.
+ * @throws Exception If an error occurred while processing the event
*/
- void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter)
- throws Exception;
+ void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
/**
- * Invoked after this filter is added to the specified parent.
+ * Invoked after this filter is added to the specified parent.
* Please note that this method can be invoked more than once if
* this filter is added to more than one parents. This method is not
* invoked before {@link #init()} is invoked.
@@ -117,12 +122,12 @@ void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter)
* @param name the name assigned to this filter
* @param nextFilter the {@link NextFilter} for this filter. You can reuse
* this object until this filter is removed from the chain.
+ * @throws Exception If an error occurred while processing the event
*/
- void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter)
- throws Exception;
+ void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
/**
- * Invoked before this filter is removed from the specified parent.
+ * Invoked before this filter is removed from the specified parent.
* Please note that this method can be invoked more than once if
* this filter is removed from more than one parents.
* This method is always invoked before {@link #destroy()} is invoked.
@@ -131,12 +136,12 @@ void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter)
* @param name the name assigned to this filter
* @param nextFilter the {@link NextFilter} for this filter. You can reuse
* this object until this filter is removed from the chain.
+ * @throws Exception If an error occurred while processing the event
*/
- void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter)
- throws Exception;
+ void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
/**
- * Invoked after this filter is removed from the specified parent.
+ * Invoked after this filter is removed from the specified parent.
* Please note that this method can be invoked more than once if
* this filter is removed from more than one parents.
* This method is always invoked before {@link #destroy()} is invoked.
@@ -145,115 +150,223 @@ void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter)
* @param name the name assigned to this filter
* @param nextFilter the {@link NextFilter} for this filter. You can reuse
* this object until this filter is removed from the chain.
+ * @throws Exception If an error occurred while processing the event
*/
- void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter)
- throws Exception;
+ void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception;
/**
* Filters {@link IoHandler#sessionCreated(IoSession)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @throws Exception If an error occurred while processing the event
*/
- void sessionCreated(NextFilter nextFilter, IoSession session)
- throws Exception;
+ void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception;
/**
* Filters {@link IoHandler#sessionOpened(IoSession)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @throws Exception If an error occurred while processing the event
*/
- void sessionOpened(NextFilter nextFilter, IoSession session)
- throws Exception;
+ void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception;
/**
* Filters {@link IoHandler#sessionClosed(IoSession)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @throws Exception If an error occurred while processing the event
*/
- void sessionClosed(NextFilter nextFilter, IoSession session)
- throws Exception;
+ void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception;
/**
- * Filters {@link IoHandler#sessionIdle(IoSession,IdleStatus)}
- * event.
+ * Filters {@link IoHandler#sessionIdle(IoSession,IdleStatus)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @param status The {@link IdleStatus} type
+ * @throws Exception If an error occurred while processing the event
*/
- void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status)
- throws Exception;
+ void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception;
/**
- * Filters {@link IoHandler#exceptionCaught(IoSession,Throwable)}
- * event.
+ * Filters {@link IoHandler#exceptionCaught(IoSession,Throwable)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @param cause The exception that cause this event to be received
+ * @throws Exception If an error occurred while processing the event
*/
- void exceptionCaught(NextFilter nextFilter, IoSession session,
- Throwable cause) throws Exception;
+ void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception;
/**
- * Filters {@link IoHandler#messageReceived(IoSession,Object)}
- * event.
+ * Filters {@link IoHandler#inputClosed(IoSession)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @throws Exception If an error occurred while processing the event
*/
- void messageReceived(NextFilter nextFilter, IoSession session,
- Object message) throws Exception;
+ void inputClosed(NextFilter nextFilter, IoSession session) throws Exception;
/**
- * Filters {@link IoHandler#messageSent(IoSession,Object)}
- * event.
+ * Filters {@link IoHandler#messageReceived(IoSession,Object)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @param message The received message
+ * @throws Exception If an error occurred while processing the event
*/
- void messageSent(NextFilter nextFilter, IoSession session,
- WriteRequest writeRequest) throws Exception;
+ void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception;
/**
- * Filters {@link IoSession#close()} method invocation.
+ * Filters {@link IoHandler#messageSent(IoSession,Object)} event.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has received this event
+ * @param writeRequest The {@link WriteRequest} that contains the sent message
+ * @throws Exception If an error occurred while processing the event
+ */
+ void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
+
+ /**
+ * Filters {@link IoSession#closeNow()} or a {@link IoSession#closeOnFlush()} method invocations.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session
+ * The {@link IoSession} which has to process this method
+ * invocation
+ * @throws Exception If an error occurred while processing the event
*/
void filterClose(NextFilter nextFilter, IoSession session) throws Exception;
/**
* Filters {@link IoSession#write(Object)} method invocation.
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param writeRequest The {@link WriteRequest} to process
+ * @throws Exception If an error occurred while processing the event
*/
- void filterWrite(NextFilter nextFilter, IoSession session,
- WriteRequest writeRequest) throws Exception;
+ void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception;
+ /**
+ * Propagate an event up to the {@link IoHandler}
+ *
+ * @param nextFilter
+ * the {@link NextFilter} for this filter. You can reuse this
+ * object until this filter is removed from the chain.
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param event The event to propagate
+ * @throws Exception If an error occurred while processing the event
+ */
+ void event(NextFilter nextFilter, IoSession session, FilterEvent event) throws Exception;
+
/**
* Represents the next {@link IoFilter} in {@link IoFilterChain}.
*/
- public interface NextFilter {
+ interface NextFilter {
/**
- * Forwards sessionCreated event to next filter.
+ * Forwards sessionCreated event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
*/
void sessionCreated(IoSession session);
/**
- * Forwards sessionOpened event to next filter.
+ * Forwards sessionOpened event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
*/
void sessionOpened(IoSession session);
/**
- * Forwards sessionClosed event to next filter.
+ * Forwards sessionClosed event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
*/
void sessionClosed(IoSession session);
/**
- * Forwards sessionIdle event to next filter.
+ * Forwards sessionIdle event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param status The {@link IdleStatus} type
*/
void sessionIdle(IoSession session, IdleStatus status);
/**
- * Forwards exceptionCaught event to next filter.
+ * Forwards exceptionCaught event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param cause The exception that cause this event to be received
*/
void exceptionCaught(IoSession session, Throwable cause);
/**
- * Forwards messageReceived event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ */
+ void inputClosed(IoSession session);
+
+ /**
+ * Forwards messageReceived event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param message The received message
*/
void messageReceived(IoSession session, Object message);
/**
- * Forwards messageSent event to next filter.
+ * Forwards messageSent event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param writeRequest The {@link WriteRequest} to process
*/
void messageSent(IoSession session, WriteRequest writeRequest);
/**
- * Forwards filterWrite event to next filter.
+ * Forwards filterWrite event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param writeRequest The {@link WriteRequest} to process
*/
void filterWrite(IoSession session, WriteRequest writeRequest);
/**
- * Forwards filterClose event to next filter.
+ * Forwards filterClose event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
*/
void filterClose(IoSession session);
-
+
+ /**
+ * Forwards an event to next filter.
+ *
+ * @param session The {@link IoSession} which has to process this invocation
+ * @param event The event to propagate
+ */
+ void event(IoSession session, FilterEvent event);
}
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterAdapter.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterAdapter.java
index e3946a17fa..5ea6b156c7 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterAdapter.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterAdapter.java
@@ -22,6 +22,7 @@
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;
+import org.apache.mina.filter.FilterEvent;
/**
* An adapter class for {@link IoFilter}. You can extend
@@ -34,115 +35,137 @@ public class IoFilterAdapter implements IoFilter {
/**
* {@inheritDoc}
*/
+ @Override
public void init() throws Exception {
}
/**
* {@inheritDoc}
*/
+ @Override
public void destroy() throws Exception {
}
/**
* {@inheritDoc}
*/
- public void onPreAdd(IoFilterChain parent, String name,
- NextFilter nextFilter) throws Exception {
+ @Override
+ public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
}
/**
* {@inheritDoc}
*/
- public void onPostAdd(IoFilterChain parent, String name,
- NextFilter nextFilter) throws Exception {
+ @Override
+ public void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
}
/**
* {@inheritDoc}
*/
- public void onPreRemove(IoFilterChain parent, String name,
- NextFilter nextFilter) throws Exception {
+ @Override
+ public void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
}
/**
* {@inheritDoc}
*/
- public void onPostRemove(IoFilterChain parent, String name,
- NextFilter nextFilter) throws Exception {
+ @Override
+ public void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
}
/**
* {@inheritDoc}
*/
- public void sessionCreated(NextFilter nextFilter, IoSession session)
- throws Exception {
+ @Override
+ public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
nextFilter.sessionCreated(session);
}
/**
* {@inheritDoc}
*/
- public void sessionOpened(NextFilter nextFilter, IoSession session)
- throws Exception {
+ @Override
+ public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
nextFilter.sessionOpened(session);
}
/**
* {@inheritDoc}
*/
- public void sessionClosed(NextFilter nextFilter, IoSession session)
- throws Exception {
+ @Override
+ public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
nextFilter.sessionClosed(session);
}
/**
* {@inheritDoc}
*/
- public void sessionIdle(NextFilter nextFilter, IoSession session,
- IdleStatus status) throws Exception {
+ @Override
+ public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
nextFilter.sessionIdle(session, status);
}
/**
* {@inheritDoc}
*/
- public void exceptionCaught(NextFilter nextFilter, IoSession session,
- Throwable cause) throws Exception {
+ @Override
+ public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception {
nextFilter.exceptionCaught(session, cause);
}
/**
* {@inheritDoc}
*/
- public void messageReceived(NextFilter nextFilter, IoSession session,
- Object message) throws Exception {
+ @Override
+ public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
nextFilter.messageReceived(session, message);
}
/**
* {@inheritDoc}
*/
- public void messageSent(NextFilter nextFilter, IoSession session,
- WriteRequest writeRequest) throws Exception {
+ @Override
+ public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
nextFilter.messageSent(session, writeRequest);
}
/**
* {@inheritDoc}
*/
- public void filterWrite(NextFilter nextFilter, IoSession session,
- WriteRequest writeRequest) throws Exception {
+ @Override
+ public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
nextFilter.filterWrite(session, writeRequest);
}
/**
* {@inheritDoc}
*/
- public void filterClose(NextFilter nextFilter, IoSession session)
- throws Exception {
+ @Override
+ public void filterClose(NextFilter nextFilter, IoSession session) throws Exception {
nextFilter.filterClose(session);
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void inputClosed(NextFilter nextFilter, IoSession session) throws Exception {
+ nextFilter.inputClosed(session);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void event(NextFilter nextFilter, IoSession session, FilterEvent event) throws Exception {
+ nextFilter.event(session, event);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String toString() {
return this.getClass().getSimpleName();
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChain.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChain.java
index 8f074473dc..7887406e1e 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChain.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChain.java
@@ -26,6 +26,7 @@
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;
+import org.apache.mina.filter.FilterEvent;
/**
* A container of {@link IoFilter}s that forwards {@link IoHandler} events
@@ -36,62 +37,60 @@
*/
public interface IoFilterChain {
/**
- * Returns the parent {@link IoSession} of this chain.
- *
- * @return {@link IoSession}
+ * @return the parent {@link IoSession} of this chain.
*/
IoSession getSession();
/**
- * Returns the {@link Entry} with the specified name in this chain.
+ * Returns the {@link Entry} with the specified name in this chain.
*
* @param name The filter's name we are looking for
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
Entry getEntry(String name);
/**
- * Returns the {@link Entry} with the specified filter in this chain.
+ * Returns the {@link Entry} with the specified filter in this chain.
*
* @param filter The Filter we are looking for
- * @return null if there's no such filter in this chain
+ * @return null if there's no such filter in this chain
*/
Entry getEntry(IoFilter filter);
/**
- * Returns the {@link Entry} with the specified filterType
+ * Returns the {@link Entry} with the specified filterType
* in this chain. If there's more than one filter with the specified
* type, the first match will be chosen.
*
* @param filterType The filter class we are looking for
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
Entry getEntry(Class extends IoFilter> filterType);
/**
- * Returns the {@link IoFilter} with the specified name in this chain.
+ * Returns the {@link IoFilter} with the specified name in this chain.
*
* @param name the filter's name
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
IoFilter get(String name);
/**
- * Returns the {@link IoFilter} with the specified filterType
+ * Returns the {@link IoFilter} with the specified filterType
* in this chain. If there's more than one filter with the specified
* type, the first match will be chosen.
*
* @param filterType The filter class
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
IoFilter get(Class extends IoFilter> filterType);
/**
* Returns the {@link NextFilter} of the {@link IoFilter} with the
- * specified name in this chain.
+ * specified name in this chain.
*
* @param name The filter's name we want the next filter
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
NextFilter getNextFilter(String name);
@@ -100,17 +99,17 @@ public interface IoFilterChain {
* in this chain.
*
* @param filter The filter for which we want the next filter
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
NextFilter getNextFilter(IoFilter filter);
/**
- * Returns the {@link NextFilter} of the specified filterType
+ * Returns the {@link NextFilter} of the specified filterType
* in this chain. If there's more than one filter with the specified
* type, the first match will be chosen.
*
* @param filterType The Filter class for which we want the next filter
- * @return null if there's no such name in this chain
+ * @return null if there's no such name in this chain
*/
NextFilter getNextFilter(Class extends IoFilter> filterType);
@@ -127,23 +126,23 @@ public interface IoFilterChain {
/**
* @param name The filter's name we are looking for
*
- * @return true if this chain contains an {@link IoFilter} with the
- * specified name.
+ * @return true if this chain contains an {@link IoFilter} with the
+ * specified name.
*/
boolean contains(String name);
/**
* @param filter The filter we are looking for
*
- * @return true if this chain contains the specified filter.
+ * @return true if this chain contains the specified filter.
*/
boolean contains(IoFilter filter);
/**
* @param filterType The filter's class we are looking for
*
- * @return true if this chain contains an {@link IoFilter} of the
- * specified filterType.
+ * @return true if this chain contains an {@link IoFilter} of the
+ * specified filterType.
*/
boolean contains(Class extends IoFilter> filterType);
@@ -209,6 +208,7 @@ public interface IoFilterChain {
*
* @param oldFilterType The filter class we want to replace
* @param newFilter The new filter
+ * @return The replaced IoFilter
*/
IoFilter replace(Class extends IoFilter> oldFilterType, IoFilter newFilter);
@@ -221,25 +221,26 @@ public interface IoFilterChain {
IoFilter remove(String name);
/**
- * Replace the filter with the specified name with the specified new
- * filter.
- *
- * @param name The filter to remove
+ * Replace the filter with the specified name with the specified new filter.
+ *
+ * @param filter The filter to remove
*/
void remove(IoFilter filter);
/**
- * Replace the filter of the specified type with the specified new
- * filter. If there's more than one filter with the specified type,
- * the first match will be replaced.
- *
- * @param name The filter class to remove
+ * Replace the filter of the specified type with the specified new filter.
+ * If there's more than one filter with the specified type, the first match
+ * will be replaced.
+ *
+ * @param filterType The filter class to remove
* @return The removed filter
*/
IoFilter remove(Class extends IoFilter> filterType);
/**
* Removes all filters added to this chain.
+ *
+ * @throws Exception If we weren't able to clear the filters
*/
void clear() throws Exception;
@@ -248,21 +249,21 @@ public interface IoFilterChain {
* call this method at all. Please use this method only when you implement a new transport
* or fire a virtual event.
*/
- public void fireSessionCreated();
+ void fireSessionCreated();
/**
* Fires a {@link IoHandler#sessionOpened(IoSession)} event. Most users don't need to call
* this method at all. Please use this method only when you implement a new transport or
* fire a virtual event.
*/
- public void fireSessionOpened();
+ void fireSessionOpened();
/**
* Fires a {@link IoHandler#sessionClosed(IoSession)} event. Most users don't need to call
* this method at all. Please use this method only when you implement a new transport or
* fire a virtual event.
*/
- public void fireSessionClosed();
+ void fireSessionClosed();
/**
* Fires a {@link IoHandler#sessionIdle(IoSession, IdleStatus)} event. Most users don't
@@ -271,25 +272,25 @@ public interface IoFilterChain {
*
* @param status The current status to propagate
*/
- public void fireSessionIdle(IdleStatus status);
+ void fireSessionIdle(IdleStatus status);
/**
- * Fires a {@link IoHandler#messageReceived(Object)} event. Most users don't need to
- * call this method at all. Please use this method only when you implement a new transport
- * or fire a virtual event.
+ * Fires a {@link IoHandler#messageReceived(IoSession, Object)} event. Most
+ * users don't need to call this method at all. Please use this method only
+ * when you implement a new transport or fire a virtual event.
*
* @param message The received message
*/
- public void fireMessageReceived(Object message);
+ void fireMessageReceived(Object message);
/**
- * Fires a {@link IoHandler#messageSent(IoSession)} event. Most users don't need to call
- * this method at all. Please use this method only when you implement a new transport or
- * fire a virtual event.
+ * Fires a {@link IoHandler#messageSent(IoSession, Object)} event. Most
+ * users don't need to call this method at all. Please use this method only
+ * when you implement a new transport or fire a virtual event.
*
* @param request The sent request
*/
- public void fireMessageSent(WriteRequest request);
+ void fireMessageSent(WriteRequest request);
/**
* Fires a {@link IoHandler#exceptionCaught(IoSession, Throwable)} event. Most users don't
@@ -298,37 +299,54 @@ public interface IoFilterChain {
*
* @param cause The exception cause
*/
- public void fireExceptionCaught(Throwable cause);
+ void fireExceptionCaught(Throwable cause);
+
+ /**
+ * Fires a {@link IoHandler#inputClosed(IoSession)} event. Most users don't
+ * need to call this method at all. Please use this method only when you
+ * implement a new transport or fire a virtual event.
+ */
+ void fireInputClosed();
/**
- * Fires a {@link IoSession#write(Object)} event. Most users don't need to call this
- * method at all. Please use this method only when you implement a new transport or fire a
- * virtual event.
+ * Fires a {@link IoSession#write(Object)} event. Most users don't need to
+ * call this method at all. Please use this method only when you implement a
+ * new transport or fire a virtual event.
*
* @param writeRequest The message to write
*/
- public void fireFilterWrite(WriteRequest writeRequest);
+ void fireFilterWrite(WriteRequest writeRequest);
/**
- * Fires a {@link IoSession#close()} event. Most users don't need to call this method at
+ * Fires a {@link IoSession#closeNow()} or a {@link IoSession#closeOnFlush()} event. Most users don't need to call this method at
+ * all. Please use this method only when you implement a new transport or fire a virtual
+ * event.
+ */
+ void fireFilterClose();
+
+
+ /**
+ * Fires a {@link IoHandler#event(IoSession, FilterEvent)} event. Most users don't need to call this method at
* all. Please use this method only when you implement a new transport or fire a virtual
* event.
+ *
+ * @param event The specific event being fired
*/
- public void fireFilterClose();
+ void fireEvent(FilterEvent event);
/**
* Represents a name-filter pair that an {@link IoFilterChain} contains.
*
* @author Apache MINA Project
*/
- public interface Entry {
+ interface Entry {
/**
- * Returns the name of the filter.
+ * @return the name of the filter.
*/
String getName();
/**
- * Returns the filter.
+ * @return the filter.
*/
IoFilter getFilter();
@@ -336,22 +354,30 @@ public interface Entry {
* @return The {@link NextFilter} of the filter.
*/
NextFilter getNextFilter();
-
+
/**
* Adds the specified filter with the specified name just before this entry.
+ *
+ * @param name The Filter's name
+ * @param filter The added Filter
*/
void addBefore(String name, IoFilter filter);
/**
* Adds the specified filter with the specified name just after this entry.
+ *
+ * @param name The Filter's name
+ * @param filter The added Filter
*/
void addAfter(String name, IoFilter filter);
/**
* Replace the filter of this entry with the specified new filter.
+ *
+ * @param newFilter The new filter that will be put in the chain
*/
void replace(IoFilter newFilter);
-
+
/**
* Removes this entry from the chain it belongs to.
*/
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChainBuilder.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChainBuilder.java
index 7f9d1f5bb5..046f731f6d 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChainBuilder.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterChainBuilder.java
@@ -41,9 +41,16 @@ public interface IoFilterChainBuilder {
* An implementation which does nothing.
*/
IoFilterChainBuilder NOOP = new IoFilterChainBuilder() {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void buildFilterChain(IoFilterChain chain) throws Exception {
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public String toString() {
return "NOOP";
@@ -51,7 +58,10 @@ public String toString() {
};
/**
- * Modifies the specified chain.
+ * Modifies the specified chain.
+ *
+ * @param chain The chain to modify
+ * @throws Exception If the chain modification failed
*/
void buildFilterChain(IoFilterChain chain) throws Exception;
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterEvent.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterEvent.java
index fa1454b2a9..99901dc644 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterEvent.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterEvent.java
@@ -25,6 +25,7 @@
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;
+import org.apache.mina.filter.FilterEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,85 +38,106 @@
*/
public class IoFilterEvent extends IoEvent {
/** A logger for this class */
- static Logger LOGGER = LoggerFactory.getLogger(IoFilterEvent.class);
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(IoFilterEvent.class);
+
/** A speedup for logs */
- static boolean DEBUG = LOGGER.isDebugEnabled();
+ private static final boolean DEBUG = LOGGER.isDebugEnabled();
+ /** The filter to call next */
private final NextFilter nextFilter;
- public IoFilterEvent(NextFilter nextFilter, IoEventType type,
- IoSession session, Object parameter) {
+ /**
+ * Creates a new IoFilterEvent instance
+ *
+ * @param nextFilter The next Filter
+ * @param type The type of event
+ * @param session The current session
+ * @param parameter Any parameter
+ */
+ public IoFilterEvent(NextFilter nextFilter, IoEventType type, IoSession session, Object parameter) {
super(type, session, parameter);
if (nextFilter == null) {
throw new IllegalArgumentException("nextFilter must not be null");
}
-
+
this.nextFilter = nextFilter;
}
+ /**
+ * @return The next filter
+ */
public NextFilter getNextFilter() {
return nextFilter;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void fire() {
IoSession session = getSession();
- NextFilter nextFilter = getNextFilter();
IoEventType type = getType();
if (DEBUG) {
- LOGGER.debug( "Firing a {} event for session {}",type, session.getId() );
+ LOGGER.debug("Firing a {} event for session {}", type, session.getId());
}
switch (type) {
- case MESSAGE_RECEIVED:
- Object parameter = getParameter();
- nextFilter.messageReceived(session, parameter);
- break;
-
- case MESSAGE_SENT:
- WriteRequest writeRequest = (WriteRequest)getParameter();
- nextFilter.messageSent(session, writeRequest);
- break;
-
- case WRITE:
- writeRequest = (WriteRequest)getParameter();
- nextFilter.filterWrite(session, writeRequest);
- break;
-
- case CLOSE:
- nextFilter.filterClose(session);
- break;
-
- case EXCEPTION_CAUGHT:
- Throwable throwable = (Throwable)getParameter();
- nextFilter.exceptionCaught(session, throwable);
- break;
-
- case SESSION_IDLE:
- nextFilter.sessionIdle(session, (IdleStatus) getParameter());
- break;
-
- case SESSION_OPENED:
- nextFilter.sessionOpened(session);
- break;
-
- case SESSION_CREATED:
- nextFilter.sessionCreated(session);
- break;
-
- case SESSION_CLOSED:
- nextFilter.sessionClosed(session);
- break;
-
- default:
- throw new IllegalArgumentException("Unknown event type: " + type);
+ case CLOSE:
+ nextFilter.filterClose(session);
+ break;
+
+ case EVENT:
+ nextFilter.event(session, (FilterEvent)getParameter());
+ break;
+
+ case EXCEPTION_CAUGHT:
+ Throwable throwable = (Throwable) getParameter();
+ nextFilter.exceptionCaught(session, throwable);
+ break;
+
+ case INPUT_CLOSED:
+ nextFilter.inputClosed(session);
+ break;
+
+ case MESSAGE_RECEIVED:
+ Object parameter = getParameter();
+ nextFilter.messageReceived(session, parameter);
+ break;
+
+ case MESSAGE_SENT:
+ WriteRequest writeRequest = (WriteRequest) getParameter();
+ nextFilter.messageSent(session, writeRequest);
+ break;
+
+ case SESSION_CLOSED:
+ nextFilter.sessionClosed(session);
+ break;
+
+ case SESSION_CREATED:
+ nextFilter.sessionCreated(session);
+ break;
+
+ case SESSION_IDLE:
+ nextFilter.sessionIdle(session, (IdleStatus) getParameter());
+ break;
+
+ case SESSION_OPENED:
+ nextFilter.sessionOpened(session);
+ break;
+
+ case WRITE:
+ writeRequest = (WriteRequest) getParameter();
+ nextFilter.filterWrite(session, writeRequest);
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown event type: " + type);
}
-
+
if (DEBUG) {
- LOGGER.debug( "Event {} has been fired for session {}", type, session.getId() );
+ LOGGER.debug("Event {} has been fired for session {}", type, session.getId());
}
}
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterLifeCycleException.java b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterLifeCycleException.java
index 9e94251086..f389705355 100644
--- a/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterLifeCycleException.java
+++ b/mina-core/src/main/java/org/apache/mina/core/filterchain/IoFilterLifeCycleException.java
@@ -19,7 +19,6 @@
*/
package org.apache.mina.core.filterchain;
-
/**
* A {@link RuntimeException} which is thrown when {@link IoFilter#init()}
* or {@link IoFilter#onPostAdd(IoFilterChain, String, org.apache.mina.core.filterchain.IoFilter.NextFilter)}
@@ -30,17 +29,37 @@
public class IoFilterLifeCycleException extends RuntimeException {
private static final long serialVersionUID = -5542098881633506449L;
+ /**
+ * Creates a new IoFilterLifeCycleException instance
+ */
public IoFilterLifeCycleException() {
+ // Default exception
}
+ /**
+ * Creates a new IoFilterLifeCycleException instance
+ *
+ * @param message The error message
+ */
public IoFilterLifeCycleException(String message) {
super(message);
}
+ /**
+ * Creates a new IoFilterLifeCycleException instance
+ *
+ * @param message The error message
+ * @param cause The original error cause
+ */
public IoFilterLifeCycleException(String message, Throwable cause) {
super(message, cause);
}
+ /**
+ * Creates a new IoFilterLifeCycleException instance
+ *
+ * @param cause The original error cause
+ */
public IoFilterLifeCycleException(Throwable cause) {
super(cause);
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/future/CloseFuture.java b/mina-core/src/main/java/org/apache/mina/core/future/CloseFuture.java
index 3b806b1778..4ba60e5383 100644
--- a/mina-core/src/main/java/org/apache/mina/core/future/CloseFuture.java
+++ b/mina-core/src/main/java/org/apache/mina/core/future/CloseFuture.java
@@ -19,16 +19,17 @@
*/
package org.apache.mina.core.future;
-
/**
* An {@link IoFuture} for asynchronous close requests.
*
- * Example
+ * Example
*
* IoSession session = ...;
* CloseFuture future = session.close(true);
+ *
* // Wait until the connection is closed
* future.awaitUninterruptibly();
+ *
* // Now connection should be closed.
* assert future.isClosed();
*
@@ -37,22 +38,38 @@
*/
public interface CloseFuture extends IoFuture {
/**
- * Returns true if the close request is finished and the session is closed.
+ * @return true if the close request is finished and the session is closed.
*/
boolean isClosed();
/**
* Marks this future as closed and notifies all threads waiting for this
- * future. This method is invoked by MINA internally. Please do not call
+ * future. This method is invoked by MINA internally. Please do not call
* this method directly.
*/
void setClosed();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
CloseFuture await() throws InterruptedException;
+ /**
+ * {@inheritDoc}
+ */
+ @Override
CloseFuture awaitUninterruptibly();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
CloseFuture addListener(IoFutureListener> listener);
+ /**
+ * {@inheritDoc}
+ */
+ @Override
CloseFuture removeListener(IoFutureListener> listener);
}
diff --git a/mina-core/src/main/java/org/apache/mina/core/future/CompositeIoFuture.java b/mina-core/src/main/java/org/apache/mina/core/future/CompositeIoFuture.java
index 69faeaeecd..1903f7eecb 100644
--- a/mina-core/src/main/java/org/apache/mina/core/future/CompositeIoFuture.java
+++ b/mina-core/src/main/java/org/apache/mina/core/future/CompositeIoFuture.java
@@ -35,26 +35,40 @@
* @param