вторник, 10 ноября 2020 г.

google.protobuf encode variants

 private static int GetDestBytes(ulong number)

        {

            for (int i = 0; i < sizeof(ulong); i++)

            {

                if (number < (ulong)1 << (8 * (i + 1) - 1) >> i)

                {

                    return i + 1;

                }

            }


            if ((number & ((ulong)1 << 63)) != 0)

            {

                return sizeof(ulong) + 2;

            }


            return sizeof(ulong) + 1;

        }


        private static int GetMinBytes(ulong number)

        {

            for (int i = 0; i < sizeof(ulong) - 1; i++)

            {

                if (number < (ulong)1 << (8 * (i + 1)))

                {

                    return i + 1;

                }

            }


            return sizeof(ulong);

        }


        public static byte[] GetVariant_my(ulong number)

        {

            int destLength = GetDestBytes(number);


            if (destLength == 1) //nothing to encode

            {

                return new byte[]

                {

                    (byte)number

                };

            }


            byte[] byteArray = BitConverter.GetBytes(number).Take(GetMinBytes(number)).ToArray();

            byte[] destArray = new byte[destLength];


            //save first 1 bit

            byte prevFirstBits = (byte)((uint)byteArray[0] >> 7);

            destArray[0] = (byte)(byteArray[0] | 128); // set msb = 1


            for (int i = 1; i < byteArray.Length; i++)

            {

                var firstBits = (byte)((uint)byteArray[i] >> (8 - i - 1));


                //shift to right and apply saved bits from prev octet

                destArray[i] = (byte)(byteArray[i] << i | prevFirstBits);


                //for non-last octet set msb = 1

                if (i < destLength - 1)

                {

                    destArray[i] = (byte)(destArray[i] | 128);

                }


                prevFirstBits = firstBits;

            }


            // apply prev saved bit to last byte

            if (prevFirstBits != 0)

            {

                destArray[byteArray.Length] = prevFirstBits;

            }


            //for numbers > 2^63 need to save msb

            if (destArray.Length == 10)

            {

                destArray[^1] = 1;

            }


            return destArray;

        }

Комментариев нет:

Отправить комментарий