Пример #1
0
        /// <summary>
        /// Proto encoding of Dictionary [uint, byte[]].
        /// Use when key is less then 4 bytes (less then 268mln).
        /// Value byte[0] will be presented as null after decoding
        /// </summary>
        /// <param name="d"></param>
        /// <param name="compression">compression method extra applied to the outgoing byte array</param>
        /// <returns></returns>
        public static byte[] Encode_DICT_PROTO_UINT_BYTEARRAY(this IDictionary<uint, byte[]> d, Compression.eCompressionMethod compression = Compression.eCompressionMethod.NoCompression)
        {
            if (d == null || d.Count == 0)
                return null;

            List<byte[]> ar = new List<byte[]>();
            ulong size = 0;
            byte[] tar = null;

            foreach (var el in d)
            {
                //Setting key
                tar = GetVarintBytes(el.Key);
                size += (ulong)tar.Length;
                ar.Add(tar);
                //Setting length of value
                tar = el.Value == null ? new byte[] { 0 } : GetVarintBytes((uint)el.Value.Length); //Supporting 0 length, will be null then
                size += (ulong)tar.Length;
                ar.Add(tar);
                //Setting value
                size += (ulong)(el.Value == null ? 0 : el.Value.Length);
                if (el.Value != null && el.Value.Length > 0)
                    ar.Add(el.Value);
            }

            byte[] encB = new byte[size];
            int pt = 0;
            foreach (var el in ar)
            {
                Buffer.BlockCopy(el, 0, encB, pt, el.Length);
                pt += el.Length;
            }

            switch (compression)
            {
                case Compression.eCompressionMethod.Gzip:
                    encB = encB.GZip_Compress();
                    break;
            }

            return encB;
        }
Пример #2
0
        /// <summary>
        /// Used when parameter is encoded with Encode_DICT_PROTO_UINT_BYTEARRAY.
        /// Returns Dictionary [uint, byte[]]
        /// </summary>
        /// <param name="encB"></param>
        /// <param name="retD">Instantiated Dictionary must be supplied and will be returned filled</param>        
        /// <param name="compression">compression method supplied by Encode_DICT_PROTO_UINT_BYTEARRAY</param>
        public static void Decode_DICT_PROTO_UINT_BYTEARRAY(this byte[] encB, IDictionary<uint, byte[]> retD, Compression.eCompressionMethod compression = Compression.eCompressionMethod.NoCompression)
        {
            if (encB == null || encB.Length < 1)
                return;

            switch (compression)
            {
                case Compression.eCompressionMethod.Gzip:
                    encB = encB.GZip_Decompress();
                    break;
            }

            byte mode = 0;
            byte[] sizer = new byte[4];
            int size = 0;

            uint key = 0;
            uint valLen = 0;
            byte[] val = null;
            int valCnt = 0;

            Action ClearSizer = () =>
            {
                sizer[0] = 0;
                sizer[1] = 0;
                sizer[2] = 0;
                sizer[3] = 0;

                size = 0;
            };

            //0 - reading key
            //1 - reading size of value
            //2 - reading value
            foreach (byte el in encB)
            {
                switch (mode)
                {
                    case 0:
                        //Key, Size of BT //
                        if ((el & 0x80) > 0)
                        {
                            sizer[size] = el;
                            size++;
                        }
                        else
                        {
                            mode = 1;
                            sizer[size] = el;
                            size++;
                            key = ToUInt32(sizer);
                            ClearSizer();
                        }

                        break;
                    case 1:
                        //Value Size
                        if ((el & 0x80) > 0)
                        {
                            sizer[size] = el;
                            size++;
                        }
                        else
                        {
                            mode = 2;
                            sizer[size] = el;
                            size++;
                            valLen = ToUInt32(sizer);
                            ClearSizer();

                            if (valLen == 0)
                            {
                                retD.Add(key, null);
                                mode = 0;
                                break;
                            }

                            val = new byte[valLen];
                            valCnt = 0;
                        }
                        break;
                    case 2:
                        val[valCnt] = el;
                        valCnt++;
                        if (valCnt == valLen)
                        {
                            retD.Add(key, val);
                            mode = 0;
                            break;
                        }
                        break;
                }
            }

            return;
        }
