View Javadoc

1   package org.apache.mina.filter.codec.prefixedstring;
2   
3   import org.apache.mina.common.IoBuffer;
4   import org.apache.mina.common.IoSession;
5   import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
6   import org.apache.mina.filter.codec.ProtocolEncoderOutput;
7   import org.apache.mina.filter.codec.ProtocolEncoder;
8   
9   import java.nio.charset.Charset;
10  
11  /**
12   * A {@link ProtocolEncoder} which encodes a string
13   * using a fixed-length length prefix.
14   *
15   * @author The Apache MINA Project (dev@mina.apache.org)
16   * @version $Rev: 591182 $, $Date: 2007-11-02 01:59:27 +0100 (vr, 02 nov 2007) $,
17   */
18  public class PrefixedStringEncoder extends ProtocolEncoderAdapter {
19  
20      public final static int DEFAULT_PREFIX_LENGTH = 4;
21  
22      public final static int DEFAULT_MAX_DATA_LENGTH = 2048;
23  
24      private final Charset charset;
25  
26      private int prefixLength = DEFAULT_PREFIX_LENGTH;
27  
28      private int maxDataLength = DEFAULT_MAX_DATA_LENGTH;
29  
30      public PrefixedStringEncoder(Charset charset, int prefixLength, int maxDataLength) {
31          this.charset = charset;
32          this.prefixLength = prefixLength;
33          this.maxDataLength = maxDataLength;
34      }
35  
36      public PrefixedStringEncoder(Charset charset, int prefixLength) {
37          this(charset, prefixLength, DEFAULT_MAX_DATA_LENGTH);
38      }
39  
40      public PrefixedStringEncoder(Charset charset) {
41          this(charset, DEFAULT_PREFIX_LENGTH);
42      }
43  
44      public PrefixedStringEncoder() {
45          this(Charset.defaultCharset());
46      }
47  
48      /**
49       * Sets the number of bytes used by the length prefix
50       *
51       * @param prefixLength the length of the length prefix (1, 2, or 4)
52       */
53      public void setPrefixLength(int prefixLength) {
54          if (prefixLength != 1 && prefixLength != 2 && prefixLength != 4) {
55              throw new IllegalArgumentException("prefixLength: " + prefixLength);
56          }
57          this.prefixLength = prefixLength;
58      }
59  
60      /**
61       * Gets the length of the length prefix (1, 2, or 4)
62       *
63       * @return length of the length prefix
64       */
65      public int getPrefixLength() {
66          return prefixLength;
67      }
68  
69      /**
70       * Sets the maximum number of bytes allowed for encoding a single String
71       * (including the prefix)
72       * <p>
73       * The encoder will throw a {@link IllegalArgumentException} when more bytes
74       * are needed to encode a String value.
75       * The default value is {@link PrefixedStringEncoder#DEFAULT_MAX_DATA_LENGTH}.
76       * </p>
77       *
78       * @param maxDataLength maximum number of bytes allowed for encoding a single String
79       */
80      public void setMaxDataLength(int maxDataLength) {
81          this.maxDataLength = maxDataLength;
82      }
83  
84      /**
85       * Gets the maximum number of bytes allowed for encoding a single String     *
86       *
87       * @return maximum number of bytes allowed for encoding a single String (prefix included)
88       */
89      public int getMaxDataLength() {
90          return maxDataLength;
91      }
92  
93  
94      public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
95          String value = (String) message;
96          IoBuffer buffer = IoBuffer.allocate(value.length()).setAutoExpand(true);
97          buffer.putPrefixedString(value, prefixLength, charset.newEncoder());
98          if (buffer.position() > maxDataLength) {
99              throw new IllegalArgumentException("Data length: " + buffer.position());
100         }
101         buffer.flip();
102         out.write(buffer);
103     }
104 }