How to convert objects in protobuf-net in java, javaprotobuf-net
Some C # services in the company use proto-net and introduce bcl. Decimal and bcl. DateTime in bcl. proto. For java proto generation code, it is required to convert the data types that are supported at a cost for bcl. Decimal and bcl. DateTime.
The structure of bcl. Decimal is 32-bit int, 64-bit long, And signScale stores symbols (plus and minus) and modulus. The conversion process is as follows:
Bcl. Decimal --> BigDecimal
1. convert a 32-bit high int to a four-Length byte array in the front format;
2. convert a 64-bit long to an eight-Length byte array in the format of a High Front;
3. combine the two arrays into a 12-Length byte array bigIntBytes to obtain the signScale symbol value sgin = (signScale & 1) = 1? -1: 1; (refer to the comment of bcl. Decimal: the number of decimal digits (bits 1-16), and the sign (bit 0 ))
4. Obtain the BigInteger object bInt, new BigInteger (sgin, bigIntBytes) based on bigIntBytes and sgin );
5. obtain the modulo value scale = (signScale & 0b1111_1111_1111_11_1110)> 1; (refer to bcl. decimal Note: the number of decimal digits (bits 1-16), and the sign (bit 0 ))
6. Get the BigDecimal object based on bInt and scale, new BigDecimal (bint, scale );
BigDecimal --> bcl. Decimal
Otherwise
The Code is as follows:
/* JDK1.7 */
Public class BclUtil {/*****/private static final long TICKS_PER_MILLISECOND = 10000; private static final int SIGNSCALE_FLAG = 0b1111_11_1111_1110; private BclUtil () {}/ *** convert bcl. decimal, returns BigDecimal <br> * Before high <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);}/*** converts BigDecimal, return bcl. decimal <br> * High Front <br> ** @ param bigDecimal * @ return */public final static Bcl. decimal bigDecimalToBclDecimal (BigDecimal bigDe Cimal) {if (bigDecimal = null) {return null;} Bcl. decimal. builder B = Bcl. decimal. newBuilder (); // obtain BigInteger, which must be unscaledValueBigInteger bi = bigDecimal. unscaledValue (); byte [] deBytes = new byte [12]; byte [] bigIntegerBytes = bi. toByteArray (); System. arraycopy (bigIntegerBytes, 0, deBytes, 12-bigIntegerBytes. length, bigIntegerBytes. length); // 4-bit intint hi = Eutil. bytes2int (deBytes, 0); B. setHi (hi ); // Take the lower 8-bit longlong 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) {// get the flag bit from BigInteger and put it in bit 0/get the flag bit from BigDecimal and put it in bit 1-16return 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 ();}/*** fill value symbol <br> ** @ param sign * @ return */public final static byte getSignInSignScale (int sign) {byte signTemp = 0; if (sign <0) {signTemp = 1;} return signTemp ;} /*** get the value symbol <br> ** @ param signScale * @ return */public final static int getSign (int signScale) {// the number of decimal digits (bits 1-16), and Sign (bit 0) boolean isNegative = (signScale & 1) = 1; return isNegative? -1: 1;}/*** obtain the modulus ** @ 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 ;} /*** get the byte array of the int, which is in the top position ** @ 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;}/*** get the byte array of long, high Front ** @ 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 & 0 xffffffff); int2byte (dst, 0 + pos, (int) (src >>> 32) & 0 xffffffff ));} else {int2byte (dst, 0 + pos, (int) (src & 0 xffffffff); int2byte (dst, 4 + pos, (int) (src >>> 32) & 0 xffffffff ));}}}