summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Clayton <alex.clayton@isode.com>2016-03-16 13:48:37 (GMT)
committerAlex Clayton <alex.clayton@isode.com>2016-03-16 14:05:38 (GMT)
commit8b9891afc85d114ff1e9c9a0291a4aaee8baeb09 (patch)
tree5027dc69d6ca785e0ed94aebc7232b3790b51464
parent892af8539f2b46e840d7344489529259d1df03b9 (diff)
downloadstroke-8b9891afc85d114ff1e9c9a0291a4aaee8baeb09.zip
stroke-8b9891afc85d114ff1e9c9a0291a4aaee8baeb09.tar.bz2
Add FileWriteBytestream class and test.
Adds a FileWriteBytestream class plus a test for it. These had been missed out previously. Also as per patch 'Fix crash when saving a received file to non-writable location' changed WriteBytestream.write() method to return a boolean indicating success or failure. Test-information: Tests pass ok. Change-Id: I0c3676db8b67573142e8628f439cecf54f3f8f1a
-rw-r--r--src/com/isode/stroke/filetransfer/ByteArrayWriteBytestream.java6
-rw-r--r--src/com/isode/stroke/filetransfer/FileTransferError.java3
-rw-r--r--src/com/isode/stroke/filetransfer/FileWriteBytestream.java73
-rw-r--r--src/com/isode/stroke/filetransfer/SOCKS5BytestreamClientSession.java1
-rw-r--r--src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerSession.java27
-rw-r--r--src/com/isode/stroke/filetransfer/WriteBytestream.java11
-rw-r--r--test/com/isode/stroke/filetransfer/FileWriteBytestreamTest.java83
7 files changed, 185 insertions, 19 deletions
diff --git a/src/com/isode/stroke/filetransfer/ByteArrayWriteBytestream.java b/src/com/isode/stroke/filetransfer/ByteArrayWriteBytestream.java
index eb3a30f..d983e89 100644
--- a/src/com/isode/stroke/filetransfer/ByteArrayWriteBytestream.java
+++ b/src/com/isode/stroke/filetransfer/ByteArrayWriteBytestream.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010-2015 Isode Limited. 2 * Copyright (c) 2010-2016 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
@@ -20,9 +20,11 @@ public class ByteArrayWriteBytestream extends WriteBytestream {
20 public ByteArrayWriteBytestream() { 20 public ByteArrayWriteBytestream() {
21 } 21 }
22 22
23 public void write(final ByteArray bytes) { 23 @Override
24 public boolean write(final ByteArray bytes) {
24 data.append(bytes); 25 data.append(bytes);
25 onWrite.emit(bytes); 26 onWrite.emit(bytes);
27 return true;
26 } 28 }
27 29
28 public ByteArray getData() { 30 public ByteArray getData() {
diff --git a/src/com/isode/stroke/filetransfer/FileTransferError.java b/src/com/isode/stroke/filetransfer/FileTransferError.java
index ac135d6..fbb5ec6 100644
--- a/src/com/isode/stroke/filetransfer/FileTransferError.java
+++ b/src/com/isode/stroke/filetransfer/FileTransferError.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010-2015 Isode Limited. 2 * Copyright (c) 2010-2016 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
@@ -19,6 +19,7 @@ public class FileTransferError {
19 UnknownError, 19 UnknownError,
20 PeerError, 20 PeerError,
21 ReadError, 21 ReadError,
22 WriteError,
22 ClosedError 23 ClosedError
23 }; 24 };
24 25
diff --git a/src/com/isode/stroke/filetransfer/FileWriteBytestream.java b/src/com/isode/stroke/filetransfer/FileWriteBytestream.java
new file mode 100644
index 0000000..7fa068d
--- /dev/null
+++ b/src/com/isode/stroke/filetransfer/FileWriteBytestream.java
@@ -0,0 +1,73 @@
1/* Copyright (c) 2016, Isode Limited, London, England.
2 * All rights reserved.
3 *
4 * Acquisition and use of this software and related materials for any
5 * purpose requires a written license agreement from Isode Limited,
6 * or a written license from an organisation licensed by Isode Limited
7 * to grant such a license.
8 *
9 */
10package com.isode.stroke.filetransfer;
11
12import java.io.File;
13import java.io.FileNotFoundException;
14import java.io.FileOutputStream;
15import java.io.IOException;
16
17import com.isode.stroke.base.ByteArray;
18
19public class FileWriteBytestream extends WriteBytestream {
20
21 private final String filePath_;
22
23 private FileOutputStream stream_ = null;
24
25 public FileWriteBytestream(String filePath) {
26 filePath_ = filePath;
27 }
28
29 @Override
30 protected void finalize() throws Throwable {
31 try {
32 close();
33 }
34 finally {
35 super.finalize();
36 }
37 }
38
39 @Override
40 public boolean write(ByteArray data) {
41 if (data.isEmpty()) {
42 return true;
43 }
44 if (stream_ == null) {
45 try {
46 stream_ = new FileOutputStream(filePath_);
47 } catch (FileNotFoundException e) {
48 return false;
49 }
50 }
51 try {
52 stream_.write(data.getData());
53 stream_.flush();
54 } catch (IOException e) {
55 return false;
56 }
57 onWrite.emit(data);
58 return true;
59 }
60
61 public void close() {
62 if (stream_ != null) {
63 try {
64 stream_.close();
65 } catch (IOException e) {
66 // Ignore exception
67 }
68 stream_ = null;
69 }
70 }
71
72
73}
diff --git a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamClientSession.java b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamClientSession.java
index 18e4484..982e3e9 100644
--- a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamClientSession.java
+++ b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamClientSession.java
@@ -116,7 +116,6 @@ public class SOCKS5BytestreamClientSession extends SOCKS5AbstractBytestreamSessi
116 state = State.Reading; 116 state = State.Reading;
117 writeBytestream = writeStream; 117 writeBytestream = writeStream;
118 writeBytestream.write(unprocessedData); 118 writeBytestream.write(unprocessedData);
119 //onBytesReceived(unprocessedData.size());
120 unprocessedData.clear(); 119 unprocessedData.clear();
121 } else { 120 } else {
122 logger_.fine("Session isn't ready for transfer yet!\n"); 121 logger_.fine("Session isn't ready for transfer yet!\n");
diff --git a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerSession.java b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerSession.java
index 8facca0..f9c1f95 100644
--- a/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerSession.java
+++ b/src/com/isode/stroke/filetransfer/SOCKS5BytestreamServerSession.java
@@ -82,7 +82,7 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
82 } 82 }
83 83
84 public void stop() { 84 public void stop() {
85 finish(false); 85 finish();
86 } 86 }
87 87
88 public void startSending(ReadBytestream stream) { 88 public void startSending(ReadBytestream stream) {
@@ -124,8 +124,12 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
124 return streamID; 124 return streamID;
125 } 125 }
126 126
127 private void finish(boolean error) { 127 private void finish() {
128 logger_.fine(error + " " + state + "\n"); 128 finish(null);
129 }
130
131 private void finish(FileTransferError error) {
132 logger_.fine("state: " + state + "\n");
129 if (State.Finished.equals(state)) { 133 if (State.Finished.equals(state)) {
130 return; 134 return;
131 } 135 }
@@ -140,11 +144,7 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
140 } 144 }
141 readBytestream = null; 145 readBytestream = null;
142 state = State.Finished; 146 state = State.Finished;
143 if (error) { 147 onFinished.emit(error);
144 onFinished.emit(new FileTransferError(FileTransferError.Type.PeerError));
145 } else {
146 onFinished.emit(null);
147 }
148 } 148 }
149 149
150 private void process() { 150 private void process() {
@@ -193,7 +193,7 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
193 if (!hasBytestream) { 193 if (!hasBytestream) {
194 logger_.fine("Readstream or Wrtiestream with ID " + streamID + " not found!\n"); 194 logger_.fine("Readstream or Wrtiestream with ID " + streamID + " not found!\n");
195 connection.write(result); 195 connection.write(result);
196 finish(true); 196 finish(new FileTransferError(FileTransferError.Type.PeerError));
197 } 197 }
198 else { 198 else {
199 logger_.fine("Found stream. Sent OK.\n"); 199 logger_.fine("Found stream. Sent OK.\n");
@@ -210,14 +210,15 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
210 unprocessedData.append(data); 210 unprocessedData.append(data);
211 process(); 211 process();
212 } else { 212 } else {
213 writeBytestream.write(new ByteArray(data)); 213 if (!writeBytestream.write(new ByteArray(data))) {
214 // onBytesReceived(data.size()); 214 finish(new FileTransferError(FileTransferError.Type.WriteError));
215 }
215 } 216 }
216 } 217 }
217 218
218 private void handleDisconnected(final Connection.Error error) { 219 private void handleDisconnected(final Connection.Error error) {
219 logger_.fine((error != null ? (error.equals(Connection.Error.ReadError) ? "Read Error" : "Write Error") : "No Error") + "\n"); 220 logger_.fine((error != null ? (error.equals(Connection.Error.ReadError) ? "Read Error" : "Write Error") : "No Error") + "\n");
220 finish(error != null ? true : false); 221 finish(error != null ? new FileTransferError(FileTransferError.Type.PeerError) : null);
221 } 222 }
222 223
223 private void handleDataAvailable() { 224 private void handleDataAvailable() {
@@ -244,7 +245,7 @@ public class SOCKS5BytestreamServerSession extends SOCKS5AbstractBytestreamSess
244 //} 245 //}
245 } 246 }
246 else { 247 else {
247 finish(false); 248 finish();
248 } 249 }
249 } 250 }
250} \ No newline at end of file 251} \ No newline at end of file
diff --git a/src/com/isode/stroke/filetransfer/WriteBytestream.java b/src/com/isode/stroke/filetransfer/WriteBytestream.java
index c243bdc..81d2093 100644
--- a/src/com/isode/stroke/filetransfer/WriteBytestream.java
+++ b/src/com/isode/stroke/filetransfer/WriteBytestream.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2016 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
@@ -16,7 +16,14 @@ import com.isode.stroke.signals.Signal1;
16 16
17public abstract class WriteBytestream { 17public abstract class WriteBytestream {
18 18
19 public abstract void write(final ByteArray b); 19 /**
20 * Write data from a {@link ByteArray} to the bytestream. On
21 * success {@code true} is returned and {@link #onWrite} is called.
22 * On failure {@code false} is returned.
23 * @param b The {@link ByteArray} to write.
24 * @return {@code true} on success, {@code false} on failure.
25 */
26 public abstract boolean write(final ByteArray b);
20 27
21 public final Signal1<ByteArray> onWrite = new Signal1<ByteArray>(); 28 public final Signal1<ByteArray> onWrite = new Signal1<ByteArray>();
22} \ No newline at end of file 29} \ No newline at end of file
diff --git a/test/com/isode/stroke/filetransfer/FileWriteBytestreamTest.java b/test/com/isode/stroke/filetransfer/FileWriteBytestreamTest.java
new file mode 100644
index 0000000..3e06646
--- /dev/null
+++ b/test/com/isode/stroke/filetransfer/FileWriteBytestreamTest.java
@@ -0,0 +1,83 @@
1/* Copyright (c) 2016, Isode Limited, London, England.
2 * All rights reserved.
3 *
4 * Acquisition and use of this software and related materials for any
5 * purpose requires a written license agreement from Isode Limited,
6 * or a written license from an organisation licensed by Isode Limited
7 * to grant such a license.
8 *
9 */
10package com.isode.stroke.filetransfer;
11
12import static org.junit.Assert.assertFalse;
13import static org.junit.Assert.assertTrue;
14
15import java.io.File;
16import java.io.IOException;
17
18import org.junit.Test;
19
20import com.isode.stroke.base.ByteArray;
21import com.isode.stroke.signals.Slot1;
22
23/**
24 * Tests for {@link FileWriteBytestream}
25 *
26 */
27public class FileWriteBytestreamTest {
28
29 private boolean onWriteWasCalled = false;
30
31 @Test
32 public void testSuccessfulWrite() {
33 File tempfile = null;
34 String filename = null;
35 try {
36 try {
37 tempfile = File.createTempFile("write_file_bytestream_test_", ".tmp");
38 filename = tempfile.getAbsolutePath();
39 } catch (IOException e) {
40 // Unable to create file exit test
41 return;
42 }
43 WriteBytestream writeBytestream = new FileWriteBytestream(filename);
44 writeBytestream.onWrite.connect(new Slot1<ByteArray>() {
45
46 @Override
47 public void call(ByteArray data) {
48 handleOnWrite(data);
49 }
50
51 });
52
53 assertTrue(writeBytestream.write(new ByteArray("Some data.")));
54 assertTrue(onWriteWasCalled);
55 }
56 finally {
57 if (tempfile != null && tempfile.exists()) {
58 tempfile.delete();
59 }
60 }
61 }
62
63 @Test
64 public void testFailingWrite() {
65 WriteBytestream writeBytestream = new FileWriteBytestream("");
66 writeBytestream.onWrite.connect(new Slot1<ByteArray>() {
67
68 @Override
69 public void call(ByteArray data) {
70 handleOnWrite(data);
71 }
72
73 });
74
75 assertFalse(writeBytestream.write(new ByteArray("Some data.")));
76 assertFalse(onWriteWasCalled);
77 }
78
79 private void handleOnWrite(ByteArray data) {
80 onWriteWasCalled = true;
81 }
82
83}