View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.handler.codec.marshalling;
    17
    18  import org.jboss.marshalling.Marshaller;
    19  import org.jboss.netty.buffer.ChannelBuffer;
    20  import org.jboss.netty.channel.Channel;
    21  import org.jboss.netty.channel.ChannelHandler.Sharable;
    22  import org.jboss.netty.channel.ChannelHandlerContext;
    23  import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
    24
    25  /**
    26   * {@link OneToOneEncoder} implementation which uses JBoss Marshalling to marshal
    27   * an Object. Be aware that this {@link OneToOneEncoder} is not compatible with
    28   * an other client that just use JBoss Marshalling as it includes the size of every
    29   * {@link Object} that gets serialized in front of the {@link Object} itself.
    30   *
    31   * Use this with {@link MarshallingDecoder}
    32   *
    33   * See <a href="http://www.jboss.org/jbossmarshalling">JBoss Marshalling website</a>
    34   * for more informations
    35   *
    36   */
    37  @Sharable
    38  public class MarshallingEncoder extends OneToOneEncoder {
    39      private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
    40      private final MarshallerProvider provider;
    41
    42      private final int estimatedLength;
    43
    44      /**
    45       * Creates a new encoder with the estimated length of 512 bytes.
    46       *
    47       * @param provider the {@link MarshallerProvider} to use
    48       */
    49      public MarshallingEncoder(MarshallerProvider provider) {
    50          this(provider, 512);
    51      }
    52
    53      /**
    54       * Creates a new encoder.
    55       *
    56       * @param provider
    57       *        the {@link MarshallerProvider} to use
    58       * @param estimatedLength
    59       *        the estimated byte length of the serialized form of an object.
    60       *        If the length of the serialized form exceeds this value, the
    61       *        internal buffer will be expanded automatically at the cost of
    62       *        memory bandwidth.  If this value is too big, it will also waste
    63       *        memory bandwidth.  To avoid unnecessary memory copy or allocation
    64       *        cost, please specify the properly estimated value.
    65       */
    66      public MarshallingEncoder(MarshallerProvider provider, int estimatedLength) {
    67          if (estimatedLength < 0) {
    68              throw new IllegalArgumentException(
    69                      "estimatedLength: " + estimatedLength);
    70          }
    71          this.estimatedLength = estimatedLength;
    72          this.provider = provider;
    73      }
    74
    75      @Override
    76      protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
    77          Marshaller marshaller = provider.getMarshaller(ctx);
    78          ChannelBufferByteOutput output = new ChannelBufferByteOutput(
    79                  ctx.getChannel().getConfig().getBufferFactory(), estimatedLength);
    80          output.getBuffer().writeBytes(LENGTH_PLACEHOLDER);
    81          marshaller.start(output);
    82          marshaller.writeObject(msg);
    83          marshaller.finish();
    84          marshaller.close();
    85
    86
    87          ChannelBuffer encoded = output.getBuffer();
    88          encoded.setInt(0, encoded.writerIndex() - 4);
    89
    90          return encoded;
    91      }
    92
    93  }