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

com.opdar.gulosity.serializable.DecimalSerializable Maven / Gradle / Ivy

package com.opdar.gulosity.serializable;

import com.opdar.gulosity.utils.BufferUtils;

import java.math.BigDecimal;
import java.nio.ByteBuffer;

/**
 * Created by Shey on 2016/8/27.
 */
public class DecimalSerializable extends JavaSerializable {
    //长度与byte字节数长度的换算
    private static final int dig2bytes[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
    //一个Int所表示的长度
    private static final int DIG_PER_DEC1 = 9;

    public DecimalSerializable(int type) {
        super(type);
    }

    @Override
    public BigDecimal getValue(int meta, ByteBuffer buffer) {
        int precision = meta >> 8;
        int scale = meta & 0xff;
        return bin2decimal(buffer, precision, scale);
    }

    private BigDecimal bin2decimal(ByteBuffer buffer, int precision, int scale) {
        int intg = precision - scale,
                intg0 = intg / DIG_PER_DEC1, frac0 = scale / DIG_PER_DEC1,
                intg0x = intg - intg0 * DIG_PER_DEC1, frac0x = scale - frac0 * DIG_PER_DEC1,
                intg1 = intg0 + (intg0x > 0 ? 1 : 0), frac1 = frac0 + (frac0x > 0 ? 1 : 0);
        byte m = buffer.get();
        boolean unsigned = (m & 0x80) == 0x80;

        int bin_size = intg0 * 4 + dig2bytes[intg0x] +
                frac0 * 4 + dig2bytes[frac0x];
        byte[] ucharBuf = BufferUtils.readFixedData(buffer, bin_size - 1);
        if (!unsigned) {
            for (int i = 0; i < ucharBuf.length; i++) {
                ucharBuf[i] ^= -1;
            }
        }
        byte[] dest = new byte[ucharBuf.length + 1];
        dest[0] = (byte) (((m ^ 0x80)) ^ (unsigned ? 0 : -1));
        System.arraycopy(ucharBuf, 0, dest, 1, dest.length-1);

        StringBuilder builder = new StringBuilder();
        int d = calculate(builder, intg0x, intg1, dest);
        //计算小数点后面的数字
        if (scale > 0) {
            dest = new byte[bin_size-d];
            System.arraycopy(ucharBuf, d-1, dest, 0, dest.length    );
            calculate(builder.append("."), frac0x, frac1, dest);
        }
        if(!unsigned){
            builder.insert(0,'-');
        }
        return new BigDecimal(builder.toString());
    }

    private int calculate(StringBuilder builder, int intg0x, int intg1,  byte[] ucharBuf) {
        int d = 0;
        int len = 0;
        byte[] dest = null;
        for (int i = 0; i < intg1; i++) {
            if(i == 0){
                len = intg0x == 0 ? 4 : dig2bytes[intg0x];
                dest = new byte[len];
                System.arraycopy(ucharBuf, 0, dest, 0, len);
            }else{
                len = 4;
                dest = new byte[len];
                System.arraycopy(ucharBuf, d, dest, 0, len);
            }
            d += len;
            int x = (int) BufferUtils.readBELog(dest, len);
            builder.append(x);
        }
        return d;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy