001: /*
002: * Copyright (c) xsocket.org, 2006-2008. All rights reserved.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
019: * The latest copy of this software may be found on http://www.xsocket.org/
020: */
021: package org.xsocket.connection;
022:
023: import java.io.File;
024: import java.io.IOException;
025: import java.io.RandomAccessFile;
026: import java.nio.BufferUnderflowException;
027: import java.nio.ByteBuffer;
028: import java.nio.channels.FileChannel;
029: import java.nio.channels.WritableByteChannel;
030:
031: import java.util.ArrayList;
032: import java.util.List;
033:
034: import org.junit.Assert;
035: import org.junit.Test;
036: import org.xsocket.QAUtil;
037: import org.xsocket.connection.BlockingConnection;
038: import org.xsocket.connection.IBlockingConnection;
039: import org.xsocket.connection.IDataHandler;
040: import org.xsocket.connection.INonBlockingConnection;
041: import org.xsocket.connection.IServer;
042: import org.xsocket.connection.Server;
043: import org.xsocket.connection.ConnectionUtils;
044:
045: import com.sun.jna.ptr.ByteByReference;
046:
047: /**
048: *
049: * @author grro@xsocket.org
050: */
051: public final class TransferAvailableByDelimiterTest {
052:
053: private static final String DELIMITER = "\r\n\r\n\r";
054: private static final String OK = "OK";
055:
056: @Test
057: public void testSimple() throws Exception {
058: DataSink dataSink = new DataSink();
059: IServer server = new Server(new Handler(dataSink));
060: ConnectionUtils.start(server);
061:
062: IBlockingConnection connection = new BlockingConnection(
063: "localhost", server.getLocalPort());
064: connection.setAutoflush(false);
065:
066: byte[] request1 = QAUtil.generateByteArray(60);
067: connection.write(request1);
068: connection.flush();
069: QAUtil.sleep(200);
070:
071: Assert.assertTrue(dataSink.getSize() > 50);
072:
073: byte[] request2 = QAUtil.generateByteArray(20);
074: connection.write(request2);
075: connection.flush();
076: QAUtil.sleep(200);
077:
078: Assert.assertTrue(dataSink.getSize() > 70);
079:
080: connection.write(DELIMITER);
081: connection.flush();
082:
083: String okResponse = connection.readStringByDelimiter(DELIMITER,
084: Integer.MAX_VALUE);
085: Assert.assertTrue(okResponse.equals(OK));
086:
087: Assert.assertTrue(dataSink.getSize() == 80);
088:
089: connection.close();
090: server.close();
091: }
092:
093: @Test
094: public void testFile() throws Exception {
095: File file = File.createTempFile("ere", "rsasd");
096: file.deleteOnExit();
097:
098: FileChannel fc = new RandomAccessFile(file, "rw").getChannel();
099:
100: IServer server = new Server(new Handler(fc));
101: ConnectionUtils.start(server);
102:
103: IBlockingConnection connection = new BlockingConnection(
104: "localhost", server.getLocalPort());
105: connection.setAutoflush(false);
106:
107: byte[] request = QAUtil.generateByteArray(60000);
108: connection.write(request);
109: connection.flush();
110:
111: connection.write(DELIMITER);
112: connection.flush();
113: connection.close();
114:
115: QAUtil.sleep(500);
116:
117: Assert.assertTrue(fc.size() == 60000);
118:
119: fc.close();
120: file.delete();
121: server.close();
122: }
123:
124: private static final class DataSink implements WritableByteChannel {
125:
126: private final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
127:
128: private boolean isOpen = true;
129:
130: public void close() throws IOException {
131: isOpen = false;
132: }
133:
134: public boolean isOpen() {
135: return isOpen;
136: }
137:
138: public int write(ByteBuffer buffer) throws IOException {
139: int size = buffer.remaining();
140: buffers.add(buffer.duplicate());
141:
142: buffer.position(buffer.limit());
143: return size;
144: }
145:
146: int getSize() {
147: int size = 0;
148:
149: ArrayList<ByteBuffer> buffersCopy = (ArrayList<ByteBuffer>) buffers
150: .clone();
151: for (ByteBuffer buffer : buffersCopy) {
152: size += buffer.remaining();
153: }
154:
155: return size;
156: }
157:
158: ByteBuffer[] getReceiveBuffers() {
159: return buffers.toArray(new ByteBuffer[buffers.size()]);
160: }
161: }
162:
163: private static final class Handler implements IDataHandler {
164:
165: private WritableByteChannel dataSink = null;
166:
167: public Handler(WritableByteChannel dataSink) {
168: this .dataSink = dataSink;
169: }
170:
171: public boolean onData(INonBlockingConnection connection)
172: throws IOException, BufferUnderflowException {
173: int available = connection.available();
174:
175: int i = connection.indexOf(DELIMITER);
176: if (i < 0) {
177: connection.transferTo(dataSink, available);
178:
179: } else {
180: connection.transferTo(dataSink, i);
181: connection.readStringByLength(DELIMITER.length()); // remove delimiter
182:
183: connection.write(OK);
184: connection.write(DELIMITER);
185: }
186:
187: return true;
188: }
189: }
190: }
|