Author: markt
Date: Sat Mar 9 19:14:18 2013
New Revision: 1454758
URL: http://svn.apache.org/r1454758
Log:
Get encoding and decoding working end to end with an associated unit test
Added:
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java
(with props)
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoEndpointClient.java
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties Sat
Mar 9 19:14:18 2013
@@ -62,5 +62,6 @@ wsWebSocketContainer.invalidHeader=Unabl
wsWebSocketContainer.invalidStatus=The HTTP response from the server [{0}] did
not permit the HTTP upgrade to WebSocket
wsWebSocketContainer.invalidSubProtocol=The WebSocket server returned multiple
values for the Sec-WebSocket-Protocol header
wsWebSocketContainer.maxBuffer=This implementation limits the maximum size of
a buffer to Integer.MAX_VALUE
+wsWebSocketContainer.missingAnnotation=Cannot use POJO class [{0}] as it is
not annotated with @ClientEndpoint
wsWebSocketContainer.pathNoHost=No host was specified in URI
wsWebSocketContainer.pathWrongScheme=The scheme [{0}] is not supported
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Util.java?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Sat Mar 9 19:14:18
2013
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentLi
import javax.websocket.CloseReason.CloseCode;
import javax.websocket.CloseReason.CloseCodes;
+import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.MessageHandler;
@@ -33,7 +34,7 @@ import javax.websocket.MessageHandler;
* Utility class for internal use only within the
* {@link org.apache.tomcat.websocket} package.
*/
-class Util {
+public class Util {
private static final Queue<SecureRandom> randoms =
new ConcurrentLinkedQueue<>();
@@ -142,6 +143,11 @@ class Util {
}
+ public static Class<?> getDecoderType(Class<? extends Decoder> Decoder) {
+ return (Class<?>) Util.getGenericType(Decoder.class, Decoder);
+ }
+
+
static Class<?> getEncoderType(Class<? extends Encoder> encoder) {
return (Class<?>) Util.getGenericType(Encoder.class, encoder);
}
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Sat
Mar 9 19:14:18 2013
@@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -80,7 +81,15 @@ public class WsWebSocketContainer
public Session connectToServer(Object pojo, URI path)
throws DeploymentException {
- Endpoint ep = new PojoEndpointClient(pojo);
+ ClientEndpoint annotation =
+ pojo.getClass().getAnnotation(ClientEndpoint.class);
+ if (annotation == null) {
+ throw new DeploymentException(
+ sm.getString("wsWebSocketContainer.missingAnnotation",
+ pojo.getClass().getName()));
+ }
+
+ Endpoint ep = new PojoEndpointClient(pojo, annotation.decoders());
Class<? extends ClientEndpointConfig.Configurator> configuratorClazz =
pojo.getClass().getAnnotation(
@@ -97,9 +106,11 @@ public class WsWebSocketContainer
}
}
- ClientEndpointConfig config =
- ClientEndpointConfig.Builder.create().configurator(
- configurator).build();
+ ClientEndpointConfig config = ClientEndpointConfig.Builder.create().
+ configurator(configurator).
+ decoders(Arrays.asList(annotation.decoders())).
+ encoders(Arrays.asList(annotation.encoders())).
+ build();
return connectToServer(ep, config, path);
}
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoEndpointClient.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoEndpointClient.java?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoEndpointClient.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoEndpointClient.java
Sat Mar 9 19:14:18 2013
@@ -18,15 +18,19 @@ package org.apache.tomcat.websocket.pojo
import java.util.Collections;
+import javax.websocket.Decoder;
+import javax.websocket.DeploymentException;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
public class PojoEndpointClient extends PojoEndpointBase {
- public PojoEndpointClient(Object pojo) {
+ public PojoEndpointClient(Object pojo,
+ Class<? extends Decoder>[] decoders) throws DeploymentException {
setPojo(pojo);
- setMethodMapping(new PojoMethodMapping(pojo.getClass(), null));
+ setMethodMapping(
+ new PojoMethodMapping(pojo.getClass(), decoders, null));
setPathParameters(Collections.EMPTY_MAP);
}
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/pojo/PojoMethodMapping.java
Sat Mar 9 19:14:18 2013
@@ -19,11 +19,17 @@ package org.apache.tomcat.websocket.pojo
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.websocket.Decoder;
+import javax.websocket.Decoder.Binary;
+import javax.websocket.Decoder.BinaryStream;
+import javax.websocket.DeploymentException;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.OnClose;
@@ -34,6 +40,9 @@ import javax.websocket.PongMessage;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.websocket.Util;
+
/**
* For a POJO class annotated with
* {@link javax.websocket.server.ServerEndpoint}, an instance of this class
@@ -42,6 +51,9 @@ import javax.websocket.server.PathParam;
*/
public class PojoMethodMapping {
+ private static final StringManager sm =
+ StringManager.getManager(Constants.PACKAGE_NAME);
+
private final Method onOpen;
private final Method onClose;
private final Method onError;
@@ -52,8 +64,13 @@ public class PojoMethodMapping {
private final String wsPath;
- public PojoMethodMapping(Class<?> clazzPojo, String wsPath) {
+ public PojoMethodMapping(Class<?> clazzPojo,
+ Class<? extends Decoder>[] decoderClazzes, String wsPath)
+ throws DeploymentException {
+
this.wsPath = wsPath;
+
+ List<DecoderEntry> decoders = getDecoders(decoderClazzes);
Method open = null;
Method close = null;
Method error = null;
@@ -68,7 +85,7 @@ public class PojoMethodMapping {
method.getAnnotation(OnError.class) != null) {
error = method;
} else if (method.getAnnotation(OnMessage.class) != null) {
- onMessage.add(new MessageMethod(method));
+ onMessage.add(new MessageMethod(method, decoders));
}
}
this.onOpen = open;
@@ -130,6 +147,29 @@ public class PojoMethodMapping {
}
+ private static List<DecoderEntry> getDecoders(
+ Class<? extends Decoder>[] decoderClazzes)
+ throws DeploymentException{
+
+ List<DecoderEntry> result = new ArrayList<>();
+ for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
+ Decoder instance;
+ try {
+ instance = decoderClazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new DeploymentException(
+ sm.getString("wsRemoteEndpoint.invalidEncoder",
+ decoderClazz.getName()), e);
+ }
+ DecoderEntry entry = new DecoderEntry(
+ Util.getDecoderType(decoderClazz), instance);
+ result.add(entry);
+ }
+
+ return result;
+ }
+
+
private static PojoPathParam[] getPathParams(Method m, boolean isError) {
if (m == null) {
return new PojoPathParam[0];
@@ -232,7 +272,7 @@ public class PojoMethodMapping {
private int indexPayload = -1;
- public MessageMethod(Method m) {
+ public MessageMethod(Method m, List<DecoderEntry> decoderEntries) {
this.m = m;
Class<?>[] types = m.getParameterTypes();
@@ -291,6 +331,31 @@ public class PojoMethodMapping {
// TODO i18n
throw new IllegalArgumentException();
}
+ } else {
+ for (DecoderEntry decoderEntry : decoderEntries) {
+ if (decoderEntry.getClazz().isAssignableFrom(
+ types[i])) {
+ if (Binary.class.isAssignableFrom(
+ decoderEntry.getDecoder().getClass())
||
+ BinaryStream.class.isAssignableFrom(
+
decoderEntry.getDecoder().getClass())) {
+ if (indexByteBuffer == -1) {
+ indexByteBuffer = i;
+ } else {
+ // TODO i18n
+ throw new IllegalArgumentException();
+ }
+ break;
+ } else {
+ if (indexString == -1) {
+ indexString = i;
+ } else {
+ // TODO i18n
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+ }
}
}
// Additional checks required
@@ -384,4 +449,24 @@ public class PojoMethodMapping {
return mh;
}
}
+
+
+ private static class DecoderEntry {
+
+ private final Class<?> clazz;
+ private final Decoder decoder;
+
+ public DecoderEntry(Class<?> clazz, Decoder decoder) {
+ this.clazz = clazz;
+ this.decoder = decoder;
+ }
+
+ public Class<?> getClazz() {
+ return clazz;
+ }
+
+ public Decoder getDecoder() {
+ return decoder;
+ }
+ }
}
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
(original)
+++
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
Sat Mar 9 19:14:18 2013
@@ -13,12 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
sci.newInstance.fail=Failed to create an Endpoint instance of type [{0}]
+
+serverContainer.configuratorFail=Failed to create configurator of type [{0}]
for POJO of type [{1}]
serverContainer.endpointDeploy=Endpoint class [{0}] deploying to path [{1}] in
ServletContext [{2}]
serverContainer.missingAnnotation=Cannot deploy POJO class [{0}] as it is not
annotated with @ServerEndpoint
serverContainer.missingEndpoint=An Endpoint instance has been request for path
[{0}] but no matching Endpoint class was found
serverContainer.pojoDeploy=POJO class [{0}] deploying to path [{1}] in
ServletContext [{2}]
serverContainer.servletContextMismatch=Attempted to register a POJO annotated
for WebSocket at path [{0}] in the ServletContext with context path [{1}] when
the WebSocket ServerContainer is allocated to the ServletContext with context
path [{2}]
serverContainer.servletContextMissing=No ServletContext was specified
+
uriTemplate.noMatch=The input template [{0}] generated the pattern [{1}] which
did not match the supplied pathInfo [{2}]
+
wsProtocolHandler.closeFailed=Failed to close the WebSocket connection cleanly
+
wsRemoteEndpointServer.closeFailed=Failed to close the ServletOutputStream
connection cleanly
\ No newline at end of file
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1454758&r1=1454757&r2=1454758&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
Sat Mar 9 19:14:18 2013
@@ -16,6 +16,7 @@
*/
package org.apache.tomcat.websocket.server;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
@@ -27,6 +28,7 @@ import javax.websocket.DeploymentExcepti
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
+import javax.websocket.server.ServerEndpointConfig.Configurator;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -181,7 +183,8 @@ public class WsServerContainer extends W
}
pojoMap.put(mapPath, pojo);
- pojoMethodMap.put(pojo, new PojoMethodMapping(pojo, wsPath));
+ pojoMethodMap.put(pojo,
+ new PojoMethodMapping(pojo, annotation.decoders(), wsPath));
addWsServletMapping(servletPath);
}
@@ -205,14 +208,31 @@ public class WsServerContainer extends W
}
Class<?> pojo = pojoMap.get(servletPath);
if (pojo != null) {
+ ServerEndpoint annotation =
+ pojo.getAnnotation(ServerEndpoint.class);
PojoMethodMapping methodMapping = pojoMethodMap.get(pojo);
if (methodMapping != null) {
+ Configurator configurator;
+ try {
+ configurator = annotation.configurator().newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new IllegalStateException(sm.getString(
+ "serverContainer.configuratorFail",
+ annotation.configurator().getName(),
+ pojo.getClass().getName()), e);
+ }
sec = ServerEndpointConfig.Builder.create(
- pojo, methodMapping.getWsPath()).build();
+ pojo, methodMapping.getWsPath()).
+ decoders(Arrays.asList(annotation.decoders())).
+ encoders(Arrays.asList(annotation.encoders())).
+ configurator(configurator).
+ build();
sec.getUserProperties().put(
- PojoEndpointServer.POJO_PATH_PARAM_KEY,
pathParameters);
+ PojoEndpointServer.POJO_PATH_PARAM_KEY,
+ pathParameters);
sec.getUserProperties().put(
- PojoEndpointServer.POJO_METHOD_MAPPING_KEY,
methodMapping);
+ PojoEndpointServer.POJO_METHOD_MAPPING_KEY,
+ methodMapping);
return sec;
}
}
Added:
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java?rev=1454758&view=auto
==============================================================================
---
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java
(added)
+++
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java
Sat Mar 9 19:14:18 2013
@@ -0,0 +1,251 @@
+/*
+ * 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.tomcat.websocket.pojo;
+
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.servlet.ServletContextEvent;
+import javax.websocket.ClientEndpoint;
+import javax.websocket.ContainerProvider;
+import javax.websocket.DecodeException;
+import javax.websocket.Decoder;
+import javax.websocket.DeploymentException;
+import javax.websocket.EncodeException;
+import javax.websocket.Encoder;
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+import javax.websocket.server.ServerEndpoint;
+import javax.websocket.server.ServerEndpointConfig.Configurator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.websocket.server.WsListener;
+import org.apache.tomcat.websocket.server.WsServerContainer;
+
+public class TestEncodingDecoding extends TomcatBaseTest {
+
+ private static final String MESSAGE_ONE = "message-one";
+
+ @Test
+ public void test() throws Exception {
+ Tomcat tomcat = getTomcatInstance();
+ // Must have a real docBase - just use temp
+ Context ctx =
+ tomcat.addContext("", System.getProperty("java.io.tmpdir"));
+ ctx.addApplicationListener(ServerConfigListener.class.getName());
+
+ WebSocketContainer wsContainer =
+ ContainerProvider.getWebSocketContainer();
+
+ tomcat.start();
+
+ Client client = new Client();
+ URI uri = new URI("http://localhost:" + getPort() + "/");
+ Session session = wsContainer.connectToServer(client, uri);
+
+ MsgString msg1 = new MsgString();
+ msg1.setData(MESSAGE_ONE);
+ session.getBasicRemote().sendObject(msg1);
+
+ Server server = ServerConfigurator.getServerInstance();
+
+ // Should not take very long
+ int i = 0;
+ while (i < 20) {
+ if (server.received.size() > 0 && client.received.size() > 0) {
+ break;
+ }
+ Thread.sleep(100);
+ }
+
+ // Check messages were received
+ Assert.assertEquals(1, server.received.size());
+ Assert.assertEquals(1, client.received.size());
+
+ // Check correct messages were received
+ Assert.assertEquals(MESSAGE_ONE,
+ ((MsgString) server.received.peek()).getData());
+ Assert.assertEquals(MESSAGE_ONE,
+ ((MsgString) client.received.peek()).getData());
+ }
+
+ @ClientEndpoint(decoders={MsgStringDecoder.class, MsgByteDecoder.class},
+ encoders={MsgStringEncoder.class, MsgByteEncoder.class})
+ public static class Client {
+ private Queue<Object> received = new ConcurrentLinkedQueue<>();
+
+ @OnMessage
+ public void rx(MsgString in) {
+ received.add(in);
+ }
+
+ @OnMessage
+ public void rx(MsgByte in) {
+ received.add(in);
+ }
+ }
+
+
+ @ServerEndpoint(value="/",
+ decoders={MsgStringDecoder.class, MsgByteDecoder.class},
+ encoders={MsgStringEncoder.class, MsgByteEncoder.class},
+ configurator=ServerConfigurator.class)
+ public static class Server {
+ private Queue<Object> received = new ConcurrentLinkedQueue<>();
+
+ public Server() {
+ System.out.println("Server created");
+ }
+
+ @OnMessage
+ public MsgString rx(MsgString in) {
+ received.add(in);
+ // Echo the message back
+ return in;
+ }
+
+ @OnMessage
+ public MsgByte rx(MsgByte in) {
+ received.add(in);
+ // Echo the message back
+ return in;
+ }
+ }
+
+
+ public static class ServerConfigurator extends Configurator {
+
+ private static final Server server = new Server();
+
+ @Override
+ public <T> T getEndpointInstance(Class<T> clazz)
+ throws InstantiationException {
+ @SuppressWarnings("unchecked")
+ T result = (T) server;
+ return result;
+ }
+
+ public static Server getServerInstance() {
+ return server;
+ }
+ }
+
+ public static class ServerConfigListener extends WsListener {
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ super.contextInitialized(sce);
+ WsServerContainer sc = WsServerContainer.getServerContainer();
+ sc.setServletContext(sce.getServletContext());
+ try {
+ sc.addEndpoint(Server.class);
+ } catch (DeploymentException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ public static class MsgString {
+ private String data;
+
+ public String getData() { return data; }
+ public void setData(String data) { this.data = data; }
+ }
+
+
+ public static class MsgStringEncoder extends Encoder.Adapter
+ implements Encoder.Text<MsgString> {
+
+ @Override
+ public String encode(MsgString msg) throws EncodeException {
+ return "MsgString:" + msg.getData();
+ }
+ }
+
+
+ public static class MsgStringDecoder extends Decoder.Adapter
+ implements Decoder.Text<MsgString> {
+
+ @Override
+ public MsgString decode(String s) throws DecodeException {
+ MsgString result = new MsgString();
+ result.setData(s.substring(10));
+ return result;
+ }
+
+ @Override
+ public boolean willDecode(String s) {
+ return s.startsWith("MsgString:");
+ }
+ }
+
+
+ public static class MsgByte {
+ private byte[] data;
+
+ public byte[] getData() { return data; }
+ public void setData(byte[] data) { this.data = data; }
+ }
+
+
+ public static class MsgByteEncoder extends Encoder.Adapter
+ implements Encoder.Binary<MsgByte> {
+
+ @Override
+ public ByteBuffer encode(MsgByte msg) throws EncodeException {
+ byte[] data = msg.getData();
+ ByteBuffer reply = ByteBuffer.allocate(2 + data.length);
+ reply.put((byte) 0x12);
+ reply.put((byte) 0x34);
+ reply.put(data);
+ return reply;
+ }
+ }
+
+
+ public static class MsgByteDecoder extends Decoder.Adapter
+ implements Decoder.Binary<MsgByte> {
+
+ @Override
+ public MsgByte decode(ByteBuffer bb) throws DecodeException {
+ MsgByte result = new MsgByte();
+ bb.position(bb.position() + 2);
+ byte[] data = new byte[bb.limit() - bb.position()];
+ bb.get(data);
+ result.setData(data);
+ return result;
+ }
+
+ @Override
+ public boolean willDecode(ByteBuffer bb) {
+ bb.mark();
+ if (bb.get() == 0x12 && bb.get() == 0x34) {
+ return true;
+ }
+ bb.reset();
+ return false;
+ }
+ }
+}
Propchange:
tomcat/trunk/test/org/apache/tomcat/websocket/pojo/TestEncodingDecoding.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]