You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/03/29 09:02:35 UTC
svn commit: r642517 - in
/james/server/trunk/imap-mailbox-processor-function/src:
main/java/org/apache/james/imapserver/processor/imap4rev1/
test/java/org/apache/james/imapserver/processor/imap4rev1/
Author: rdonkin
Date: Sat Mar 29 01:02:34 2008
New Revision: 642517
URL: http://svn.apache.org/viewvc?rev=642517&view=rev
Log:
Partial FETCH processing
Added:
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElement.java
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannel.java
james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElementTest.java
james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannelTest.java
Modified:
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
Modified: james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java?rev=642517&r1=642516&r2=642517&view=diff
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java (original)
+++ james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java Sat Mar 29 01:02:34 2008
@@ -476,43 +476,70 @@
private FetchResponse.BodyElement bodyFetch(final MessageResult messageResult,
BodyFetchElement fetchElement) throws MessagingException, ProtocolException {
- final FetchResponse.BodyElement result;
+ final Long firstOctet = fetchElement.getFirstOctet();
+ final Long numberOfOctets = fetchElement.getNumberOfOctets();
final String name = fetchElement.getResponseName();
final int specifier = fetchElement.getSectionType();
final int[] path = fetchElement.getPath();
final Collection names = fetchElement.getFieldNames();
final boolean isBase = (path == null || path.length == 0);
+ final FetchResponse.BodyElement fullResult
+ = bodyContent(messageResult, name, specifier, path, names, isBase);
+ final FetchResponse.BodyElement result
+ = wrapIfPartialFetch(firstOctet, numberOfOctets, fullResult);
+ return result;
+
+ }
+
+ private FetchResponse.BodyElement bodyContent(final MessageResult messageResult, final String name, final int specifier, final int[] path, final Collection names, final boolean isBase) throws MailboxManagerException, MessagingException {
+ final FetchResponse.BodyElement fullResult;
switch (specifier) {
case BodyFetchElement.CONTENT:
- result = content(messageResult, name, path, isBase);
+ fullResult = content(messageResult, name, path, isBase);
break;
case BodyFetchElement.HEADER_FIELDS:
- result = fields(messageResult, name, path, names, isBase);
+ fullResult = fields(messageResult, name, path, names, isBase);
break;
case BodyFetchElement.HEADER_NOT_FIELDS:
- result = fieldsNot(messageResult, name, path, names, isBase);
+ fullResult = fieldsNot(messageResult, name, path, names, isBase);
break;
case BodyFetchElement.MIME:
- result = mimeHeaders(messageResult, name, path, isBase);
+ fullResult = mimeHeaders(messageResult, name, path, isBase);
break;
case BodyFetchElement.HEADER:
- result = headers(messageResult, name, path, isBase);
+ fullResult = headers(messageResult, name, path, isBase);
break;
case BodyFetchElement.TEXT:
- result = text(messageResult, name, path, isBase);
+ fullResult = text(messageResult, name, path, isBase);
break;
default:
- result = null;
+ fullResult = null;
break;
}
+ return fullResult;
+ }
+ private FetchResponse.BodyElement wrapIfPartialFetch(final Long firstOctet, final Long numberOfOctets, final FetchResponse.BodyElement fullResult) {
+ final FetchResponse.BodyElement result;
+ if (firstOctet == null) {
+ result = fullResult;
+ } else {
+ final long numberOfOctetsAsLong;
+ if (numberOfOctets == null) {
+ numberOfOctetsAsLong = Long.MAX_VALUE;
+ } else {
+ numberOfOctetsAsLong = numberOfOctets.longValue();
+ }
+ final long firstOctetAsLong = firstOctet.longValue();
+ result = new PartialFetchBodyElement(fullResult,
+ firstOctetAsLong, numberOfOctetsAsLong);
+ }
return result;
-
}
private FetchResponse.BodyElement text(final MessageResult messageResult, String name, final int[] path, final boolean isBase) throws MailboxManagerException {
@@ -815,7 +842,5 @@
public void writeTo(WritableByteChannel channel) throws IOException {
content.writeTo(channel);
}
-
-
}
}
Added: james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElement.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElement.java?rev=642517&view=auto
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElement.java (added)
+++ james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElement.java Sat Mar 29 01:02:34 2008
@@ -0,0 +1,47 @@
+package org.apache.james.imapserver.processor.imap4rev1;
+
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
+
+import org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement;
+
+/**
+ * Wraps full content to implement a partial fetch.
+ */
+final class PartialFetchBodyElement implements BodyElement {
+
+ private final BodyElement delegate;
+ private final long firstOctet;
+ private final long numberOfOctets;
+
+ public PartialFetchBodyElement(final BodyElement delegate, final long firstOctet,
+ final long numberOfOctets) {
+ super();
+ this.delegate = delegate;
+ this.firstOctet = firstOctet;
+ this.numberOfOctets = numberOfOctets;
+ }
+
+ public String getName() {
+ return delegate.getName();
+ }
+
+ public long size() {
+ final long size = delegate.size();
+ final long numberOfOctets;
+ if (size > this.numberOfOctets) {
+ numberOfOctets = this.numberOfOctets;
+ } else {
+ numberOfOctets = size;
+ }
+ final long result = numberOfOctets - firstOctet;
+ return result;
+ }
+
+ public void writeTo(WritableByteChannel channel) throws IOException {
+ PartialWritableByteChannel partialChannel =
+ new PartialWritableByteChannel(channel, firstOctet, size());
+ delegate.writeTo(partialChannel);
+ }
+
+}
\ No newline at end of file
Added: james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannel.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannel.java?rev=642517&view=auto
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannel.java (added)
+++ james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannel.java Sat Mar 29 01:02:34 2008
@@ -0,0 +1,96 @@
+/****************************************************************
+ * 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.james.imapserver.processor.imap4rev1;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+/**
+ * Filters a {@link WritableByteChannel}
+ * to supply a limited byte range
+ */
+class PartialWritableByteChannel implements WritableByteChannel {
+
+ private final WritableByteChannel delegate;
+ private final long firstOctet;
+ private final long numberOfOctets;
+ private long bytesWritten;
+
+ public PartialWritableByteChannel(final WritableByteChannel delegate, final long firstOctet, final long numberOfOctets) {
+ super();
+ this.delegate = delegate;
+ this.firstOctet = firstOctet;
+ this.numberOfOctets = numberOfOctets;
+ bytesWritten = 0;
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ final int result;
+ final long bytesToIgnore = firstOctet - bytesWritten;
+ if (bytesToIgnore > 0) {
+ final int remaining = src.remaining();
+ if (remaining <= bytesToIgnore) {
+ result = ignoreRemaining(src);
+ } else {
+ final int remainingBytesToIgnore = (int) bytesToIgnore;
+ src.position(src.position() + remainingBytesToIgnore);
+ result = writeRemaining(src, numberOfOctets) + remainingBytesToIgnore;
+ }
+ } else {
+ final long bytesToWrite = numberOfOctets - bytesWritten + firstOctet;
+ result = writeRemaining(src, bytesToWrite);
+ }
+ bytesWritten += result;
+ return result;
+ }
+
+ private int writeRemaining(ByteBuffer src, final long bytesToWrite) throws IOException {
+ final int remaining = src.remaining();
+ final int result;
+ if (bytesToWrite <= 0) {
+ result = ignoreRemaining(src);
+ } else if (remaining < bytesToWrite ) {
+ result = delegate.write(src);
+ } else {
+ final ByteBuffer slice = src.asReadOnlyBuffer();
+ slice.limit(slice.position() + (int) bytesToWrite);
+ delegate.write(slice);
+ result = ignoreRemaining(src);
+ }
+ return result;
+ }
+
+ private int ignoreRemaining(ByteBuffer src) {
+ final int result;
+ result = src.remaining();
+ src.position(src.limit());
+ return result;
+ }
+
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ public boolean isOpen() {
+ return delegate.isOpen();
+ }
+
+}
Added: james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElementTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElementTest.java?rev=642517&view=auto
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElementTest.java (added)
+++ james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialFetchBodyElementTest.java Sat Mar 29 01:02:34 2008
@@ -0,0 +1,72 @@
+/****************************************************************
+ * 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.james.imapserver.processor.imap4rev1;
+
+import org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class PartialFetchBodyElementTest extends MockObjectTestCase {
+
+ private static final long NUMBER_OF_OCTETS = 100;
+
+ Mock mockBodyElement;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mockBodyElement = mock(BodyElement.class);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testSizeShouldBeNumberOfOctetsWhenSizeMoreWhenStartIsZero() throws Exception {
+ long moreThanNumberOfOctets = NUMBER_OF_OCTETS + 1;
+ PartialFetchBodyElement element = new PartialFetchBodyElement((BodyElement) mockBodyElement.proxy(),
+ 0, NUMBER_OF_OCTETS);
+ mockBodyElement.expects(once()).method("size").will(returnValue(new Long(moreThanNumberOfOctets)));
+ assertEquals("Size is more than number of octets so should be number of octets", NUMBER_OF_OCTETS, element.size());
+ }
+
+ public void testSizeShouldBeSizeWhenNumberOfOctetsMoreWhenStartIsZero() throws Exception {
+ long lessThanNumberOfOctets = NUMBER_OF_OCTETS -1;
+ PartialFetchBodyElement element = new PartialFetchBodyElement((BodyElement) mockBodyElement.proxy(),
+ 0, NUMBER_OF_OCTETS);
+ mockBodyElement.expects(once()).method("size").will(returnValue(new Long(lessThanNumberOfOctets)));
+ assertEquals("Size is less than number of octets so should be size", lessThanNumberOfOctets, element.size());
+ }
+
+ public void testWhenStartPlusNumberOfOctetsIsMoreThanSizeSizeShouldBeSizeMinusStart() throws Exception {
+ long size = 60;
+ PartialFetchBodyElement element = new PartialFetchBodyElement((BodyElement) mockBodyElement.proxy(),
+ 10, NUMBER_OF_OCTETS);
+ mockBodyElement.expects(once()).method("size").will(returnValue(new Long(size)));
+ assertEquals("Size is less than number of octets so should be size", 50, element.size());
+ }
+
+ public void testWhenStartPlusNumberOfOctetsIsLessThanSizeSizeShouldBeNumberOfOctetsMinusStart() throws Exception {
+ long size = 600;
+ PartialFetchBodyElement element = new PartialFetchBodyElement((BodyElement) mockBodyElement.proxy(),
+ 10, NUMBER_OF_OCTETS);
+ mockBodyElement.expects(once()).method("size").will(returnValue(new Long(size)));
+ assertEquals("Size is less than number of octets so should be size", 90, element.size());
+ }
+}
Added: james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannelTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannelTest.java?rev=642517&view=auto
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannelTest.java (added)
+++ james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/PartialWritableByteChannelTest.java Sat Mar 29 01:02:34 2008
@@ -0,0 +1,484 @@
+/****************************************************************
+ * 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.james.imapserver.processor.imap4rev1;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+import junit.framework.TestCase;
+
+public class PartialWritableByteChannelTest extends TestCase implements WritableByteChannel {
+
+ private static final int CAPACITY = 2048;
+
+ ByteBuffer sink;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ sink = ByteBuffer.allocate(CAPACITY);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testShouldPassFullBufferWhenStartZeroSizeLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 10);
+ assertEquals(10, channel.write(src));
+ assertEquals(10, sink.position());
+ sink.flip();
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testShouldIgnoreBytesAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 4);
+ assertEquals(10, channel.write(src));
+ assertEquals(4, sink.position());
+ sink.flip();
+ for (int i=0;i<4;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 4, 6);
+ assertEquals(10, channel.write(src));
+ assertEquals(6, sink.position());
+ sink.flip();
+ for (int i=4;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 4, 2);
+ assertEquals(10, channel.write(src));
+ assertEquals(2, sink.position());
+ sink.flip();
+ for (int i=4;i<6;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testMultiBufferShouldPassFullBufferWhenStartZeroSizeLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 50);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(50, sink.position());
+ sink.flip();
+ for (int l=0;l<5;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ }
+
+ public void testMultiBufferOnBoundaryShouldIgnoreBytesAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 30);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(30, sink.position());
+ sink.flip();
+ for (int l=0;l<3;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryShouldIgnoreBytesAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 39);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(39, sink.position());
+ sink.flip();
+ for (int l=0;l<3;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ for (int i=0;i<9;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryShouldIgnoreBytesAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 0, 31);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(31, sink.position());
+ sink.flip();
+ for (int l=0;l<3;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ assertEquals(0, sink.get());
+ }
+
+ public void testMultiBufferOnBoundaryOctetsOverBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 20, 21);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(21, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ assertEquals(0, sink.get());
+ }
+
+ public void testMultiBufferAfterBoundaryOctetsOverBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 21, 21);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(21, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=1;i<11;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ assertEquals(1, sink.get());
+ }
+
+ public void testMultiBufferBeforeBoundaryOctetsOverBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 19, 21);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(21, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=9;i<19;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ assertEquals(9, sink.get());
+ }
+
+ public void testMultiBufferOnBoundaryOctetsOnBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 20, 20);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(20, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=0;i<10;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryOctetsObBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 21, 20);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(20, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=1;i<11;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryOctetsOnBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 19, 20);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(20, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=9;i<19;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ }
+
+ public void testMultiBufferOnBoundaryOctetsUnderBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 20, 19);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(19, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=0;i<10;i++) {
+ if (sink.hasRemaining()) {
+ assertEquals(i, sink.get());
+ }
+ }
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryOctetsUnderBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 21, 19);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(19, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=1;i<11;i++) {
+ if (sink.hasRemaining()) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryOctetsUnderBufferShouldIgnoreBytesBeforeStart() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 19, 19);
+ for (int i=0;i<5;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(19, sink.position());
+ sink.flip();
+ for (int l=0;l<2;l++) {
+ for (int i=9;i<19;i++) {
+ if (sink.hasRemaining()) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+ }
+ }
+
+ public void testMultiBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 4, 2);
+ assertEquals(10, channel.write(src));
+ assertEquals(2, sink.position());
+ sink.flip();
+ for (int i=4;i<6;i++) {
+ assertEquals(i, sink.get());
+ }
+ }
+
+ public void testMultiBufferOnBoundaryOnBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 30, 30);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(30, sink.position());
+ sink.flip();
+ for (int i=0;i<30;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryOnBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 29, 30);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(30, sink.position());
+ sink.flip();
+ for (int i=9;i<39;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryOnBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 31, 30);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(30, sink.position());
+ sink.flip();
+ for (int i=1;i<31;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferOnBoundaryAfterBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 30, 31);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(31, sink.position());
+ sink.flip();
+ for (int i=0;i<31;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryAfterBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 29, 31);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(31, sink.position());
+ sink.flip();
+ for (int i=9;i<40;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryAfterBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 31, 31);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(31, sink.position());
+ sink.flip();
+ for (int i=1;i<32;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferOnBoundaryBeforeBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 30, 29);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(29, sink.position());
+ sink.flip();
+ for (int i=0;i<29;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferBeforeBoundaryBeforeBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 29, 29);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(29, sink.position());
+ sink.flip();
+ for (int i=9;i<38;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public void testMultiBufferAfterBoundaryBeforeBufferShouldIgnoreBytesBeforeStartAndAfterLimit() throws Exception {
+ byte [] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ ByteBuffer src = ByteBuffer.wrap(bytes);
+ PartialWritableByteChannel channel = new PartialWritableByteChannel(this, 31, 29);
+ for (int i=0;i<8;i++) {
+ assertEquals(10, channel.write(src));
+ src.rewind();
+ }
+ assertEquals(29, sink.position());
+ sink.flip();
+ for (int i=1;i<30;i++) {
+ assertEquals(i % 10, sink.get());
+ }
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ int result = src.remaining();
+ sink.put(src);
+ return result;
+ }
+
+ public void close() throws IOException {
+ }
+
+ public boolean isOpen() {
+ return true;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org