A small sugestion :
the DEFAUKT value can be initialized this way :
public static final LineDelimiter DEFAULT = new LineDelimiter(
System.getProperty( "line.separator" ) );
Le 4/7/13 6:22 PM, [email protected] a écrit :
> Updated Branches:
> refs/heads/trunk 2d51d12db -> 653d1a5ff
>
>
> Added text line coded and related unit tests
>
>
> Project: http://git-wip-us.apache.org/repos/asf/mina/repo
> Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/653d1a5f
> Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/653d1a5f
> Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/653d1a5f
>
> Branch: refs/heads/trunk
> Commit: 653d1a5ff37904e4515bc375d24dcb301862dad4
> Parents: 2d51d12
> Author: Jeff MAURY <[email protected]>
> Authored: Sun Apr 7 18:21:47 2013 +0200
> Committer: Jeff MAURY <[email protected]>
> Committed: Sun Apr 7 18:21:47 2013 +0200
>
> ----------------------------------------------------------------------
> .../apache/mina/codec/textline/LineDelimiter.java | 149 ++++++
> .../mina/codec/textline/TextLineDecoder.java | 407 +++++++++++++++
> .../mina/codec/textline/TextLineEncoder.java | 147 ++++++
> .../codec/textline/AutoTextLineDecoderTest.java | 123 +++++
> .../codec/textline/UnixTextLineDecoderTest.java | 123 +++++
> .../codec/textline/WindowsTextLineDecoderTest.java | 121 +++++
> 6 files changed, 1070 insertions(+), 0 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/main/java/org/apache/mina/codec/textline/LineDelimiter.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/main/java/org/apache/mina/codec/textline/LineDelimiter.java
> b/codec/src/main/java/org/apache/mina/codec/textline/LineDelimiter.java
> new file mode 100644
> index 0000000..c6f858a
> --- /dev/null
> +++ b/codec/src/main/java/org/apache/mina/codec/textline/LineDelimiter.java
> @@ -0,0 +1,149 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import java.io.ByteArrayOutputStream;
> +import java.io.PrintWriter;
> +
> +/**
> + * A delimiter which is appended to the end of a text line, such as
> + * <tt>CR/LF</tt>. This class defines default delimiters for various
> + * OS :
> + * <ul>
> + * <li><b>Unix/Linux</b> : LineDelimiter.UNIX ("\n")</li>
> + * <li><b>Windows</b> : LineDelimiter.WINDOWS ("\r\n")</li>
> + * <li><b>MAC</b> : LineDelimiter.MAC ("\r")</li>
> + * </ul>
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class LineDelimiter {
> + /** the line delimiter constant of the current O/S. */
> + public static final LineDelimiter DEFAULT;
> +
> + /** Compute the default delimiter on he current OS */
> + static {
> + ByteArrayOutputStream bout = new ByteArrayOutputStream();
> + PrintWriter out = new PrintWriter(bout, true);
> + out.println();
> + DEFAULT = new LineDelimiter(new String(bout.toByteArray()));
> + }
> +
> + /**
> + * A special line delimiter which is used for auto-detection of
> + * EOL in {@link TextLineDecoder}. If this delimiter is used,
> + * {@link TextLineDecoder} will consider both <tt>'\r'</tt> and
> + * <tt>'\n'</tt> as a delimiter.
> + */
> + public static final LineDelimiter AUTO = new LineDelimiter("");
> +
> + /**
> + * The CRLF line delimiter constant (<tt>"\r\n"</tt>)
> + */
> + public static final LineDelimiter CRLF = new LineDelimiter("\r\n");
> +
> + /**
> + * The line delimiter constant of UNIX (<tt>"\n"</tt>)
> + */
> + public static final LineDelimiter UNIX = new LineDelimiter("\n");
> +
> + /**
> + * The line delimiter constant of MS Windows/DOS (<tt>"\r\n"</tt>)
> + */
> + public static final LineDelimiter WINDOWS = CRLF;
> +
> + /**
> + * The line delimiter constant of Mac OS (<tt>"\r"</tt>)
> + */
> + public static final LineDelimiter MAC = new LineDelimiter("\r");
> +
> + /**
> + * The line delimiter constant for NUL-terminated text protocols
> + * such as Flash XML socket (<tt>"\0"</tt>)
> + */
> + public static final LineDelimiter NUL = new LineDelimiter("\0");
> +
> + /** Stores the selected Line delimiter */
> + private final String value;
> +
> + /**
> + * Creates a new line delimiter with the specified <tt>value</tt>.
> + */
> + public LineDelimiter(String value) {
> + if (value == null) {
> + throw new IllegalArgumentException("delimiter");
> + }
> +
> + this.value = value;
> + }
> +
> + /**
> + * Return the delimiter string.
> + */
> + public String getValue() {
> + return value;
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + public int hashCode() {
> + return value.hashCode();
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + public boolean equals(Object o) {
> + if (this == o) {
> + return true;
> + }
> +
> + if (!(o instanceof LineDelimiter)) {
> + return false;
> + }
> +
> + LineDelimiter that = (LineDelimiter) o;
> +
> + return this.value.equals(that.value);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + public String toString() {
> + if (value.length() == 0) {
> + return "delimiter: auto";
> + } else {
> + StringBuilder buf = new StringBuilder();
> + buf.append("delimiter:");
> +
> + for (int i = 0; i < value.length(); i++) {
> + buf.append(" 0x");
> + buf.append(Integer.toHexString(value.charAt(i)));
> + }
> +
> + return buf.toString();
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/main/java/org/apache/mina/codec/textline/TextLineDecoder.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/main/java/org/apache/mina/codec/textline/TextLineDecoder.java
> b/codec/src/main/java/org/apache/mina/codec/textline/TextLineDecoder.java
> new file mode 100644
> index 0000000..845ee24
> --- /dev/null
> +++ b/codec/src/main/java/org/apache/mina/codec/textline/TextLineDecoder.java
> @@ -0,0 +1,407 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import java.nio.ByteBuffer;
> +import java.nio.CharBuffer;
> +import java.nio.charset.CharacterCodingException;
> +import java.nio.charset.Charset;
> +import java.nio.charset.CharsetDecoder;
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +import org.apache.mina.codec.ProtocolDecoder;
> +
> +/**
> + * A {@link ProtocolDecoder} which decodes a text line into a string.
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class TextLineDecoder implements ProtocolDecoder<ByteBuffer, String,
> TextLineDecoder.Context> {
> + private final Charset charset;
> +
> + /** The delimiter used to determinate when a line has been fully decoded
> */
> + private final LineDelimiter delimiter;
> +
> + /** An ByteBuffer containing the delimiter */
> + private ByteBuffer delimBuf;
> +
> + /** The default maximum Line length. Default to 1024. */
> + private int maxLineLength = 1024;
> +
> + /** The default maximum buffer length. Default to 128 chars. */
> + private int bufferLength = 128;
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and {@link LineDelimiter#AUTO} delimiter.
> + */
> + public TextLineDecoder() {
> + this(LineDelimiter.AUTO);
> + }
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineDecoder(String delimiter) {
> + this(new LineDelimiter(delimiter));
> + }
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineDecoder(LineDelimiter delimiter) {
> + this(Charset.defaultCharset(), delimiter);
> + }
> +
> + /**
> + * Creates a new instance with the spcified <tt>charset</tt>
> + * and {@link LineDelimiter#AUTO} delimiter.
> + */
> + public TextLineDecoder(Charset charset) {
> + this(charset, LineDelimiter.AUTO);
> + }
> +
> + /**
> + * Creates a new instance with the spcified <tt>charset</tt>
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineDecoder(Charset charset, String delimiter) {
> + this(charset, new LineDelimiter(delimiter));
> + }
> +
> + /**
> + * Creates a new instance with the specified <tt>charset</tt>
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineDecoder(Charset charset, LineDelimiter delimiter) {
> + if (charset == null) {
> + throw new IllegalArgumentException("charset parameter shuld not
> be null");
> + }
> +
> + if (delimiter == null) {
> + throw new IllegalArgumentException("delimiter parameter should
> not be null");
> + }
> +
> + this.charset = charset;
> + this.delimiter = delimiter;
> +
> + // Convert delimiter to ByteBuffer if not done yet.
> + if (delimBuf == null) {
> + ByteBuffer tmp =
> charset.encode(CharBuffer.wrap(delimiter.getValue()));
> + tmp.rewind();
> + delimBuf = tmp;
> + }
> + }
> +
> + /**
> + * Returns the allowed maximum size of the line to be decoded.
> + * If the size of the line to be decoded exceeds this value, the
> + * decoder will throw a {@link BufferDataException}. The default
> + * value is <tt>1024</tt> (1KB).
> + */
> + public int getMaxLineLength() {
> + return maxLineLength;
> + }
> +
> + /**
> + * Sets the allowed maximum size of the line to be decoded.
> + * If the size of the line to be decoded exceeds this value, the
> + * decoder will throw a {@link BufferDataException}. The default
> + * value is <tt>1024</tt> (1KB).
> + */
> + public void setMaxLineLength(int maxLineLength) {
> + if (maxLineLength <= 0) {
> + throw new IllegalArgumentException("maxLineLength (" +
> maxLineLength + ") should be a positive value");
> + }
> +
> + this.maxLineLength = maxLineLength;
> + }
> +
> + /**
> + * Sets the default buffer size. This buffer is used in the Context
> + * to store the decoded line.
> + *
> + * @param bufferLength The default bufer size
> + */
> + public void setBufferLength(int bufferLength) {
> + if (bufferLength <= 0) {
> + throw new IllegalArgumentException("bufferLength (" +
> maxLineLength + ") should be a positive value");
> +
> + }
> +
> + this.bufferLength = bufferLength;
> + }
> +
> + /**
> + * Returns the allowed buffer size used to store the decoded line
> + * in the Context instance.
> + */
> + public int getBufferLength() {
> + return bufferLength;
> + }
> +
> + @Override
> + public Context createDecoderState() {
> + return new Context(bufferLength);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + public String[] decode(ByteBuffer in, Context ctx) {
> + if (LineDelimiter.AUTO.equals(delimiter)) {
> + return decodeAuto(ctx, in);
> + } else {
> + return decodeNormal(ctx, in);
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + public void finishDecode(Context ctx) {
> + }
> +
> + /**
> + * Decode a line using the default delimiter on the current system
> + */
> + private String[] decodeAuto(Context ctx, ByteBuffer in) {
> + List<String> decoded = new ArrayList<String>();
> + int matchCount = ctx.getMatchCount();
> +
> + // Try to find a match
> + int oldPos = in.position();
> + int oldLimit = in.limit();
> +
> + while (in.hasRemaining()) {
> + byte b = in.get();
> + boolean matched = false;
> +
> + switch (b) {
> + case '\r':
> + // Might be Mac, but we don't auto-detect Mac EOL
> + // to avoid confusion.
> + matchCount++;
> + break;
> +
> + case '\n':
> + // UNIX
> + matchCount++;
> + matched = true;
> + break;
> +
> + default:
> + matchCount = 0;
> + }
> +
> + if (matched) {
> + // Found a match.
> + int pos = in.position();
> + in.limit(pos);
> + in.position(oldPos);
> +
> + ctx.append(in);
> +
> + in.limit(oldLimit);
> + in.position(pos);
> +
> + try {
> + if (ctx.getOverflowLength() == 0) {
> + ByteBuffer buf = ctx.getBuffer();
> + buf.flip();
> + buf.limit(buf.limit() - matchCount);
> +
> + CharsetDecoder decoder = ctx.getDecoder();
> + CharBuffer buffer = decoder.decode(buf);
> + String str = new String(buffer.array());
> + decoded.add(str);
> + } else {
> + int overflowPosition = ctx.getOverflowLength();
> + throw new IllegalStateException("Line is too long: "
> + overflowPosition);
> + }
> + } catch (CharacterCodingException cce) {
> + throw new RuntimeException(cce);
> + } finally {
> + ctx.reset();
> + }
> + oldPos = pos;
> + matchCount = 0;
> + }
> + }
> +
> + // Put remainder to buf.
> + in.position(oldPos);
> + ctx.append(in);
> +
> + ctx.setMatchCount(matchCount);
> + return decoded.toArray(new String[decoded.size()]);
> + }
> +
> + /**
> + * Decode a line using the delimiter defined by the caller
> + * @return
> + */
> + private String[] decodeNormal(Context ctx, ByteBuffer in) {
> + List<String> decoded = new ArrayList<String>();
> + int matchCount = ctx.getMatchCount();
> +
> + // Try to find a match
> + int oldPos = in.position();
> + int oldLimit = in.limit();
> +
> + while (in.hasRemaining()) {
> + byte b = in.get();
> +
> + if (delimBuf.get(matchCount) == b) {
> + matchCount++;
> +
> + if (matchCount == delimBuf.limit()) {
> + // Found a match.
> + int pos = in.position();
> + in.limit(pos);
> + in.position(oldPos);
> +
> + ctx.append(in);
> +
> + in.limit(oldLimit);
> + in.position(pos);
> +
> + try {
> + if (ctx.getOverflowLength() == 0) {
> + ByteBuffer buf = ctx.getBuffer();
> + buf.flip();
> + buf.limit(buf.limit() - matchCount);
> +
> + CharsetDecoder decoder = ctx.getDecoder();
> + CharBuffer buffer = decoder.decode(buf);
> + String str = new String(buffer.array());
> + decoded.add(str);
> + } else {
> + int overflowLength = ctx.getOverflowLength();
> + throw new IllegalStateException("Line is too
> long: " + overflowLength);
> + }
> + } catch (CharacterCodingException cce) {
> + throw new RuntimeException(cce);
> + } finally {
> + ctx.reset();
> + }
> +
> +
> + oldPos = pos;
> + matchCount = 0;
> + }
> + } else {
> + // fix for DIRMINA-506 & DIRMINA-536
> + in.position(Math.max(0, in.position() - matchCount));
> + matchCount = 0;
> + }
> + }
> +
> + // Put remainder to buf.
> + in.position(oldPos);
> + ctx.append(in);
> +
> + ctx.setMatchCount(matchCount);
> + return decoded.toArray(new String[decoded.size()]);
> + }
> +
> + /**
> + * A Context used during the decoding of a lin. It stores the decoder,
> + * the temporary buffer containing the decoded line, and other status
> flags.
> + *
> + * @author <a href="mailto:[email protected]">Apache Directory
> Project</a>
> + * @version $Rev$, $Date$
> + */
> + public class Context {
> + /** The decoder */
> + private final CharsetDecoder decoder;
> +
> + /** The temporary buffer containing the decoded line */
> + private ByteBuffer buf;
> +
> + /** The number of lines found so far */
> + private int matchCount = 0;
> +
> + /**
> + * Overflow length
> + */
> + private int overflowLength = 0;
> +
> + /** Create a new Context object with a default buffer */
> + private Context(int bufferLength) {
> + decoder = charset.newDecoder();
> + buf = ByteBuffer.allocate(bufferLength);
> + }
> +
> + public CharsetDecoder getDecoder() {
> + return decoder;
> + }
> +
> + public ByteBuffer getBuffer() {
> + return buf;
> + }
> +
> + public int getMatchCount() {
> + return matchCount;
> + }
> +
> + public void setMatchCount(int matchCount) {
> + this.matchCount = matchCount;
> + }
> +
> + public int getOverflowLength() {
> + return overflowLength;
> + }
> +
> + public void reset() {
> + overflowLength = 0;
> + matchCount = 0;
> + decoder.reset();
> + buf.clear();
> + }
> +
> + private void ensureSpace(int size) {
> + if (buf.position() + size > buf.capacity()) {
> + ByteBuffer b = ByteBuffer.allocate(buf.position() + size +
> bufferLength);
> + buf.flip();
> + b.put(buf);
> + buf = b;
> + }
> + }
> + public void append(ByteBuffer in) {
> + if (buf.position() > maxLineLength - in.remaining()) {
> + overflowLength = buf.position() + in.remaining();
> + buf.clear();
> + discard(in);
> + } else {
> + ensureSpace(in.remaining());
> + getBuffer().put(in);
> + }
> + }
> +
> + private void discard(ByteBuffer in) {
> + in.position(in.limit());
> + }
> + }
> +
> +}
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/main/java/org/apache/mina/codec/textline/TextLineEncoder.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/main/java/org/apache/mina/codec/textline/TextLineEncoder.java
> b/codec/src/main/java/org/apache/mina/codec/textline/TextLineEncoder.java
> new file mode 100644
> index 0000000..6ce02c3
> --- /dev/null
> +++ b/codec/src/main/java/org/apache/mina/codec/textline/TextLineEncoder.java
> @@ -0,0 +1,147 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import java.nio.ByteBuffer;
> +import java.nio.CharBuffer;
> +import java.nio.charset.CharacterCodingException;
> +import java.nio.charset.Charset;
> +import java.nio.charset.CharsetEncoder;
> +
> +import org.apache.mina.codec.ProtocolEncoder;
> +import org.apache.mina.codec.StatelessProtocolEncoder;
> +
> +
> +/**
> + * A {@link ProtocolEncoder} which encodes a string into a text line
> + * which ends with the delimiter.
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class TextLineEncoder implements StatelessProtocolEncoder<String,
> ByteBuffer> {
> + private final CharsetEncoder charsetEncoder;
> +
> + private final LineDelimiter delimiter;
> +
> + private int maxLineLength = Integer.MAX_VALUE;
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and {@link LineDelimiter#UNIX} delimiter.
> + */
> + public TextLineEncoder() {
> + this(Charset.defaultCharset(), LineDelimiter.UNIX);
> + }
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineEncoder(String delimiter) {
> + this(new LineDelimiter(delimiter));
> + }
> +
> + /**
> + * Creates a new instance with the current default {@link Charset}
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineEncoder(LineDelimiter delimiter) {
> + this(Charset.defaultCharset(), delimiter);
> + }
> +
> + /**
> + * Creates a new instance with the spcified <tt>charset</tt>
> + * and {@link LineDelimiter#UNIX} delimiter.
> + */
> + public TextLineEncoder(Charset charset) {
> + this(charset, LineDelimiter.UNIX);
> + }
> +
> + /**
> + * Creates a new instance with the spcified <tt>charset</tt>
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineEncoder(Charset charset, String delimiter) {
> + this(charset, new LineDelimiter(delimiter));
> + }
> +
> + /**
> + * Creates a new instance with the spcified <tt>charset</tt>
> + * and the specified <tt>delimiter</tt>.
> + */
> + public TextLineEncoder(Charset charset, LineDelimiter delimiter) {
> + if (charset == null) {
> + throw new IllegalArgumentException("charset");
> + }
> + if (delimiter == null) {
> + throw new IllegalArgumentException("delimiter");
> + }
> + if (LineDelimiter.AUTO.equals(delimiter)) {
> + throw new IllegalArgumentException("AUTO delimiter is not
> allowed for encoder.");
> + }
> +
> + this.charsetEncoder = charset.newEncoder();
> + this.delimiter = delimiter;
> + }
> +
> + /**
> + * Returns the allowed maximum size of the encoded line.
> + * If the size of the encoded line exceeds this value, the encoder
> + * will throw a {@link IllegalArgumentException}. The default value
> + * is {@link Integer#MAX_VALUE}.
> + */
> + public int getMaxLineLength() {
> + return maxLineLength;
> + }
> +
> + /**
> + * Sets the allowed maximum size of the encoded line.
> + * If the size of the encoded line exceeds this value, the encoder
> + * will throw a {@link IllegalArgumentException}. The default value
> + * is {@link Integer#MAX_VALUE}.
> + */
> + public void setMaxLineLength(int maxLineLength) {
> + if (maxLineLength <= 0) {
> + throw new IllegalArgumentException("maxLineLength: " +
> maxLineLength);
> + }
> +
> + this.maxLineLength = maxLineLength;
> + }
> +
> + @Override
> + public Void createEncoderState() {
> + return null;
> + }
> +
> + @Override
> + public ByteBuffer encode(String message, Void context) {
> + try {
> + String value = (message == null ? "" : message);
> +
> + if (value.length() > maxLineLength) {
> + throw new IllegalArgumentException("Line length: " +
> message.length());
> + }
> + return
> charsetEncoder.encode(CharBuffer.wrap(value).append(CharBuffer.wrap(delimiter.getValue())));
> + } catch (CharacterCodingException e) {
> + throw new RuntimeException(e);
> + }
> + }
> +
> +}
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/test/java/org/apache/mina/codec/textline/AutoTextLineDecoderTest.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/test/java/org/apache/mina/codec/textline/AutoTextLineDecoderTest.java
>
> b/codec/src/test/java/org/apache/mina/codec/textline/AutoTextLineDecoderTest.java
> new file mode 100644
> index 0000000..ca087c4
> --- /dev/null
> +++
> b/codec/src/test/java/org/apache/mina/codec/textline/AutoTextLineDecoderTest.java
> @@ -0,0 +1,123 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertNotNull;
> +
> +import java.nio.ByteBuffer;
> +
> +import org.apache.mina.codec.textline.TextLineDecoder.Context;
> +import org.junit.Test;
> +
> +/**
> + * A {@link TextLineDecoder} test.
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class AutoTextLineDecoderTest {
> +
> + @Test
> + public void testThatEmptyBufferReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.allocate(0), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + }
> +
> + @Test
> + public void testThatNonLineTerminatedStringReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + assertEquals(8, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatWindowsLineTerminatedStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\r\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatContextIsMaintainedBetweenMessages() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\na".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(1, context.getBuffer().position());
> + results = decoder.decode(ByteBuffer.wrap(" string\n".getBytes()),
> context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedLongStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals(sb.toString(), results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void
> testThatWindowsLineTerminatedLongStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder();
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\r\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals(sb.toString(), results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/test/java/org/apache/mina/codec/textline/UnixTextLineDecoderTest.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/test/java/org/apache/mina/codec/textline/UnixTextLineDecoderTest.java
>
> b/codec/src/test/java/org/apache/mina/codec/textline/UnixTextLineDecoderTest.java
> new file mode 100644
> index 0000000..2023187
> --- /dev/null
> +++
> b/codec/src/test/java/org/apache/mina/codec/textline/UnixTextLineDecoderTest.java
> @@ -0,0 +1,123 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertNotNull;
> +
> +import java.nio.ByteBuffer;
> +
> +import org.apache.mina.codec.textline.TextLineDecoder.Context;
> +import org.junit.Test;
> +
> +/**
> + * A {@link TextLineDecoder} test.
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class UnixTextLineDecoderTest {
> +
> + @Test
> + public void testThatEmptyBufferReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.allocate(0), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + }
> +
> + @Test
> + public void testThatNonLineTerminatedStringReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + assertEquals(8, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatWindowsLineTerminatedStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\r\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string\r", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatContextIsMaintainedBetweenMessages() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\na".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(1, context.getBuffer().position());
> + results = decoder.decode(ByteBuffer.wrap(" string\n".getBytes()),
> context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedLongStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals(sb.toString(), results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void
> testThatWindowsLineTerminatedLongStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.UNIX);
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\r\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals(sb.toString() + "\r", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina/blob/653d1a5f/codec/src/test/java/org/apache/mina/codec/textline/WindowsTextLineDecoderTest.java
> ----------------------------------------------------------------------
> diff --git
> a/codec/src/test/java/org/apache/mina/codec/textline/WindowsTextLineDecoderTest.java
>
> b/codec/src/test/java/org/apache/mina/codec/textline/WindowsTextLineDecoderTest.java
> new file mode 100644
> index 0000000..727fd17
> --- /dev/null
> +++
> b/codec/src/test/java/org/apache/mina/codec/textline/WindowsTextLineDecoderTest.java
> @@ -0,0 +1,121 @@
> +/*
> + * 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
> + *
> + * http://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.
> + *
> + */
> +package org.apache.mina.codec.textline;
> +
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertNotNull;
> +
> +import java.nio.ByteBuffer;
> +
> +import org.apache.mina.codec.textline.TextLineDecoder.Context;
> +import org.junit.Test;
> +
> +/**
> + * A {@link TextLineDecoder} test.
> + *
> + * @author <a href="http://mina.apache.org">Apache MINA Project</a>
> + */
> +public class WindowsTextLineDecoderTest {
> +
> + @Test
> + public void testThatEmptyBufferReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.allocate(0), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + }
> +
> + @Test
> + public void testThatNonLineTerminatedStringReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + assertEquals(8, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedStringReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + assertEquals(9, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatWindowsLineTerminatedStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\r\n".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatContextIsMaintainedBetweenMessages() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + String[] results = decoder.decode(ByteBuffer.wrap("a
> string\r\na".getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(1, context.getBuffer().position());
> + results = decoder.decode(ByteBuffer.wrap(" string\r\n".getBytes()),
> context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals("a string", results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +
> + @Test
> + public void testThatUnixLineTerminatedLongStringReturnsEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(0, results.length);
> + assertEquals(801, context.getBuffer().position());
> + }
> +
> + @Test
> + public void
> testThatWindowsLineTerminatedLongStringReturnsNonEmptyResult() {
> + TextLineDecoder decoder = new TextLineDecoder(LineDelimiter.WINDOWS);
> + Context context = decoder.createDecoderState();
> + StringBuffer sb = new StringBuffer();
> + for(int i=0; i < 100;++i) {
> + sb.append("a string");
> + }
> + String[] results = decoder.decode(ByteBuffer.wrap((sb.toString() +
> "\r\n").getBytes()), context);
> + assertNotNull(results);
> + assertEquals(1, results.length);
> + assertEquals(sb.toString(), results[0]);
> + assertEquals(0, context.getBuffer().position());
> + }
> +}
>
--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com