diff --git a/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoder.java b/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoder.java new file mode 100644 index 0000000000..9bd272d6cd --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoder.java @@ -0,0 +1,84 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat 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.jboss.netty.handler.codec.bytes; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; + +/** + * Decodes a received {@link ChannelBuffer} into an array of bytes. + * A typical setup for TCP/IP would be: + *
+ * {@link ChannelPipeline} pipeline = ...;
+ *
+ * // Decoders
+ * pipeline.addLast("frameDecoder",
+ *                  new {@link LengthFieldBasedFrameDecoder}(1048576, 0, 4, 0, 4));
+ * pipeline.addLast("bytesDecoder",
+ *                  new {@link ByteArrayDecoder}());
+ *
+ * // Encoder
+ * pipeline.addLast("frameEncoder", new {@link LengthFieldPrepender}(4));
+ * pipeline.addLast("bytesEncoder", new {@link ByteArrayEncoder}());
+ * 
+ * and then you can use an array of bytes instead of a {@link ChannelBuffer} + * as a message: + *
+ * void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
+ *     byte[] bytes = (byte[]) e.getMessage();
+ *     ...
+ * }
+ * 
+ * + * @author The Netty Project + * @author Tomasz Blachowicz (tblachowicz@gmail.com) + * + * @version $Rev$, $Date$ + */ +public class ByteArrayDecoder extends OneToOneDecoder { + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) { + return msg; + } + ChannelBuffer buf = (ChannelBuffer )msg; + byte[] array; + if (buf.hasArray()) { + if (buf.arrayOffset() == 0 && buf.readableBytes() == buf.capacity()) { + // we have no offset and the length is the same as the capacity. Its safe to reuse the array without copy it first + array = buf.array(); + } else { + // copy the ChannelBuffer to a byte array + array = new byte[buf.readableBytes()]; + buf.getBytes(0, array); + } + } else { + // copy the ChannelBuffer to a byte array + + array = new byte[buf.readableBytes()]; + buf.getBytes(0, array); + } + return array; + } + +} diff --git a/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoder.java b/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoder.java new file mode 100644 index 0000000000..1267f9b160 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoder.java @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat 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.jboss.netty.handler.codec.bytes; + +import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +/** + * Encodes the requested array of bytes into a {@link ChannelBuffer}. + * A typical setup for TCP/IP would be: + *
+ * {@link ChannelPipeline} pipeline = ...;
+ *
+ * // Decoders
+ * pipeline.addLast("frameDecoder",
+ *                  new {@link LengthFieldBasedFrameDecoder}(1048576, 0, 4, 0, 4));
+ * pipeline.addLast("bytesDecoder",
+ *                  new {@link ByteArrayDecoder}());
+ *
+ * // Encoder
+ * pipeline.addLast("frameEncoder", new {@link LengthFieldPrepender}(4));
+ * pipeline.addLast("bytesEncoder", new {@link ByteArrayEncoder}());
+ * 
+ * and then you can use an array of bytes instead of a {@link ChannelBuffer} + * as a message: + *
+ * void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
+ *     byte[] bytes = (byte[]) e.getMessage();
+ *     ...
+ * }
+ * 
+ * + * @author The Netty Project + * @author Tomasz Blachowicz (tblachowicz@gmail.com) + * + * @version $Rev$, $Date$ + */ +public class ByteArrayEncoder extends OneToOneEncoder { + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof byte[])) { + return msg; + } + return wrappedBuffer((byte[]) msg); + } + +} diff --git a/src/main/java/org/jboss/netty/handler/codec/bytes/package-info.java b/src/main/java/org/jboss/netty/handler/codec/bytes/package-info.java new file mode 100644 index 0000000000..b09bfe8bfd --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/bytes/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat 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. + */ + +/** + * Encoder and decoder which transform an array of bytes into a + * {@link org.jboss.netty.buffer.ChannelBuffer} and vice versa. + * + * @apiviz.exclude \.oneone\. + */ +package org.jboss.netty.handler.codec.bytes; diff --git a/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoderTest.java b/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoderTest.java new file mode 100644 index 0000000000..380ed21108 --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayDecoderTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat 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.jboss.netty.handler.codec.bytes; + +import static org.hamcrest.core.Is.is; +import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer; +import static org.junit.Assert.assertThat; + +import java.util.Random; + +import org.jboss.netty.handler.codec.embedder.DecoderEmbedder; +import org.junit.Before; +import org.junit.Test; + +/** + * @author The Netty Project + * @author Tomasz Blachowicz (tblachowicz@gmail.com) + * @version $Rev$, $Date$ + */ +public class ByteArrayDecoderTest { + + private DecoderEmbedder embedder; + + @Before + public void setUp() { + embedder = new DecoderEmbedder(new ByteArrayDecoder()); + } + + @Test + public void testDecode() { + byte[] b = new byte[2048]; + new Random().nextBytes(b); + embedder.offer(wrappedBuffer(b)); + assertThat(embedder.poll(), is(b)); + } + + @Test + public void testDecodeEmpty() { + byte[] b = new byte[0]; + embedder.offer(wrappedBuffer(b)); + assertThat(embedder.poll(), is(b)); + } + + @Test + public void testDecodeOtherType() { + String str = "Meep!"; + embedder.offer(str); + assertThat(embedder.poll(), is((Object) str)); + } + +} diff --git a/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoderTest.java b/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoderTest.java new file mode 100644 index 0000000000..44ae01f524 --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/bytes/ByteArrayEncoderTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2009 Red Hat, Inc. + * + * Red Hat 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.jboss.netty.handler.codec.bytes; + +import static org.hamcrest.core.Is.is; +import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer; +import static org.junit.Assert.assertThat; + +import java.util.Random; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.handler.codec.embedder.EncoderEmbedder; +import org.junit.Before; +import org.junit.Test; + +/** + * @author The Netty Project + * @author Tomasz Blachowicz (tblachowicz@gmail.com) + * @version $Rev$, $Date$ + */ +public class ByteArrayEncoderTest { + + private EncoderEmbedder embedder; + + @Before + public void setUp() { + embedder = new EncoderEmbedder(new ByteArrayEncoder()); + } + + @Test + public void testDecode() { + byte[] b = new byte[2048]; + new Random().nextBytes(b); + embedder.offer(b); + assertThat(embedder.poll(), is(wrappedBuffer(b))); + } + + @Test + public void testDecodeEmpty() { + byte[] b = new byte[0]; + embedder.offer(b); + assertThat(embedder.poll(), is(wrappedBuffer(b))); + } + + @Test + public void testDecodeOtherType() { + String str = "Meep!"; + embedder.offer(str); + assertThat(embedder.poll(), is((Object) str)); + } + +}