Пример #3
0
        /// <summary>
        /// Proto encoding of Dictionary [string, HashSet[uint]].
        /// Hashset can be null, after decoding istantiated, zero-length hashset will be returned in this case.
        /// </summary>
        /// <param name="d"></param>
        /// <param name="compression"></param>
        /// <returns></returns>
        public static byte[] Encode_DICT_PROTO_STRING_UINTHASHSET(this IDictionary<string, HashSet<uint>> d, Compression.eCompressionMethod compression = Compression.eCompressionMethod.NoCompression)
        {
            if (d == null || d.Count == 0)
                return null;

            List<byte[]> ar = new List<byte[]>();
            int size = 0;
            byte[] tar = null;
            byte[] tar1 = null;

            foreach (var el in d)
            {
                //Setting key
                tar = el.Key.To_UTF8Bytes();
                tar1 = GetVarintBytes((uint)tar.Length);
                ar.Add(tar1);//length of key
                ar.Add(tar);//key self
                size += tar1.Length;
                size += tar.Length;

                //Setting count of hashset
                tar = GetVarintBytes((uint)(el.Value == null ? 0 : el.Value.Count));
                ar.Add(tar);
                size += tar.Length;
                //Hashset
                if (el.Value != null)
                {
                    foreach (var evl in el.Value)
                    {
                        tar = GetVarintBytes(evl);
                        ar.Add(tar);
                        size += tar.Length;
                    }
                }

            }

            byte[] encB = new byte[size];
            int pt = 0;
            foreach (var el in ar)
            {
                Buffer.BlockCopy(el, 0, encB, pt, el.Length);
                pt += el.Length;
            }

            switch (compression)
            {
                case Compression.eCompressionMethod.Gzip:
                    encB = encB.GZip_Compress();
                    break;
            }

            return encB;
        }
Пример #4
0
        /// <summary>
        /// Decodes byte[] into  Dictionary [string, HashSet[uint]]
        /// </summary>
        /// <param name="encB"></param>
        /// <param name="retD"></param>
        /// <param name="compression"></param>
        /// <returns></returns>
        public static void Decode_DICT_PROTO_STRING_UINTHASHSET(this byte[] encB, IDictionary<string, HashSet<uint>> retD, Compression.eCompressionMethod compression = Compression.eCompressionMethod.NoCompression)
        {
            if (encB == null || encB.Length < 1)
                return;

            switch (compression)
            {
                case Compression.eCompressionMethod.Gzip:
                    encB = encB.GZip_Decompress();
                    break;
            }

            byte mode = 0;
            byte[] sizer = new byte[4];
            int size = 0;

            uint keyLength = 0;
            string key = "";
            uint valCnt = 0;

            Action ClearSizer = () =>
            {
                sizer[0] = 0;
                sizer[1] = 0;
                sizer[2] = 0;
                sizer[3] = 0;

                size = 0;
            };

            //0 - reading key
            //1 - HashSet Count
            //2 - reading Hashset elements one by one

            byte el = 0;
            int i = 0;
            int hc = 0; //Hashset grabbed count
            HashSet<uint> mhs = null;

            while (i < encB.Length)
            {
                el = encB[i];

                switch (mode)
                {
                    case 0:

                        if ((el & 0x80) > 0)
                        {
                            sizer[size] = el;
                            size++;
                        }
                        else
                        {
                            hc = 0;
                            mode = 1;
                            sizer[size] = el;
                            size++;
                            keyLength = ToUInt32(sizer);
                            key = System.Text.Encoding.UTF8.GetString(encB.Substring(i + 1, (int)keyLength));
                            i += (int)keyLength + 1;
                            ClearSizer();
                            continue;
                        }

                        break;
                    case 1:
                        //HashSet Count
                        if ((el & 0x80) > 0)
                        {
                            sizer[size] = el;
                            size++;
                        }
                        else
                        {
                            mode = 2;
                            sizer[size] = el;
                            size++;
                            valCnt = ToUInt32(sizer);
                            ClearSizer();

                            if (valCnt == 0)
                            {
                                retD.Add(key, new HashSet<uint>());
                                mode = 0;
                            }
                        }
                        break;
                    case 2:
                        if ((el & 0x80) > 0)
                        {
                            sizer[size] = el;
                            size++;
                        }
                        else
                        {
                            sizer[size] = el;
                            size++;
                            if (hc == 0)
                                mhs = new HashSet<uint>();
                            mhs.Add(ToUInt32(sizer));
                            hc++;
                            ClearSizer();

                            if (valCnt == hc)
                            {
                                mode = 0;
                                retD.Add(key, mhs);
                            }
                        }
                        break;
                }
                i++;
            }

            return;
        }