Exemplo n.º 1
0
        private static int BytesToRead(object i)
        {
            if (i is byte)
            {
                return(1);
            }
            bool  size;
            ulong integer;

            if (i is decimal)
            {
                return(BytesToRead((int)dec_flags.GetValue(i)) + BytesToRead((int)dec_lo.GetValue(i)) + BytesToRead((int)dec_mid.GetValue(i)) + BytesToRead((int)dec_hi.GetValue(i)));
            }
            if ((size = i is float) || i is double)
            {
                int   bytes         = size ? 4 : 8;
                Array type_holder   = size ? holder_f as Array : holder_d as Array; // Fetch the preallocated array
                Array result_holder = size ? holder_i as Array : holder_u as Array;
                lock (result_holder)
                    lock (type_holder)
                    {
                        // Clear artifacts
                        if (size)
                        {
                            result_holder.SetValue(0U, 0);
                        }
                        else
                        {
                            result_holder.SetValue(0UL, 0);
                        }

                        type_holder.SetValue(i, 0);                                // Insert the value to convert into the preallocated holder array
                        Buffer.BlockCopy(type_holder, 0, result_holder, 0, bytes); // Perform an internal copy to the byte-based holder
                        if (size)
                        {
                            integer = BinaryHelpers.SwapEndian((uint)result_holder.GetValue(0));
                        }
                        else
                        {
                            integer = BinaryHelpers.SwapEndian((ulong)result_holder.GetValue(0));
                        }
                    }
            }
            else
            {
                integer = i as ulong? ?? i as uint? ?? i as ushort? ?? i as byte? ?? 0;
            }
            return
                (integer <= 240 ? 1 :
                 integer <= 2287 ? 2 :
                 integer <= 67823 ? 3 :
                 integer <= 16777215 ? 4 :
                 integer <= 4294967295 ? 5 :
                 integer <= 1099511627775 ? 6 :
                 integer <= 281474976710655 ? 7 :
                 integer <= 72057594037927935 ? 8 :
                 9);
        }
Exemplo n.º 2
0
        private T ReadFloating <T>()
        {
            int   size          = Marshal.SizeOf(typeof(T));
            Array type_holder   = size == 4 ? holder_f as Array : holder_d as Array;
            Array result_holder = size == 4 ? holder_i as Array : holder_u as Array;
            T     result;

            lock (result_holder)
                lock (type_holder)
                {
                    if (size == 4)
                    {
                        result_holder.SetValue(BinaryHelpers.SwapEndian(ReadUInt()), 0);
                    }
                    else
                    {
                        result_holder.SetValue(BinaryHelpers.SwapEndian(ReadULong()), 0);
                    }
                    Buffer.BlockCopy(result_holder, 0, type_holder, 0, size);
                    result = (T)type_holder.GetValue(0);
                }
            return(result);
        }
Exemplo n.º 3
0
        private static void Serialize <T>(T t, byte[] writeTo, ref long bitOffset, ref bool isAligned)
        {
            Type type = t.GetType();
            bool size = false;

            if (type.IsArray)
            {
                var array = t as Array;
                Serialize((uint)array.Length, writeTo, ref bitOffset, ref isAligned);
                foreach (var element in array)
                {
                    Serialize(element, writeTo, ref bitOffset, ref isAligned);
                }
            }
            else if (type == typeof(Partial))
            {
                byte count;
                WriteByte(writeTo, (byte)Partial.value_info.GetValue(t), bitOffset, isAligned, count = (byte)Partial.count_info.GetValue(t));
                bitOffset += count;
                isAligned  = bitOffset % 8 == 0;
                return;
            }
            else if (IsSupportedType(type))
            {
                long offset = t is bool? 1 : BytesToRead(t) * 8;
                if (type == typeof(bool))
                {
                    WriteBit(writeTo, t as bool? ?? false, bitOffset);
                    bitOffset += offset;
                    isAligned  = bitOffset % 8 == 0;
                }
                else if (type == typeof(decimal))
                {
                    WriteDynamic(writeTo, (int)dec_lo.GetValue(t), 4, bitOffset, isAligned);
                    WriteDynamic(writeTo, (int)dec_mid.GetValue(t), 4, bitOffset + 32, isAligned);
                    WriteDynamic(writeTo, (int)dec_hi.GetValue(t), 4, bitOffset + 64, isAligned);
                    WriteDynamic(writeTo, (int)dec_flags.GetValue(t), 4, bitOffset + 96, isAligned);
                    bitOffset += offset;
                }
                else if ((size = type == typeof(float)) || type == typeof(double))
                {
                    int   bytes         = size ? 4 : 8;
                    Array type_holder   = size ? holder_f as Array : holder_d as Array; // Fetch the preallocated array
                    Array result_holder = size ? holder_i as Array : holder_u as Array;
                    lock (result_holder)
                        lock (type_holder)
                        {
                            // Clear artifacts
                            if (size)
                            {
                                result_holder.SetValue(0U, 0);
                            }
                            else
                            {
                                result_holder.SetValue(0UL, 0);
                            }
                            type_holder.SetValue(t, 0);                                // Insert the value to convert into the preallocated holder array
                            Buffer.BlockCopy(type_holder, 0, result_holder, 0, bytes); // Perform an internal copy to the byte-based holder

                            // Since floating point flag bits are seemingly the highest bytes of the floating point values
                            // and even very small values have them, we swap the endianness in the hopes of reducing the size
                            if (size)
                            {
                                Serialize(BinaryHelpers.SwapEndian((uint)result_holder.GetValue(0)), writeTo, ref bitOffset, ref isAligned);
                            }
                            else
                            {
                                Serialize(BinaryHelpers.SwapEndian((ulong)result_holder.GetValue(0)), writeTo, ref bitOffset, ref isAligned);
                            }
                        }
                }
                else
                {
                    ulong value;
                    if (t is byte)
                    {
                        WriteByte(writeTo, t as byte? ?? 0, bitOffset, isAligned);
                        bitOffset += 8;
                        return;
                    }
                    else if (t is ushort)
                    {
                        value = t as ushort? ?? 0;
                    }
                    else if (t is uint)
                    {
                        value = t as uint? ?? 0;
                    }
                    else
                    {
                        value = t as ulong? ?? 0;
                    }

                    if (value <= 240)
                    {
                        WriteByte(writeTo, (byte)value, bitOffset, isAligned);
                    }
                    else if (value <= 2287)
                    {
                        WriteByte(writeTo, (value - 240) / 256 + 241, bitOffset, isAligned);
                        WriteByte(writeTo, (value - 240) % 256, bitOffset + 8, isAligned);
                    }
                    else if (value <= 67823)
                    {
                        WriteByte(writeTo, 249, bitOffset, isAligned);
                        WriteByte(writeTo, (value - 2288) / 256, bitOffset + 8, isAligned);
                        WriteByte(writeTo, (value - 2288) % 256, bitOffset + 16, isAligned);
                    }
                    else
                    {
                        WriteByte(writeTo, value & 255, bitOffset + 8, isAligned);
                        WriteByte(writeTo, (value >> 8) & 255, bitOffset + 16, isAligned);
                        WriteByte(writeTo, (value >> 16) & 255, bitOffset + 24, isAligned);
                        if (value > 16777215)
                        {
                            WriteByte(writeTo, (value >> 24) & 255, bitOffset + 32, isAligned);
                            if (value > 4294967295)
                            {
                                WriteByte(writeTo, (value >> 32) & 255, bitOffset + 40, isAligned);
                                if (value > 1099511627775)
                                {
                                    WriteByte(writeTo, (value >> 40) & 255, bitOffset + 48, isAligned);
                                    if (value > 281474976710655)
                                    {
                                        WriteByte(writeTo, (value >> 48) & 255, bitOffset + 56, isAligned);
                                        if (value > 72057594037927935)
                                        {
                                            WriteByte(writeTo, 255, bitOffset, isAligned);
                                            WriteByte(writeTo, (value >> 56) & 255, bitOffset + 64, isAligned);
                                        }
                                        else
                                        {
                                            WriteByte(writeTo, 254, bitOffset, isAligned);
                                        }
                                    }
                                    else
                                    {
                                        WriteByte(writeTo, 253, bitOffset, isAligned);
                                    }
                                }
                                else
                                {
                                    WriteByte(writeTo, 252, bitOffset, isAligned);
                                }
                            }
                            else
                            {
                                WriteByte(writeTo, 251, bitOffset, isAligned);
                            }
                        }
                        else
                        {
                            WriteByte(writeTo, 250, bitOffset, isAligned);
                        }
                    }
                    bitOffset += BytesToRead(value) * 8;
                }
            }
        }