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, jeffma...@apache.org 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 <jeffma...@apache.org> > Authored: Sun Apr 7 18:21:47 2013 +0200 > Committer: Jeff MAURY <jeffma...@apache.org> > 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:d...@directory.apache.org">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