程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java如何轉換protobuf-net中的對象,javaprotobuf-net

java如何轉換protobuf-net中的對象,javaprotobuf-net

編輯:JAVA綜合教程

java如何轉換protobuf-net中的對象,javaprotobuf-net


      公司內部有些C#服務使用proto-net,引入了bcl.proto中的bcl.Decimal、bcl.DateTime等。對於java的proto生成代碼需要對bcl.Decimal、bcl.DateTime轉換成本地支持的數據類型。
bcl.Decimal結構為32位int保存高位、64位long保存低位,signScale 保存符號(正負)及模數。轉換過程如下:

  bcl.Decimal  --> BigDecimal
  1. 將高32位的int以高位在前格式轉換為4個長度的byte數組;
  2. 將低64位的long以高位在前的格式轉換為8個長度的byte數組;
  3. 將兩個數組組合為12長度的byte數組bigIntBytes,獲取signScale的符號值sgin = (signScale & 1) == 1 ? -1 : 1; (參考bcl.Decimal 注釋:the number of decimal digits (bits 1-16), and the sign (bit 0))
  4. 根據bigIntBytes和sgin獲取BigInteger對象bInt,new BigInteger(sgin,bigIntBytes);
  5. 獲取signScale的模數值scale = (signScale & 0b1111_1111_1111_1110) >> 1; (參考bcl.Decimal 注釋:the number of decimal digits (bits 1-16), and the sign (bit 0))

     6.根據bInt和scale獲取BigDecimal對象,new BigDecimal(bint, scale);

  BigDecimal -->  bcl.Decimal
  上述過程反之即可

代碼如下:

/*JDK1.7*/
public class BclUtil { /** * */ private static final long TICKS_PER_MILLISECOND = 10000; private static final int SIGNSCALE_FLAG = 0b1111_1111_1111_1110; private BclUtil() { } /** * 轉換 bcl.Decimal,返回BigDecimal<br> * 高位在前<br> * * @param bclDecimal * @return */ public final static BigDecimal bclDecimalToBigDecimal(Bcl.Decimal bclDecimal) { if (bclDecimal == null) { return BigDecimal.ZERO; } byte[] deBytes = new byte[12]; int2byte(deBytes, 0, bclDecimal.getHi()); long2byte(deBytes, 4, bclDecimal.getLo()); int signScale = bclDecimal.getSignScale(); BigInteger bint = new BigInteger(getSign(signScale), deBytes); return new BigDecimal(bint, getScale(signScale)); } /** * 轉換BigDecimal,返回bcl.Decimal<br> * 高位在前<br> * * @param bigDecimal * @return */ public final static Bcl.Decimal bigDecimalToBclDecimal(BigDecimal bigDecimal) { if (bigDecimal == null) { return null; } Bcl.Decimal.Builder b = Bcl.Decimal.newBuilder(); // 獲取BigInteger,必須是unscaledValue BigInteger bi = bigDecimal.unscaledValue(); byte[] deBytes = new byte[12]; byte[] bigIntegerBytes = bi.toByteArray(); System.arraycopy(bigIntegerBytes, 0, deBytes, 12 - bigIntegerBytes.length, bigIntegerBytes.length); // 取高4位int int hi = Eutil.bytes2int(deBytes, 0); b.setHi(hi); // 取低8位long long lo = Eutil.bytes2long(deBytes, 4); b.setLo(lo); int signScale = getSignScale(bi.signum(), bigDecimal.scale()); b.setSignScale(signScale); return b.build(); } private static int getSignScale(int signum, int scale) { // 從BigInteger獲取取標志位放在bit 0/從BigDecimal獲取取標志位放在bit 1-16 return getSignInSignScale(signum) | (scale << 1); } public final static Bcl.Decimal zeroOfBclDecimal() { Bcl.Decimal.Builder b = Bcl.Decimal.newBuilder(); b.setHi(0); b.setLo(0); b.setSignScale(0); return b.build(); } /** * 填充值符號<br> * * @param sign * @return */ public final static byte getSignInSignScale(int sign) { byte signTemp = 0; if (sign < 0) { signTemp = 1; } return signTemp; } /** * 獲取值符號<br> * * @param signScale * @return */ public final static int getSign(int signScale) { // the number of decimal digits (bits 1-16), and the sign (bit 0) boolean isNegative = (signScale & 1) == 1; return isNegative ? -1 : 1; } /** * 獲取模數 * * @param signScale * @return */ public final static int getScale(int signScale) { // the number of decimal digits (bits 1-16), and the sign (bit 0) return (signScale & SIGNSCALE_FLAG) >> 1; } /** * 獲取int的byte數組,高位在前 * * @param dst * @param pos * @param src */ public final static void int2byte(byte[] dst, int pos, int src) { int2byte(dst, pos, src, true); } public final static byte[] int2byte(byte[] dst, int pos, int src, boolean big_endian) { if (big_endian) { dst[pos + 3] = (byte) ((src >>> 0) & 0xff); dst[pos + 2] = (byte) ((src >>> 8) & 0xff); dst[pos + 1] = (byte) ((src >>> 16) & 0xff); dst[pos + 0] = (byte) ((src >>> 24) & 0xff); } else { dst[pos + 0] = (byte) ((src >>> 0) & 0xff); dst[pos + 1] = (byte) ((src >>> 8) & 0xff); dst[pos + 2] = (byte) ((src >>> 16) & 0xff); dst[pos + 3] = (byte) ((src >>> 24) & 0xff); } return dst; } public final static byte[] int2unSignByte(byte[] dst, int pos, int src, boolean big_endian) { if (big_endian) { dst[pos + 3] = (byte) ((src >>> 0) & 0xff + 128); dst[pos + 2] = (byte) ((src >>> 8) & 0xff + 128); dst[pos + 1] = (byte) ((src >>> 16) & 0xff + 128); dst[pos + 0] = (byte) ((src >>> 24) & 0xff + 128); } else { dst[pos + 0] = (byte) ((src >>> 0) & 0xff + 128); dst[pos + 1] = (byte) ((src >>> 8) & 0xff + 128); dst[pos + 2] = (byte) ((src >>> 16) & 0xff + 128); dst[pos + 3] = (byte) ((src >>> 24) & 0xff + 128); } return dst; } /** * 獲取long的byte數組,高位在前 * * @param dst * @param pos * @param src */ final static void long2byte(byte[] dst, int pos, long src) { long2byte(dst, pos, src, true); } final static void long2byte(byte[] dst, int pos, long src, boolean big_endian) { if (big_endian) { int2byte(dst, 4 + pos, (int) (src & 0xffffffff)); int2byte(dst, 0 + pos, (int) ((src >>> 32) & 0xffffffff)); } else { int2byte(dst, 0 + pos, (int) (src & 0xffffffff)); int2byte(dst, 4 + pos, (int) ((src >>> 32) & 0xffffffff)); } } }

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved