All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taobao.tair.comm.DefaultTranscoder Maven / Gradle / Ivy

/**
 * (C) 2007-2010 Taobao Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */
package com.taobao.tair.comm;

import java.util.Date;

import com.taobao.tair.etc.TairConstant;
import com.taobao.tair.etc.TairUtil;
import com.taobao.tair.etc.TranscoderUtil;
import com.taobao.tair.etc.IncData;

/**
 * the default transcoder impl
 */
public class DefaultTranscoder implements Transcoder {
    private int    compressionThreshold = TairConstant.TAIR_DEFAULT_COMPRESSION_THRESHOLD;
    private String charset              = TairConstant.DEFAULT_CHARSET;
    
    private boolean withHeader			= true;

    public DefaultTranscoder() {
    }


    public DefaultTranscoder(int compressionThreshold, String charset) {
        if (compressionThreshold > 0) {
            this.compressionThreshold = compressionThreshold;
        }

        if (charset != null) {
            this.charset = charset;
        }
    }

    public byte[] encode(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("key,value can not be null");
        }

        byte[] b    = null;
        short  flag = 0;

        if (object instanceof String) {
            b    = TranscoderUtil.encodeString((String) object, charset);
            flag = TairConstant.TAIR_STYPE_STRING;
        } else if (object instanceof Long) {
            b    = TranscoderUtil.encodeLong((Long) object);
            flag = TairConstant.TAIR_STYPE_LONG;
        } else if (object instanceof Integer) {
            b    = TranscoderUtil.encodeInt((Integer) object);
            flag = TairConstant.TAIR_STYPE_INT;
        } else if (object instanceof Boolean) {
            b    = TranscoderUtil.encodeBoolean((Boolean) object);
            flag = TairConstant.TAIR_STYPE_BOOL;
        } else if (object instanceof Date) {
            b    = TranscoderUtil.encodeLong(((Date) object).getTime());
            flag = TairConstant.TAIR_STYPE_DATE;
        } else if (object instanceof Byte) {
            b    = TranscoderUtil.encodeByte((Byte) object);
            flag = TairConstant.TAIR_STYPE_BYTE;
        } else if (object instanceof Float) {
            b    = TranscoderUtil.encodeInt(Float.floatToRawIntBits((Float) object));
            flag = TairConstant.TAIR_STYPE_FLOAT;
        } else if (object instanceof Double) {
            b    = TranscoderUtil.encodeLong(Double.doubleToRawLongBits((Double) object));
            flag = TairConstant.TAIR_STYPE_DOUBLE;
        } else if (object instanceof byte[]) {
            b    = (byte[]) object;
            flag = TairConstant.TAIR_STYPE_BYTEARRAY;
        } else if (object instanceof IncData) {
            b    = IncData.encode((IncData)object);
            flag = TairConstant.TAIR_STYPE_INCDATA;
        } else {
            b    = TranscoderUtil.serialize(object);
            flag = TairConstant.TAIR_STYPE_SERIALIZE;
        }

        flag <<= 1;

        if (b.length > compressionThreshold) {
            b = TranscoderUtil.compress(b);
            flag += 1;
        }

        TairUtil.checkMalloc(b.length + 2);

        if (false == withHeader) {
        	return b;
        }
        byte[] result = new byte[b.length + 2];
        byte[] fg     = new byte[2];

        fg[1]         = (byte) (flag & 0xFF);
        fg[0]         = (byte) ((flag >> 8) & 0xFF);

        for (int i = 0; i < 2; i++) {
            result[i] = fg[i];
        }

        for (int i = 0; i < b.length; i++) {
            result[i + 2] = b[i];
        }

        return result;
    }

    public Object decode(byte[] data) {
        return decode(data, 0, data.length);
    }

    public Object decode(byte[] data, int offset, int size) {
    	///////////////////////////////////////////////////////////
    	/////////////////////判断并获取是否是一个整形数值///////////
    	int index = 0;
    	for(index = 0; index < size && (index + offset < data.length); index++) {
    		if(data[index+offset] == '+' || data[index+offset] == '-') {
    			continue;
    		}
    		if(data[index+offset] < '0' || data[index+offset] > '9') {
    			break;
    		}
    	}
    	if(index == size) {
        	String tmpstr = new String(data, offset, size);
        	try {
        		long tmp = Long.valueOf(tmpstr);
        		return tmp;
        	} catch(NumberFormatException e) {
        	
        	}
    	}
    	///////////////////////////////////////////////////////////
    	if (false == withHeader) {
    		TairUtil.checkMalloc(size);
    		return TranscoderUtil.decodeString(data, charset);
    	}
        TairUtil.checkMalloc(size - 2);

        byte[] vb = new byte[size - 2];

        System.arraycopy(data, offset + 2, vb, 0, size - 2);

        Object obj = null;

        int    flags = 0;

        for (int i = 0; i < 2; i++) {
            byte b = data[offset + i];

            flags = (flags << 8) | ((b < 0) ? (256 + b)
                                            : b);
        }

        if ((flags & 1) == 1) {
            vb = TranscoderUtil.decompress(vb);
        }

        int type = (flags >> 1) & 0xF;

        switch (type) {
            case TairConstant.TAIR_STYPE_INT:
                obj = TranscoderUtil.decodeInt(vb);
                break;

            case TairConstant.TAIR_STYPE_STRING:
                obj = TranscoderUtil.decodeString(vb, charset);
                break;

            case TairConstant.TAIR_STYPE_BOOL:
                obj = TranscoderUtil.decodeBoolean(vb);
                break;

            case TairConstant.TAIR_STYPE_LONG:
                obj = TranscoderUtil.decodeLong(vb);
                break;

            case TairConstant.TAIR_STYPE_DATE:

                Long time = TranscoderUtil.decodeLong(vb);

                obj = new Date(time);
                break;

            case TairConstant.TAIR_STYPE_BYTE:
                obj = TranscoderUtil.decodeByte(vb);
                break;

            case TairConstant.TAIR_STYPE_FLOAT:

                Integer f = TranscoderUtil.decodeInt(vb);

                obj = new Float(Float.intBitsToFloat(f));
                break;

            case TairConstant.TAIR_STYPE_DOUBLE:

                Long l = TranscoderUtil.decodeLong(vb);

                obj = new Double(Double.longBitsToDouble(l));
                break;

            case TairConstant.TAIR_STYPE_BYTEARRAY:
                obj = vb;
                break;

            case TairConstant.TAIR_STYPE_SERIALIZE:
                obj = TranscoderUtil.deserialize(vb);
                break;

            case TairConstant.TAIR_STYPE_INCDATA:
                obj = IncData.decode(vb);
                break;

            default:
                throw new RuntimeException("unknow serialize flag: " + type);
        }

        return obj;
    }
 
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy