summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/isode/stroke/base/SafeByteArray.java158
-rw-r--r--src/com/isode/stroke/compress/ZLibCodecompressor.java6
-rw-r--r--src/com/isode/stroke/network/Connection.java6
-rw-r--r--src/com/isode/stroke/network/JavaConnection.java13
-rw-r--r--src/com/isode/stroke/session/BasicSessionStream.java9
-rw-r--r--src/com/isode/stroke/session/Session.java5
-rw-r--r--src/com/isode/stroke/session/SessionTracer.java12
-rw-r--r--src/com/isode/stroke/streamstack/CompressionLayer.java6
-rw-r--r--src/com/isode/stroke/streamstack/ConnectionLayer.java14
-rw-r--r--src/com/isode/stroke/streamstack/HighLayer.java6
-rw-r--r--src/com/isode/stroke/streamstack/LowLayer.java6
-rw-r--r--src/com/isode/stroke/streamstack/StreamLayer.java6
-rw-r--r--src/com/isode/stroke/streamstack/StreamStack.java2
-rw-r--r--src/com/isode/stroke/streamstack/TLSLayer.java16
-rw-r--r--src/com/isode/stroke/streamstack/WhitespacePingLayer.java8
-rw-r--r--src/com/isode/stroke/streamstack/XMPPLayer.java26
-rw-r--r--src/com/isode/stroke/tls/TLSContext.java9
-rw-r--r--src/com/isode/stroke/tls/java/JSSEContext.java15
-rw-r--r--test/com/isode/stroke/compress/ZLibCompressorTest.java12
-rw-r--r--test/com/isode/stroke/compress/ZLibDecompressorTest.java28
-rw-r--r--test/com/isode/stroke/streamstack/StreamStackTest.java219
-rw-r--r--test/com/isode/stroke/streamstack/XMPPLayerTest.java194
22 files changed, 602 insertions, 174 deletions
diff --git a/src/com/isode/stroke/base/SafeByteArray.java b/src/com/isode/stroke/base/SafeByteArray.java
index 74c1848..ac8960f 100644
--- a/src/com/isode/stroke/base/SafeByteArray.java
+++ b/src/com/isode/stroke/base/SafeByteArray.java
@@ -22,83 +22,93 @@ public class SafeByteArray extends ByteArray {
super(s);
}
- public SafeByteArray(ByteArray b) {
- this.append(b.getData());
- }
+ public SafeByteArray(ByteArray b) {
+ this.append(b.getData());
+ }
- /**
- * Creates a new SafeByteArray object containing all
- * the elements from two existing ByteArrays (immutable add).
- *
- * @param a an existing SafeByteArray. Must not be null, but may be empty.
- * @param b an existing SafeByteArray. Must not be null, but may be empty.
- * @return a new SafeByteArray containing all the elements of <em>a</em>
- * followed by all the elements of <em>b</em>.
- */
- public static SafeByteArray plus(SafeByteArray a, SafeByteArray b) {
- SafeByteArray x = new SafeByteArray().append(a.getData());
- x.append(b);
- return x;
- }
-
- /**
- * Updates the SafeByteArray by adding all the elements
- * of another SafeByteArray to the end of the array (mutable add).
- * @param b an existing SafeByteArray. Must not be null, but may be empty
- * @return a reference to the updated object
- */
- public SafeByteArray append(ByteArray b) {
- append(b.getData());
- return this;
- }
+ /**
+ * Constructs a new ByteArray containing the bytes in a user-supplied
+ * byte[]
+ * @param c an array of bytes, which must not be null, but may contain
+ * zero elements.
+ */
+ public SafeByteArray(byte[] c) {
+ super(c);
+ }
- /**
- * Updates the SafeByteArray by adding all the bytes
- * in a byte[] to the end of the array (mutable add).
- *
- * @param b an array of bytes. Must not be null, but may contain zero
- * elements.
- *
- * @return a reference to the updated object
- */
- public SafeByteArray append(byte[] b) {
- return append(b, b.length);
- }
+ /**
+ * Creates a new SafeByteArray object containing all
+ * the elements from two existing ByteArrays (immutable add).
+ *
+ * @param a an existing SafeByteArray. Must not be null, but may be empty.
+ * @param b an existing SafeByteArray. Must not be null, but may be empty.
+ * @return a new SafeByteArray containing all the elements of <em>a</em>
+ * followed by all the elements of <em>b</em>.
+ */
+ public static SafeByteArray plus(SafeByteArray a, SafeByteArray b) {
+ SafeByteArray x = new SafeByteArray().append(a.getData());
+ x.append(b);
+ return x;
+ }
+
+ /**
+ * Updates the SafeByteArray by adding all the elements
+ * of another SafeByteArray to the end of the array (mutable add).
+ * @param b an existing SafeByteArray. Must not be null, but may be empty
+ * @return a reference to the updated object
+ */
+ public SafeByteArray append(ByteArray b) {
+ append(b.getData());
+ return this;
+ }
- /** Mutable add */
- public SafeByteArray append(byte[] b, int len) {
- for (int i = 0; i < len; i++) {
- append(b[i]);
- }
- return this;
- }
+ /**
+ * Updates the SafeByteArray by adding all the bytes
+ * in a byte[] to the end of the array (mutable add).
+ *
+ * @param b an array of bytes. Must not be null, but may contain zero
+ * elements.
+ *
+ * @return a reference to the updated object
+ */
+ public SafeByteArray append(byte[] b) {
+ return append(b, b.length);
+ }
- /**
- * Updates the SafeByteArray by adding a single byte
- * value to the end of the array (mutable add).
- * @param b a single byte
- * @return a reference to the updated object
- */
- public SafeByteArray append(byte b) {
- dataCopy_ = null; /* Invalidate cache */
- data_.add(Byte.valueOf(b));
- return this;
- }
+ /** Mutable add */
+ public SafeByteArray append(byte[] b, int len) {
+ for (int i = 0; i < len; i++) {
+ append(b[i]);
+ }
+ return this;
+ }
+
+ /**
+ * Updates the SafeByteArray by adding a single byte
+ * value to the end of the array (mutable add).
+ * @param b a single byte
+ * @return a reference to the updated object
+ */
+ public SafeByteArray append(byte b) {
+ dataCopy_ = null; /* Invalidate cache */
+ data_.add(Byte.valueOf(b));
+ return this;
+ }
- /**
- * Updates the SafeByteArray by adding all the bytes
- * obtained by UTF-8 encoding the provided String to the end of the array (mutable add).
- * @param s a String that must not be null.
- * @return a reference to the updated object.
- */
- public SafeByteArray append(String s) {
- byte[] bytes;
- try {
- bytes = s.getBytes("UTF-8");
- } catch (UnsupportedEncodingException ex) {
- throw new IllegalStateException("JVM has no 'UTF-8' encoding");
- }
- append(bytes);
- return this;
- }
+ /**
+ * Updates the SafeByteArray by adding all the bytes
+ * obtained by UTF-8 encoding the provided String to the end of the array (mutable add).
+ * @param s a String that must not be null.
+ * @return a reference to the updated object.
+ */
+ public SafeByteArray append(String s) {
+ byte[] bytes;
+ try {
+ bytes = s.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException ex) {
+ throw new IllegalStateException("JVM has no 'UTF-8' encoding");
+ }
+ append(bytes);
+ return this;
+ }
} \ No newline at end of file
diff --git a/src/com/isode/stroke/compress/ZLibCodecompressor.java b/src/com/isode/stroke/compress/ZLibCodecompressor.java
index 3925949..fed1f33 100644
--- a/src/com/isode/stroke/compress/ZLibCodecompressor.java
+++ b/src/com/isode/stroke/compress/ZLibCodecompressor.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.compress;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZStream;
@@ -17,8 +17,8 @@ public abstract class ZLibCodecompressor {
protected static final int CHUNK_SIZE = 1024;
protected final ZStream stream_ = new ZStream();
- public ByteArray process(ByteArray input) throws ZLibException {
- ByteArray output = new ByteArray();
+ public SafeByteArray process(SafeByteArray input) throws ZLibException {
+ SafeByteArray output = new SafeByteArray();
stream_.avail_in = input.getSize();
stream_.next_in = input.getData();
stream_.next_in_index = 0;
diff --git a/src/com/isode/stroke/network/Connection.java b/src/com/isode/stroke/network/Connection.java
index dbda1b7..b0e4799 100644
--- a/src/com/isode/stroke/network/Connection.java
+++ b/src/com/isode/stroke/network/Connection.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.network;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.signals.Signal;
import com.isode.stroke.signals.Signal1;
@@ -30,11 +30,11 @@ public abstract class Connection {
public abstract void disconnect();
- public abstract void write(ByteArray data);
+ public abstract void write(SafeByteArray data);
public abstract HostAddressPort getLocalAddress();
public final Signal1<Boolean /*error*/> onConnectFinished = new Signal1<Boolean>();
public final Signal1<Error> onDisconnected = new Signal1<Error>();
- public final Signal1<ByteArray> onDataRead = new Signal1<ByteArray>();
+ public final Signal1<SafeByteArray> onDataRead = new Signal1<SafeByteArray>();
public final Signal onDataWritten = new Signal();
}
diff --git a/src/com/isode/stroke/network/JavaConnection.java b/src/com/isode/stroke/network/JavaConnection.java
index 4e7503b..66f068f 100644
--- a/src/com/isode/stroke/network/JavaConnection.java
+++ b/src/com/isode/stroke/network/JavaConnection.java
@@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.List;
import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.eventloop.Event.Callback;
import com.isode.stroke.eventloop.EventLoop;
import com.isode.stroke.eventloop.EventOwner;
@@ -30,16 +31,16 @@ public class JavaConnection extends Connection implements EventOwner {
* got closed.
*/
private static class ReadResult {
- public ByteArray dataRead_;
+ public SafeByteArray dataRead_;
public boolean socketClosed_;
ReadResult(boolean socketClosed) {
- dataRead_ = new ByteArray();
+ dataRead_ = new SafeByteArray();
socketClosed_ = socketClosed;
}
ReadResult(ByteArrayOutputStream byteArrayOutputStream, boolean socketClosed) {
- dataRead_ = new ByteArray(byteArrayOutputStream.toByteArray());
+ dataRead_ = new SafeByteArray(byteArrayOutputStream.toByteArray());
socketClosed_ = socketClosed;
}
}
@@ -95,7 +96,7 @@ public class JavaConnection extends Connection implements EventOwner {
}
{ /* Handle any reading */
- ByteArray dataRead;
+ SafeByteArray dataRead;
if (readNeeded) {
ReadResult rr = doRead();
@@ -299,7 +300,7 @@ public class JavaConnection extends Connection implements EventOwner {
}
}
- private void handleDataRead(final ByteArray data) {
+ private void handleDataRead(final SafeByteArray data) {
if (synchroniseReads_) {
selectionKey_.interestOps(0);
}
@@ -372,7 +373,7 @@ public class JavaConnection extends Connection implements EventOwner {
}
@Override
- public void write(ByteArray data) {
+ public void write(SafeByteArray data) {
worker_.writeBuffer_.add(data.getData());
// Check "isOpen" to Avoid Android crash see
// https://code.google.com/p/android/issues/detail?id=80785
diff --git a/src/com/isode/stroke/session/BasicSessionStream.java b/src/com/isode/stroke/session/BasicSessionStream.java
index f1e7bf1..4f0e75b 100644
--- a/src/com/isode/stroke/session/BasicSessionStream.java
+++ b/src/com/isode/stroke/session/BasicSessionStream.java
@@ -10,6 +10,7 @@ package com.isode.stroke.session;
import java.util.List;
import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.elements.Element;
import com.isode.stroke.elements.ProtocolHeader;
import com.isode.stroke.elements.StreamType;
@@ -71,15 +72,15 @@ public class BasicSessionStream extends SessionStream {
handleXMPPError();
}
});
- xmppLayer.onDataRead.connect(new Slot1<ByteArray>() {
+ xmppLayer.onDataRead.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
handleDataRead(p1);
}
});
- xmppLayer.onWriteData.connect(new Slot1<ByteArray>() {
+ xmppLayer.onWriteData.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
handleDataWritten(p1);
}
});
diff --git a/src/com/isode/stroke/session/Session.java b/src/com/isode/stroke/session/Session.java
index eb64051..815be02 100644
--- a/src/com/isode/stroke/session/Session.java
+++ b/src/com/isode/stroke/session/Session.java
@@ -10,6 +10,7 @@
package com.isode.stroke.session;
import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.elements.Element;
import com.isode.stroke.elements.ProtocolHeader;
import com.isode.stroke.elements.StreamType;
@@ -81,8 +82,8 @@ public abstract class Session {
}
public final Signal1<Element> onElementReceived = new Signal1<Element>();
public final Signal1<SessionError> onSessionFinished = new Signal1<SessionError>();
- public final Signal1<ByteArray> onDataWritten = new Signal1<ByteArray>();
- public final Signal1<ByteArray> onDataRead = new Signal1<ByteArray>();
+ public final Signal1<SafeByteArray> onDataWritten = new Signal1<SafeByteArray>();
+ public final Signal1<SafeByteArray> onDataRead = new Signal1<SafeByteArray>();
protected void setRemoteJID(JID j) {
remoteJID = j;
diff --git a/src/com/isode/stroke/session/SessionTracer.java b/src/com/isode/stroke/session/SessionTracer.java
index 7db165d..8b878a8 100644
--- a/src/com/isode/stroke/session/SessionTracer.java
+++ b/src/com/isode/stroke/session/SessionTracer.java
@@ -9,29 +9,29 @@
*/
package com.isode.stroke.session;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.signals.Slot1;
public class SessionTracer {
public SessionTracer(Session session) {
this.session = session;
- session.onDataRead.connect(new Slot1<ByteArray>() {
+ session.onDataRead.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
printData('<', p1);
}
});
- session.onDataWritten.connect(new Slot1<ByteArray>() {
+ session.onDataWritten.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
printData('>', p1);
}
});
}
- private void printData(char direction, ByteArray data) {
+ private void printData(char direction, SafeByteArray data) {
System.err.print("" + direction + direction + " " + session.getLocalJID().toString() + " ");
for (int i = 0; i < 72 - session.getLocalJID().toString().length() - session.getRemoteJID().toString().length(); ++i) {
System.err.print(direction);
diff --git a/src/com/isode/stroke/streamstack/CompressionLayer.java b/src/com/isode/stroke/streamstack/CompressionLayer.java
index d08f105..b89b3d2 100644
--- a/src/com/isode/stroke/streamstack/CompressionLayer.java
+++ b/src/com/isode/stroke/streamstack/CompressionLayer.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.compress.ZLibCompressor;
import com.isode.stroke.compress.ZLibDecompressor;
import com.isode.stroke.compress.ZLibException;
@@ -17,7 +17,7 @@ import com.isode.stroke.signals.Signal;
public class CompressionLayer extends StreamLayer {
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
try {
writeDataToChildLayer(compressor_.process(data));
}
@@ -26,7 +26,7 @@ public class CompressionLayer extends StreamLayer {
}
}
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
try {
writeDataToParentLayer(decompressor_.process(data));
}
diff --git a/src/com/isode/stroke/streamstack/ConnectionLayer.java b/src/com/isode/stroke/streamstack/ConnectionLayer.java
index 0927a32..d003b52 100644
--- a/src/com/isode/stroke/streamstack/ConnectionLayer.java
+++ b/src/com/isode/stroke/streamstack/ConnectionLayer.java
@@ -4,7 +4,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.network.Connection;
import com.isode.stroke.signals.Slot1;
@@ -12,15 +12,15 @@ public class ConnectionLayer implements LowLayer {
public ConnectionLayer(Connection connection) {
this.connection = connection;
- connection.onDataRead.connect(new Slot1<ByteArray>() {
+ connection.onDataRead.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
writeDataToParentLayer(p1);
}
});
}
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
connection.write(data);
}
@@ -29,11 +29,11 @@ public class ConnectionLayer implements LowLayer {
/* Work around multiple inheritance workaround again */
StreamLayer fakeStreamLayer_ = new StreamLayer() {
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
connection.write(data);
}
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
throw new UnsupportedOperationException("Not supported yet.");
}
};
@@ -46,7 +46,7 @@ public class ConnectionLayer implements LowLayer {
fakeStreamLayer_.setParentLayer(parentLayer);
}
- public void writeDataToParentLayer(ByteArray data) {
+ public void writeDataToParentLayer(SafeByteArray data) {
fakeStreamLayer_.writeDataToParentLayer(data);
}
}
diff --git a/src/com/isode/stroke/streamstack/HighLayer.java b/src/com/isode/stroke/streamstack/HighLayer.java
index 1ff36e1..c95e21f 100644
--- a/src/com/isode/stroke/streamstack/HighLayer.java
+++ b/src/com/isode/stroke/streamstack/HighLayer.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
/**
* Because of the lack of multiple inheritance in Java, this has to be done
@@ -18,7 +18,7 @@ import com.isode.stroke.base.ByteArray;
*/
public interface HighLayer {
- void handleDataRead(ByteArray data);
+ void handleDataRead(SafeByteArray data);
/* Should be protected */
@@ -26,6 +26,6 @@ public interface HighLayer {
void setChildLayer(LowLayer childLayer);
- void writeDataToChildLayer(ByteArray data);
+ void writeDataToChildLayer(SafeByteArray data);
}
diff --git a/src/com/isode/stroke/streamstack/LowLayer.java b/src/com/isode/stroke/streamstack/LowLayer.java
index dcead38..37b04d4 100644
--- a/src/com/isode/stroke/streamstack/LowLayer.java
+++ b/src/com/isode/stroke/streamstack/LowLayer.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
/**
* Because of the lack of multiple inheritance in Java, this has to be done
@@ -18,7 +18,7 @@ import com.isode.stroke.base.ByteArray;
*/
public interface LowLayer {
- void writeData(ByteArray data);
+ void writeData(SafeByteArray data);
/* Should be protected */
@@ -26,5 +26,5 @@ public interface LowLayer {
void setParentLayer(HighLayer parentLayer);
- void writeDataToParentLayer(ByteArray data);
+ void writeDataToParentLayer(SafeByteArray data);
}
diff --git a/src/com/isode/stroke/streamstack/StreamLayer.java b/src/com/isode/stroke/streamstack/StreamLayer.java
index ac9538b..a947400 100644
--- a/src/com/isode/stroke/streamstack/StreamLayer.java
+++ b/src/com/isode/stroke/streamstack/StreamLayer.java
@@ -9,7 +9,7 @@
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
/**
* Because of the lack of multiple inheritance in Java, this implements
@@ -26,7 +26,7 @@ public abstract class StreamLayer implements LowLayer, HighLayer {
this.parentLayer = parentLayer;
}
- public void writeDataToParentLayer(final ByteArray data) {
+ public void writeDataToParentLayer(final SafeByteArray data) {
assert parentLayer != null;
parentLayer.handleDataRead(data);
}
@@ -39,7 +39,7 @@ public abstract class StreamLayer implements LowLayer, HighLayer {
this.childLayer = childLayer;
}
- public void writeDataToChildLayer(final ByteArray data) {
+ public void writeDataToChildLayer(final SafeByteArray data) {
assert childLayer != null;
childLayer.writeData(data);
}
diff --git a/src/com/isode/stroke/streamstack/StreamStack.java b/src/com/isode/stroke/streamstack/StreamStack.java
index 08f986c..96fe2fd 100644
--- a/src/com/isode/stroke/streamstack/StreamStack.java
+++ b/src/com/isode/stroke/streamstack/StreamStack.java
@@ -49,4 +49,4 @@ public class StreamStack {
private XMPPLayer xmppLayer_;
private LowLayer physicalLayer_;
private List<StreamLayer> layers_ = new ArrayList<StreamLayer>();
-}
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/streamstack/TLSLayer.java b/src/com/isode/stroke/streamstack/TLSLayer.java
index 70bcd1a..8244766 100644
--- a/src/com/isode/stroke/streamstack/TLSLayer.java
+++ b/src/com/isode/stroke/streamstack/TLSLayer.java
@@ -11,7 +11,7 @@ package com.isode.stroke.streamstack;
import java.util.List;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.signals.Signal;
import com.isode.stroke.signals.Slot1;
import com.isode.stroke.tls.Certificate;
@@ -24,15 +24,15 @@ public class TLSLayer extends StreamLayer {
public TLSLayer(TLSContextFactory factory) {
context = factory.createTLSContext();
- context.onDataForNetwork.connect(new Slot1<ByteArray>() {
+ context.onDataForNetwork.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
writeDataToChildLayer(p1);
}
});
- context.onDataForApplication.connect(new Slot1<ByteArray>() {
+ context.onDataForApplication.connect(new Slot1<SafeByteArray>() {
- public void call(ByteArray p1) {
+ public void call(SafeByteArray p1) {
writeDataToParentLayer(p1);
}
});
@@ -44,11 +44,11 @@ public class TLSLayer extends StreamLayer {
context.connect();
}
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
context.handleDataFromApplication(data);
}
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
context.handleDataFromNetwork(data);
}
@@ -72,7 +72,7 @@ public class TLSLayer extends StreamLayer {
return context;
}
- public final Signal onError = new Signal();
+ public final Signal onError = new Signal();//needs port
public final Signal onConnected = new Signal();
private final TLSContext context;
diff --git a/src/com/isode/stroke/streamstack/WhitespacePingLayer.java b/src/com/isode/stroke/streamstack/WhitespacePingLayer.java
index 53c360a..3a1805c 100644
--- a/src/com/isode/stroke/streamstack/WhitespacePingLayer.java
+++ b/src/com/isode/stroke/streamstack/WhitespacePingLayer.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.network.Timer;
import com.isode.stroke.network.TimerFactory;
import com.isode.stroke.signals.Slot;
@@ -28,17 +28,17 @@ public class WhitespacePingLayer extends StreamLayer {
});
}
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
writeDataToChildLayer(data);
}
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
writeDataToParentLayer(data);
}
private void handleTimerTick() {
timer.stop();
- writeDataToChildLayer(new ByteArray(" "));
+ writeDataToChildLayer(new SafeByteArray(" "));
timer.start();
}
diff --git a/src/com/isode/stroke/streamstack/XMPPLayer.java b/src/com/isode/stroke/streamstack/XMPPLayer.java
index 4e7a265..6d14b9b 100644
--- a/src/com/isode/stroke/streamstack/XMPPLayer.java
+++ b/src/com/isode/stroke/streamstack/XMPPLayer.java
@@ -4,7 +4,7 @@
*/
package com.isode.stroke.streamstack;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.elements.Element;
import com.isode.stroke.elements.ProtocolHeader;
import com.isode.stroke.elements.StreamType;
@@ -25,8 +25,8 @@ import com.isode.stroke.signals.Signal1;
public class XMPPLayer implements HighLayer, XMPPParserClient {
public final Signal1<ProtocolHeader> onStreamStart = new Signal1<ProtocolHeader>();
public final Signal1<Element> onElement = new Signal1<Element>();
- public final Signal1<ByteArray> onWriteData = new Signal1<ByteArray>();
- public final Signal1<ByteArray> onDataRead = new Signal1<ByteArray>();
+ public final Signal1<SafeByteArray> onWriteData = new Signal1<SafeByteArray>();
+ public final Signal1<SafeByteArray> onDataRead = new Signal1<SafeByteArray>();
public final Signal onError = new Signal();
private PayloadParserFactoryCollection payloadParserFactories_;
@@ -59,19 +59,19 @@ public class XMPPLayer implements HighLayer, XMPPParserClient {
}
public void writeHeader(ProtocolHeader header) {
- writeDataInternal(new ByteArray(xmppSerializer_.serializeHeader(header)));
+ writeDataInternal(new SafeByteArray(xmppSerializer_.serializeHeader(header)));
}
public void writeFooter() {
- writeDataInternal(new ByteArray(xmppSerializer_.serializeFooter()));
+ writeDataInternal(new SafeByteArray(xmppSerializer_.serializeFooter()));
}
public void writeElement(Element element) {
- writeDataInternal(new ByteArray(xmppSerializer_.serializeElement(element)));
+ writeDataInternal(new SafeByteArray(xmppSerializer_.serializeElement(element)));
}
public void writeData(String data) {
- writeDataInternal(new ByteArray(data));
+ writeDataInternal(new SafeByteArray(data));
}
public void resetParser() {
@@ -87,11 +87,11 @@ public class XMPPLayer implements HighLayer, XMPPParserClient {
* Should be protected, but can't because of interface implementation.
* @param data
*/
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
handleDataReadInternal(data);
}
- protected void writeDataInternal(ByteArray data) {
+ protected void writeDataInternal(SafeByteArray data) {
onWriteData.emit(data);
writeDataToChildLayer(data);
}
@@ -115,16 +115,16 @@ public class XMPPLayer implements HighLayer, XMPPParserClient {
/* Multiple-inheritance workarounds */
private StreamLayer fakeStreamLayer_ = new StreamLayer() {
- public void writeData(ByteArray data) {
+ public void writeData(SafeByteArray data) {
throw new UnsupportedOperationException("Not supported yet.");
}
- public void handleDataRead(ByteArray data) {
+ public void handleDataRead(SafeByteArray data) {
handleDataReadInternal(data);
}
};
- private void handleDataReadInternal(ByteArray data) {
+ private void handleDataReadInternal(SafeByteArray data) {
onDataRead.emit(data);
inParser_ = true;
if(!xmppParser_.parse(data.toString())) {
@@ -146,7 +146,7 @@ public class XMPPLayer implements HighLayer, XMPPParserClient {
fakeStreamLayer_.setChildLayer(childLayer);
}
- public void writeDataToChildLayer(ByteArray data) {
+ public void writeDataToChildLayer(SafeByteArray data) {
fakeStreamLayer_.writeDataToChildLayer(data);
}
}
diff --git a/src/com/isode/stroke/tls/TLSContext.java b/src/com/isode/stroke/tls/TLSContext.java
index 738c8b6..3f5e8d7 100644
--- a/src/com/isode/stroke/tls/TLSContext.java
+++ b/src/com/isode/stroke/tls/TLSContext.java
@@ -12,6 +12,7 @@ package com.isode.stroke.tls;
import java.util.List;
import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.signals.Signal;
import com.isode.stroke.signals.Signal1;
@@ -21,8 +22,8 @@ public abstract class TLSContext {
public abstract boolean setClientCertificate(CertificateWithKey cert);
- public abstract void handleDataFromNetwork(ByteArray data);
- public abstract void handleDataFromApplication(ByteArray data);
+ public abstract void handleDataFromNetwork(SafeByteArray data);
+ public abstract void handleDataFromApplication(SafeByteArray data);
/**
* The peer certificate, as presented by the remote entity
@@ -38,8 +39,8 @@ public abstract class TLSContext {
public abstract ByteArray getFinishMessage();
- public Signal1<ByteArray> onDataForNetwork = new Signal1<ByteArray>();
- public Signal1<ByteArray> onDataForApplication = new Signal1<ByteArray>();
+ public Signal1<SafeByteArray> onDataForNetwork = new Signal1<SafeByteArray>();
+ public Signal1<SafeByteArray> onDataForApplication = new Signal1<SafeByteArray>();
public Signal onError = new Signal();
public Signal onConnected = new Signal();
}
diff --git a/src/com/isode/stroke/tls/java/JSSEContext.java b/src/com/isode/stroke/tls/java/JSSEContext.java
index da8316a..17b7d4d 100644
--- a/src/com/isode/stroke/tls/java/JSSEContext.java
+++ b/src/com/isode/stroke/tls/java/JSSEContext.java
@@ -45,6 +45,7 @@ import javax.net.ssl.SSLException;
import javax.net.ssl.X509ExtendedKeyManager;
import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.tls.CAPICertificate;
import com.isode.stroke.tls.Certificate;
import com.isode.stroke.tls.CertificateVerificationError;
@@ -238,7 +239,7 @@ public class JSSEContext extends TLSContext {
int bytesToUnwrap = 0;
int lastConsumed = 0;
HandshakeStatus handshakeStatus = null;
- ByteArray byteArray = null;
+ SafeByteArray byteArray = null;
synchronized(recvMutex) {
try {
@@ -353,7 +354,7 @@ public class JSSEContext extends TLSContext {
byte[] result = new byte[unwrappedReceived.remaining()];
unwrappedReceived.get(result);
unwrappedReceived.compact();
- byteArray = new ByteArray(result);
+ byteArray = new SafeByteArray(result);
}
}
@@ -377,7 +378,7 @@ public class JSSEContext extends TLSContext {
private int wrapAndSendData() {
int bytesSentToSocket = 0;
- ByteArray byteArray = null;
+ SafeByteArray byteArray = null;
SSLEngineResult sslEngineResult = null;
Status status = null;
HandshakeStatus handshakeStatus = null;
@@ -394,7 +395,7 @@ public class JSSEContext extends TLSContext {
if (wrappedToSend.hasRemaining()) {
byte[] b = new byte[(wrappedToSend.remaining())];
wrappedToSend.get(b);
- byteArray = new ByteArray(b);
+ byteArray = new SafeByteArray(b);
}
wrappedToSend.compact();
} /* end synchronized */
@@ -480,7 +481,7 @@ public class JSSEContext extends TLSContext {
if (wrappedToSend.hasRemaining()) {
byte[] b = new byte[(wrappedToSend.remaining())];
wrappedToSend.get(b);
- byteArray = new ByteArray(b);
+ byteArray = new SafeByteArray(b);
}
wrappedToSend.compact();
break;
@@ -917,7 +918,7 @@ public class JSSEContext extends TLSContext {
}
@Override
- public void handleDataFromNetwork(ByteArray data) {
+ public void handleDataFromNetwork(SafeByteArray data) {
if (hasError()) {
/* We have previously seen, and reported, an error. Emit again */
onError.emit();
@@ -995,7 +996,7 @@ public class JSSEContext extends TLSContext {
}
@Override
- public void handleDataFromApplication(ByteArray data) {
+ public void handleDataFromApplication(SafeByteArray data) {
if (hasError()) {
/* We have previously seen, and reported, an error. Emit again */
onError.emit();
diff --git a/test/com/isode/stroke/compress/ZLibCompressorTest.java b/test/com/isode/stroke/compress/ZLibCompressorTest.java
index 5767415..c9d1f69 100644
--- a/test/com/isode/stroke/compress/ZLibCompressorTest.java
+++ b/test/com/isode/stroke/compress/ZLibCompressorTest.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.compress;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.stringcodecs.Hexify;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
@@ -27,7 +27,7 @@ public class ZLibCompressorTest {
@Test
public void testProcess() throws Exception {
ZLibCompressor testling = new ZLibCompressor();
- ByteArray result = testling.process(new ByteArray("foo"));
+ SafeByteArray result = testling.process(new SafeByteArray("foo"));
assertEquals("78da4acbcf07000000ffff", Hexify.hexify(result));
}
@@ -35,14 +35,14 @@ public class ZLibCompressorTest {
@Test
public void testProcess_Twice() throws ZLibException {
ZLibCompressor testling = new ZLibCompressor();
- testling.process(new ByteArray("foo"));
- ByteArray result = testling.process(new ByteArray("bar"));
+ testling.process(new SafeByteArray("foo"));
+ SafeByteArray result = testling.process(new SafeByteArray("bar"));
assertEquals("4a4a2c02000000ffff", Hexify.hexify(result));
}
- public static ByteArray unhex(String string) {
+ public static SafeByteArray unhex(String string) {
HexBinaryAdapter adaptor = new HexBinaryAdapter();
- return new ByteArray(adaptor.unmarshal(string));
+ return new SafeByteArray(adaptor.unmarshal(string));
}
}
diff --git a/test/com/isode/stroke/compress/ZLibDecompressorTest.java b/test/com/isode/stroke/compress/ZLibDecompressorTest.java
index f4f5e06..d691363 100644
--- a/test/com/isode/stroke/compress/ZLibDecompressorTest.java
+++ b/test/com/isode/stroke/compress/ZLibDecompressorTest.java
@@ -9,7 +9,7 @@
*/
package com.isode.stroke.compress;
-import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.base.SafeByteArray;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -24,48 +24,48 @@ public class ZLibDecompressorTest {
@Test
public void testProcess() throws ZLibException {
ZLibDecompressor testling = new ZLibDecompressor();
- ByteArray result = testling.process(ZLibCompressorTest.unhex("78da4acbcf07000000ffff"));
+ SafeByteArray result = testling.process(ZLibCompressorTest.unhex("78da4acbcf07000000ffff"));
- assertEquals(new ByteArray("foo"), result);
+ assertEquals(new SafeByteArray("foo"), result);
}
@Test
public void testProcess_Twice() throws ZLibException {
ZLibDecompressor testling = new ZLibDecompressor();
testling.process(ZLibCompressorTest.unhex("78da4acbcf07000000ffff"));
- ByteArray result = testling.process(ZLibCompressorTest.unhex("4a4a2c02000000ffff"));
+ SafeByteArray result = testling.process(ZLibCompressorTest.unhex("4a4a2c02000000ffff"));
- assertEquals(new ByteArray("bar"), result);
+ assertEquals(new SafeByteArray("bar"), result);
}
@Test(expected = ZLibException.class)
public void testProcess_Invalid() throws ZLibException {
ZLibDecompressor testling = new ZLibDecompressor();
- testling.process(new ByteArray("invalid"));
+ testling.process(new SafeByteArray("invalid"));
}
@Test
public void testProcess_Huge() throws ZLibException {
- ByteArray data = new ByteArray();
+ SafeByteArray data = new SafeByteArray();
for (int i = 0; i < 2048; ++i) {
data.append((byte) i);
}
- ByteArray original = new ByteArray(data);
- ByteArray compressed = new ZLibCompressor().process(original);
- ByteArray decompressed = new ZLibDecompressor().process(compressed);
+ SafeByteArray original = new SafeByteArray(data);
+ SafeByteArray compressed = new ZLibCompressor().process(original);
+ SafeByteArray decompressed = new ZLibDecompressor().process(compressed);
assertEquals(original, decompressed);
}
@Test
public void testProcess_ChunkSize() throws ZLibException {
- ByteArray data = new ByteArray();
+ SafeByteArray data = new SafeByteArray();
for (int i = 0; i < 1024; ++i) {
data.append((byte) i);
}
- ByteArray original = new ByteArray(data);
- ByteArray compressed = new ZLibCompressor().process(original);
- ByteArray decompressed = new ZLibDecompressor().process(compressed);
+ SafeByteArray original = new SafeByteArray(data);
+ SafeByteArray compressed = new ZLibCompressor().process(original);
+ SafeByteArray decompressed = new ZLibDecompressor().process(compressed);
assertEquals(original, decompressed);
}
diff --git a/test/com/isode/stroke/streamstack/StreamStackTest.java b/test/com/isode/stroke/streamstack/StreamStackTest.java
new file mode 100644
index 0000000..b868a59
--- /dev/null
+++ b/test/com/isode/stroke/streamstack/StreamStackTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2010-2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.streamstack;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.Before;
+import com.isode.stroke.base.SafeByteArray;
+import com.isode.stroke.streamstack.StreamStack;
+import com.isode.stroke.streamstack.LowLayer;
+import com.isode.stroke.streamstack.XMPPLayer;
+import com.isode.stroke.streamstack.StreamLayer;
+import com.isode.stroke.parser.PlatformXMLParserFactory;
+import com.isode.stroke.parser.payloadparsers.FullPayloadParserFactoryCollection;
+import com.isode.stroke.serializer.payloadserializers.FullPayloadSerializerCollection;
+import com.isode.stroke.elements.Element;
+import com.isode.stroke.elements.StreamType;
+import com.isode.stroke.signals.Slot1;
+import java.util.Vector;
+
+public class StreamStackTest {
+
+ private class MyStreamLayer extends StreamLayer {
+
+ public MyStreamLayer(final String prepend) {
+ this.prepend_ = prepend;
+ }
+
+ public void writeData(final SafeByteArray data) {
+ writeDataToChildLayer(new SafeByteArray(prepend_).append(data));
+ }
+
+ public void handleDataRead(final SafeByteArray data) {
+ writeDataToParentLayer(new SafeByteArray(prepend_).append(data));
+ }
+
+ private String prepend_ = "";
+ };
+
+ /* Multiple-inheritance workarounds */
+
+ private StreamLayer fakeStreamLayer_ = new StreamLayer() {
+ public void writeData(SafeByteArray data) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void handleDataRead(SafeByteArray data) {
+ writeDataToParentLayer(data);
+ }
+ };
+
+ private class TestLowLayer implements LowLayer {
+
+ public Vector<SafeByteArray> data_ = new Vector<SafeByteArray>();
+
+ public TestLowLayer() {
+
+ }
+
+ public void writeData(final SafeByteArray data) {
+ data_.add(data);
+ }
+
+ public void onDataRead(SafeByteArray data) {
+ writeDataToParentLayer(data);
+ }
+
+ public HighLayer getParentLayer() {
+ return fakeStreamLayer_.getParentLayer();
+ }
+
+ public void setParentLayer(HighLayer highLayer) {
+ fakeStreamLayer_.setParentLayer(highLayer);
+ }
+
+ public void writeDataToParentLayer(SafeByteArray data) {
+ fakeStreamLayer_.writeDataToParentLayer(data);
+ }
+ };
+
+ private FullPayloadParserFactoryCollection parserFactories_ = new FullPayloadParserFactoryCollection();
+ private FullPayloadSerializerCollection serializers_ = new FullPayloadSerializerCollection();
+ private TestLowLayer physicalStream_;
+ private XMPPLayer xmppStream_;
+ private int elementsReceived_;
+ private int dataWriteReceived_;
+
+ @Before
+ public void setUp() {
+ physicalStream_ = new TestLowLayer();
+ xmppStream_ = new XMPPLayer(parserFactories_, serializers_, StreamType.ClientStreamType);
+ elementsReceived_ = 0;
+ dataWriteReceived_ = 0;
+ }
+
+ public void handleElement(Element element) {
+ ++elementsReceived_;
+ }
+
+ public void handleWriteData(final SafeByteArray SafeByteArray) {
+ ++dataWriteReceived_;
+ }
+
+ @Test
+ public void testWriteData_NoIntermediateStreamStack() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+
+ xmppStream_.writeData("foo");
+
+ assertEquals(1, physicalStream_.data_.size());
+ assertEquals(new SafeByteArray("foo"), physicalStream_.data_.get(0));
+ }
+
+ @Test
+ public void testWriteData_OneIntermediateStream() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ MyStreamLayer xStream = new MyStreamLayer("X");
+ testling.addLayer(xStream);
+
+ xmppStream_.writeData("foo");
+
+ assertEquals(1, physicalStream_.data_.size());
+ assertEquals(new SafeByteArray("Xfoo"), physicalStream_.data_.get(0));
+ }
+
+ @Test
+ public void testWriteData_TwoIntermediateStreamStack() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ MyStreamLayer xStream = new MyStreamLayer("X");
+ MyStreamLayer yStream = new MyStreamLayer("Y");
+ testling.addLayer(xStream);
+ testling.addLayer(yStream);
+
+ xmppStream_.writeData("foo");
+
+ assertEquals(1, physicalStream_.data_.size());
+ assertEquals(new SafeByteArray("XYfoo"), physicalStream_.data_.get(0));
+ }
+
+ @Test
+ public void testReadData_NoIntermediateStreamStack() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ xmppStream_.onElement.connect(new Slot1<Element>() {
+ @Override
+ public void call(Element e1) {
+ handleElement(e1);
+ }
+ });
+ physicalStream_.onDataRead(new SafeByteArray("<stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>"));
+
+ assertEquals(1, elementsReceived_);
+ }
+
+ @Test
+ public void testReadData_OneIntermediateStream() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ xmppStream_.onElement.connect(new Slot1<Element>() {
+ @Override
+ public void call(Element e1) {
+ handleElement(e1);
+ }
+ });
+ MyStreamLayer xStream = new MyStreamLayer("<");
+ testling.addLayer(xStream);
+
+ physicalStream_.onDataRead(new SafeByteArray("stream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>"));
+
+ assertEquals(1, elementsReceived_);
+ }
+
+ @Test
+ public void testReadData_TwoIntermediateStreamStack() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ xmppStream_.onElement.connect(new Slot1<Element>() {
+ @Override
+ public void call(Element e1) {
+ handleElement(e1);
+ }
+ });
+ MyStreamLayer xStream = new MyStreamLayer("s");
+ MyStreamLayer yStream = new MyStreamLayer("<");
+ testling.addLayer(xStream);
+ testling.addLayer(yStream);
+
+ physicalStream_.onDataRead(new SafeByteArray("tream:stream xmlns:stream='http://etherx.jabber.org/streams'><presence/>"));
+
+ assertEquals(1, elementsReceived_);
+ }
+
+ @Test
+ public void testAddLayer_ExistingOnWriteDataSlot() {
+ StreamStack testling = new StreamStack(xmppStream_, physicalStream_);
+ xmppStream_.onWriteData.connect(new Slot1<SafeByteArray>() {
+ @Override
+ public void call(SafeByteArray b1) {
+ handleWriteData(b1);
+ }
+ });
+ MyStreamLayer xStream = new MyStreamLayer("X");
+ testling.addLayer(xStream);
+
+ xmppStream_.writeData("foo");
+
+ assertEquals(1, dataWriteReceived_);
+ }
+} \ No newline at end of file
diff --git a/test/com/isode/stroke/streamstack/XMPPLayerTest.java b/test/com/isode/stroke/streamstack/XMPPLayerTest.java
new file mode 100644
index 0000000..1043291
--- /dev/null
+++ b/test/com/isode/stroke/streamstack/XMPPLayerTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2010-2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.streamstack;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.Before;
+import com.isode.stroke.base.SafeByteArray;
+import com.isode.stroke.streamstack.XMPPLayer;
+import com.isode.stroke.streamstack.StreamStack;
+import com.isode.stroke.streamstack.LowLayer;
+import com.isode.stroke.streamstack.XMPPLayer;
+import com.isode.stroke.streamstack.StreamLayer;
+import com.isode.stroke.parser.PlatformXMLParserFactory;
+import com.isode.stroke.parser.payloadparsers.FullPayloadParserFactoryCollection;
+import com.isode.stroke.serializer.payloadserializers.FullPayloadSerializerCollection;
+import com.isode.stroke.parser.PayloadParserFactoryCollection;
+import com.isode.stroke.serializer.PayloadSerializerCollection;
+import com.isode.stroke.elements.ProtocolHeader;
+import com.isode.stroke.elements.Element;
+import com.isode.stroke.elements.StreamType;
+import com.isode.stroke.elements.Presence;
+import com.isode.stroke.signals.Slot1;
+import com.isode.stroke.signals.Slot;
+import java.util.Vector;
+
+public class XMPPLayerTest {
+
+ private class XMPPLayerExposed extends XMPPLayer {
+
+ public XMPPLayerExposed(PayloadParserFactoryCollection payloadParserFactories, PayloadSerializerCollection payloadSerializers, StreamType streamType) {
+ super(payloadParserFactories, payloadSerializers, streamType);
+ }
+
+ //using XMPPLayer::handleDataRead;
+ //using HighLayer::setChildLayer;
+ };
+
+ /* Multiple-inheritance workarounds */
+
+ private StreamLayer fakeStreamLayer_ = new StreamLayer() {
+ public void writeData(SafeByteArray data) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void handleDataRead(SafeByteArray data) {
+ writeDataToParentLayer(data);
+ }
+ };
+
+ private class DummyLowLayer implements LowLayer {
+
+ public String writtenData = "";
+
+ public DummyLowLayer() {
+
+ }
+
+ public void writeData(final SafeByteArray data) {
+ writtenData += data.toString();
+ }
+
+ public HighLayer getParentLayer() {
+ return fakeStreamLayer_.getParentLayer();
+ }
+
+ public void setParentLayer(HighLayer highLayer) {
+ fakeStreamLayer_.setParentLayer(highLayer);
+ }
+
+ public void writeDataToParentLayer(SafeByteArray data) {
+ fakeStreamLayer_.writeDataToParentLayer(data);
+ }
+ };
+
+ private FullPayloadParserFactoryCollection parserFactories_ = new FullPayloadParserFactoryCollection();
+ private FullPayloadSerializerCollection serializers_ = new FullPayloadSerializerCollection();
+ private DummyLowLayer lowLayer_;
+ private XMPPLayerExposed testling_;
+ private PlatformXMLParserFactory xmlParserFactory_;
+ private int elementsReceived_;
+ private int errorReceived_;
+
+ @Before
+ public void setUp() {
+ lowLayer_ = new DummyLowLayer();
+ testling_ = new XMPPLayerExposed(parserFactories_, serializers_, StreamType.ClientStreamType);
+ testling_.setChildLayer(lowLayer_);
+ elementsReceived_ = 0;
+ errorReceived_ = 0;
+ }
+
+ public void handleElement(Element element) {
+ ++elementsReceived_;
+ }
+
+ public void handleElementAndReset(Element element) {
+ ++elementsReceived_;
+ testling_.resetParser();
+ }
+
+ public void handleError() {
+ ++errorReceived_;
+ }
+
+ @Test
+ public void testParseData_Error() {
+ testling_.onError.connect(new Slot() {
+ @Override
+ public void call() {
+ handleError();
+ }
+ });
+
+ testling_.handleDataRead(new SafeByteArray("<iq>"));
+
+ assertEquals(1, errorReceived_);
+ }
+
+ @Test
+ public void testResetParser() {
+ testling_.onElement.connect(new Slot1<Element>() {
+ @Override
+ public void call(Element e1) {
+ handleElement(e1);
+ }
+ });
+ testling_.onError.connect(new Slot() {
+ @Override
+ public void call() {
+ handleError();
+ }
+ });
+
+ testling_.handleDataRead(new SafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >"));
+ testling_.resetParser();
+ testling_.handleDataRead(new SafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >"));
+ testling_.handleDataRead(new SafeByteArray("<presence/>"));
+
+ assertEquals(1, elementsReceived_);
+ assertEquals(0, errorReceived_);
+ }
+
+ @Test
+ public void testResetParser_FromSlot() {
+ testling_.onElement.connect(new Slot1<Element>() {
+ @Override
+ public void call(Element e1) {
+ handleElementAndReset(e1);
+ }
+ });
+ testling_.handleDataRead(new SafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>"));
+ testling_.handleDataRead(new SafeByteArray("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>"));
+
+ assertEquals(2, elementsReceived_);
+ assertEquals(0, errorReceived_);
+ }
+
+ @Test
+ public void testWriteHeader() {
+ ProtocolHeader header = new ProtocolHeader();
+ header.setTo("example.com");
+ testling_.writeHeader(header);
+
+ assertEquals("<?xml version=\"1.0\"?><stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"example.com\" version=\"1.0\">", lowLayer_.writtenData);
+ }
+
+ @Test
+ public void testWriteElement() {
+ testling_.writeElement(new Presence());
+
+ assertEquals("<presence/>", lowLayer_.writtenData);
+ }
+
+ @Test
+ public void testWriteFooter() {
+ testling_.writeFooter();
+
+ assertEquals("</stream:stream>", lowLayer_.writtenData);
+ }
+} \ No newline at end of file