View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.filter.codec.prefixedstring;
    21
    22  import org.apache.mina.core.buffer.IoBuffer;
    23  import org.apache.mina.core.session.IoSession;
    24  import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
    25  import org.apache.mina.filter.codec.ProtocolEncoderOutput;
    26  import org.apache.mina.filter.codec.ProtocolEncoder;
    27
    28  import java.nio.charset.Charset;
    29
    30  /**
    31   * A {@link ProtocolEncoder} which encodes a string
    32   * using a fixed-length length prefix.
    33   *
    34   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    35   */
    36  public class PrefixedStringEncoder extends ProtocolEncoderAdapter {
    37
    38      public final static int DEFAULT_PREFIX_LENGTH = 4;
    39
    40      public final static int DEFAULT_MAX_DATA_LENGTH = 2048;
    41
    42      private final Charset charset;
    43
    44      private int prefixLength = DEFAULT_PREFIX_LENGTH;
    45
    46      private int maxDataLength = DEFAULT_MAX_DATA_LENGTH;
    47
    48      public PrefixedStringEncoder(Charset charset, int prefixLength, int maxDataLength) {
    49          this.charset = charset;
    50          this.prefixLength = prefixLength;
    51          this.maxDataLength = maxDataLength;
    52      }
    53
    54      public PrefixedStringEncoder(Charset charset, int prefixLength) {
    55          this(charset, prefixLength, DEFAULT_MAX_DATA_LENGTH);
    56      }
    57
    58      public PrefixedStringEncoder(Charset charset) {
    59          this(charset, DEFAULT_PREFIX_LENGTH);
    60      }
    61
    62      public PrefixedStringEncoder() {
    63          this(Charset.defaultCharset());
    64      }
    65
    66      /**
    67       * Sets the number of bytes used by the length prefix
    68       *
    69       * @param prefixLength the length of the length prefix (1, 2, or 4)
    70       */
    71      public void setPrefixLength(int prefixLength) {
    72          if (prefixLength != 1 && prefixLength != 2 && prefixLength != 4) {
    73              throw new IllegalArgumentException("prefixLength: " + prefixLength);
    74          }
    75          this.prefixLength = prefixLength;
    76      }
    77
    78      /**
    79       * Gets the length of the length prefix (1, 2, or 4)
    80       *
    81       * @return length of the length prefix
    82       */
    83      public int getPrefixLength() {
    84          return prefixLength;
    85      }
    86
    87      /**
    88       * Sets the maximum number of bytes allowed for encoding a single String
    89       * (including the prefix)
    90       * <p>
    91       * The encoder will throw a {@link IllegalArgumentException} when more bytes
    92       * are needed to encode a String value.
    93       * The default value is {@link PrefixedStringEncoder#DEFAULT_MAX_DATA_LENGTH}.
    94       * </p>
    95       *
    96       * @param maxDataLength maximum number of bytes allowed for encoding a single String
    97       */
    98      public void setMaxDataLength(int maxDataLength) {
    99          this.maxDataLength = maxDataLength;
    100     }
    101
    102     /**
    103      * Gets the maximum number of bytes allowed for encoding a single String     *
    104      *
    105      * @return maximum number of bytes allowed for encoding a single String (prefix included)
    106      */
    107     public int getMaxDataLength() {
    108         return maxDataLength;
    109     }
    110
    111     public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
    112         String value = (String) message;
    113         IoBuffer buffer = IoBuffer.allocate(value.length()).setAutoExpand(true);
    114         buffer.putPrefixedString(value, prefixLength, charset.newEncoder());
    115         if (buffer.position() > maxDataLength) {
    116             throw new IllegalArgumentException("Data length: " + buffer.position());
    117         }
    118         buffer.flip();
    119         out.write(buffer);
    120     }
    121 }