/**
*Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)]
*Licensed 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
*/
/**
*Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)]
*Licensed 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 net.rubyeye.xmemcached.transcoders;
import net.rubyeye.xmemcached.exception.MemcachedDecodeException;
/**
* Transcoder for TokyoTyrant.Add 4-bytes flag before value.
*
* @author boyan
*
*/
public class TokyoTyrantTranscoder implements Transcoder<Object> {
private final SerializingTranscoder serializingTranscoder;
public TokyoTyrantTranscoder(int maxSize) {
serializingTranscoder = new SerializingTranscoder(maxSize);
serializingTranscoder.setPackZeros(false);
}
public TokyoTyrantTranscoder() {
serializingTranscoder = new SerializingTranscoder();
serializingTranscoder.setPackZeros(false);
}
public final Object decode(CachedData d) {
byte[] compositeData = d.getData();
if (compositeData.length <= 4)
throw new MemcachedDecodeException(
"There are no four bytes before value for TokyoTyrantTranscoder");
byte[] flagBytes = new byte[4];
byte[] realData = new byte[compositeData.length - 4];
System.arraycopy(compositeData, 0, flagBytes, 0, 4);
System.arraycopy(compositeData, 4, realData, 0,
compositeData.length - 4);
int flag = serializingTranscoder.getTranscoderUtils().decodeInt(
flagBytes);
d.setFlag(flag);
if ((flag & SerializingTranscoder.COMPRESSED) != 0) {
realData = serializingTranscoder.decompress(realData);
}
flag = flag & SerializingTranscoder.SPECIAL_MASK;
return serializingTranscoder.decode0(d, realData, flag);
}
public final CachedData encode(Object o) {
CachedData result = serializingTranscoder.encode(o);
byte[] realData = result.getData();
int flag = result.getFlag();
byte[] flagBytes = serializingTranscoder.getTranscoderUtils()
.encodeInt(flag);
byte[] compisiteData = new byte[4 + realData.length];
System.arraycopy(flagBytes, 0, compisiteData, 0, 4);
System.arraycopy(realData, 0, compisiteData, 4, realData.length);
result.setData(compisiteData);
return result;
}
public final int getMaxSize() {
return serializingTranscoder.getMaxSize();
}
public boolean isPackZeros() {
return serializingTranscoder.isPackZeros();
}
public boolean isPrimitiveAsString() {
return serializingTranscoder.isPrimitiveAsString();
}
public void setCharset(String to) {
serializingTranscoder.setCharset(to);
}
public void setCompressionThreshold(int to) {
serializingTranscoder.setCompressionThreshold(to);
}
public void setPackZeros(boolean packZeros) {
throw new UnsupportedOperationException(
"TokyoTyrantTranscoder doesn't support pack zeros");
}
public void setPrimitiveAsString(boolean primitiveAsString) {
throw new UnsupportedOperationException(
"TokyoTyrantTranscoder doesn't support save primitive type as String");
}
}