001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.filter.codec.prefixedstring; 021 022import org.apache.mina.core.buffer.IoBuffer; 023import org.apache.mina.core.session.IoSession; 024import org.apache.mina.filter.codec.ProtocolEncoderAdapter; 025import org.apache.mina.filter.codec.ProtocolEncoderOutput; 026import org.apache.mina.filter.codec.ProtocolEncoder; 027 028import java.nio.charset.Charset; 029 030/** 031 * A {@link ProtocolEncoder} which encodes a string 032 * using a fixed-length length prefix. 033 * 034 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 035 */ 036public class PrefixedStringEncoder extends ProtocolEncoderAdapter { 037 038 public final static int DEFAULT_PREFIX_LENGTH = 4; 039 040 public final static int DEFAULT_MAX_DATA_LENGTH = 2048; 041 042 private final Charset charset; 043 044 private int prefixLength = DEFAULT_PREFIX_LENGTH; 045 046 private int maxDataLength = DEFAULT_MAX_DATA_LENGTH; 047 048 public PrefixedStringEncoder(Charset charset, int prefixLength, int maxDataLength) { 049 this.charset = charset; 050 this.prefixLength = prefixLength; 051 this.maxDataLength = maxDataLength; 052 } 053 054 public PrefixedStringEncoder(Charset charset, int prefixLength) { 055 this(charset, prefixLength, DEFAULT_MAX_DATA_LENGTH); 056 } 057 058 public PrefixedStringEncoder(Charset charset) { 059 this(charset, DEFAULT_PREFIX_LENGTH); 060 } 061 062 public PrefixedStringEncoder() { 063 this(Charset.defaultCharset()); 064 } 065 066 /** 067 * Sets the number of bytes used by the length prefix 068 * 069 * @param prefixLength the length of the length prefix (1, 2, or 4) 070 */ 071 public void setPrefixLength(int prefixLength) { 072 if (prefixLength != 1 && prefixLength != 2 && prefixLength != 4) { 073 throw new IllegalArgumentException("prefixLength: " + prefixLength); 074 } 075 this.prefixLength = prefixLength; 076 } 077 078 /** 079 * Gets the length of the length prefix (1, 2, or 4) 080 * 081 * @return length of the length prefix 082 */ 083 public int getPrefixLength() { 084 return prefixLength; 085 } 086 087 /** 088 * Sets the maximum number of bytes allowed for encoding a single String 089 * (including the prefix) 090 * <p> 091 * The encoder will throw a {@link IllegalArgumentException} when more bytes 092 * are needed to encode a String value. 093 * The default value is {@link PrefixedStringEncoder#DEFAULT_MAX_DATA_LENGTH}. 094 * </p> 095 * 096 * @param maxDataLength maximum number of bytes allowed for encoding a single String 097 */ 098 public void setMaxDataLength(int maxDataLength) { 099 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}