All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.netty.handler.codec.frame.LengthFieldPrepender Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project 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.frame;

import static org.jboss.netty.buffer.ChannelBuffers.*;

import java.nio.ByteOrder;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferFactory;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;

/**
 * An encoder that prepends the length of the message.  The length value is
 * prepended as a binary form.  It is encoded in either big endian or little
 * endian depending on the default {@link ByteOrder} of the current
 * {@link ChannelBufferFactory}.
 * 

* For example, {@link LengthFieldPrepender}(2) will encode the * following 12-bytes string: *

 * +----------------+
 * | "HELLO, WORLD" |
 * +----------------+
 * 
* into the following: *
 * +--------+----------------+
 * + 0x000C | "HELLO, WORLD" |
 * +--------+----------------+
 * 
* If you turned on the {@code lengthIncludesLengthFieldLength} flag in the * constructor, the encoded data would look like the following * (12 (original data) + 2 (prepended data) = 14 (0xE)): *
 * +--------+----------------+
 * + 0x000E | "HELLO, WORLD" |
 * +--------+----------------+
 * 
*/ @Sharable public class LengthFieldPrepender extends OneToOneEncoder { private final int lengthFieldLength; private final boolean lengthIncludesLengthFieldLength; /** * Creates a new instance. * * @param lengthFieldLength the length of the prepended length field. * Only 1, 2, 3, 4, and 8 are allowed. * * @throws IllegalArgumentException * if {@code lengthFieldLength} is not 1, 2, 3, 4, or 8 */ public LengthFieldPrepender(int lengthFieldLength) { this(lengthFieldLength, false); } /** * Creates a new instance. * * @param lengthFieldLength the length of the prepended length field. * Only 1, 2, 3, 4, and 8 are allowed. * @param lengthIncludesLengthFieldLength * if {@code true}, the length of the prepended * length field is added to the value of the * prepended length field. * * @throws IllegalArgumentException * if {@code lengthFieldLength} is not 1, 2, 3, 4, or 8 */ public LengthFieldPrepender( int lengthFieldLength, boolean lengthIncludesLengthFieldLength) { if (lengthFieldLength != 1 && lengthFieldLength != 2 && lengthFieldLength != 3 && lengthFieldLength != 4 && lengthFieldLength != 8) { throw new IllegalArgumentException( "lengthFieldLength must be either 1, 2, 3, 4, or 8: " + lengthFieldLength); } this.lengthFieldLength = lengthFieldLength; this.lengthIncludesLengthFieldLength = lengthIncludesLengthFieldLength; } @Override protected Object encode( ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { if (!(msg instanceof ChannelBuffer)) { return msg; } ChannelBuffer body = (ChannelBuffer) msg; ChannelBuffer header = channel.getConfig().getBufferFactory().getBuffer(body.order(), lengthFieldLength); int length = lengthIncludesLengthFieldLength? body.readableBytes() + lengthFieldLength : body.readableBytes(); switch (lengthFieldLength) { case 1: if (length >= 256) { throw new IllegalArgumentException( "length does not fit into a byte: " + length); } header.writeByte((byte) length); break; case 2: if (length >= 65536) { throw new IllegalArgumentException( "length does not fit into a short integer: " + length); } header.writeShort((short) length); break; case 3: if (length >= 16777216) { throw new IllegalArgumentException( "length does not fit into a medium integer: " + length); } header.writeMedium(length); break; case 4: header.writeInt(length); break; case 8: header.writeLong(length); break; default: throw new Error("should not reach here"); } return wrappedBuffer(header, body); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy