/*
* Copyright [2013-2015] PayPal Software Foundation
*
* 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 ml.shifu.guagua.io;
import java.io.StreamCorruptedException;
import java.nio.charset.Charset;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
/**
* A decoder to decode bytes array to {@link Bytable} object.
*/
public class NettyBytableDecoder extends LengthFieldBasedFrameDecoder {
private BytableSerializer<Bytable> serializer;
/**
* Default constructor with max object size 256M.
*/
public NettyBytableDecoder() {
this(256 * 1024 * 1024);
}
/**
* Creates a new decoder with the specified maximum object size.
*
* @param maxObjectSize
* the maximum byte length of the serialized object. if the length of the received object is greater than
* this value, {@link StreamCorruptedException} will be raised.
*/
public NettyBytableDecoder(int maxObjectSize) {
super(maxObjectSize, 0, 4, 0, 4);
this.serializer = new BytableSerializer<Bytable>();
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
ChannelBuffer frame = (ChannelBuffer) super.decode(ctx, channel, buffer);
if(frame == null) {
return null;
}
int classNameSize = frame.readInt();
byte[] classNameBytes = new byte[classNameSize];
frame.readBytes(classNameBytes);
String className = new String(classNameBytes, Charset.forName("UTF-8"));
int readableBytes = frame.readableBytes();
byte[] objectBytes = new byte[readableBytes];
frame.readBytes(objectBytes);
Bytable bytesToObject = this.serializer.bytesToObject(objectBytes, className);
return bytesToObject;
}
@Override
protected ChannelBuffer extractFrame(ChannelBuffer buffer, int index, int length) {
return buffer.slice(index, length);
}
}