コード例 #1
0
        internal static void WriteArray(IValueWriter valueWriter, object value, Type type)
        {
            var items = Underlying.As <Array>(value).Clone();

            Underlying.GetMethodTablePointer(items) = TypeHelper.GetMethodTablePointer(GetArrayValueType(type));

            ValueInterface.WriteValue(valueWriter, items);
        }
コード例 #2
0
        internal static SerializationInfo CreateSerializationInfo(object obj)
        {
            var serializationInfo = new SerializationInfo(obj.GetType(), DefaultFormatterConverter);
            var streamingContext  = new StreamingContext(DefaultStreamingContextStates);

            Underlying.As <ISerializable>(obj).GetObjectData(serializationInfo, streamingContext);

            return(serializationInfo);
        }
コード例 #3
0
ファイル: XConvert.cs プロジェクト: shunfy/Swifter.Json
        public static TDestination Convert <TSource, TDestination>(TSource value)
        {
            if (typeof(TSource) == typeof(TDestination))
            {
                return(Underlying.As <TSource, TDestination>(ref value));
            }

            return(InternalConvert <TSource, TDestination> .Instance.Convert(value));
        }
コード例 #4
0
        public static void ReadFrom <T>(this HGlobalCache <T> hGCache, ref T source, int length) where T : unmanaged
        {
            hGCache.Grow(length);

            Underlying.CopyBlock(
                ref Underlying.As <T, byte>(ref *hGCache.Current),
                ref Underlying.As <T, byte>(ref source),
                checked ((uint)((long)length * sizeof(T)))
                );

            hGCache.Count += length;
        }
コード例 #5
0
        public void OffsetOfTest()
        {
            var obj = new Tester();

            var int64_offset  = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.public_int64)));
            var string_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.public_string)));

            var static_int_offset    = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_int)));
            var static_string_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_string)));
            var static_object_offset = TypeHelper.OffsetOf(typeof(Tester).GetField(nameof(Tester.static_object)));

            var struct_int64_offset  = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.public_int64)));
            var struct_string_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.public_string)));

            var struct_static_bool_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.static_bool)));
            var struct_static_byte_offset = TypeHelper.OffsetOf(typeof(Tester_Struct).GetField(nameof(Tester_Struct.static_byte)));

            var gc_statics_base_pointer            = (void *)TypeHelper.GetGCStaticsBasePointer(typeof(Tester));
            var non_gc_statics_base_pointer        = (void *)TypeHelper.GetNonGCStaticsBasePointer(typeof(Tester));
            var struct_non_gc_statics_base_pointer = (void *)TypeHelper.GetNonGCStaticsBasePointer(typeof(Tester_Struct));

            Underlying.AddByteOffset(ref TypeHelper.Unbox <long>(obj), int64_offset)    = 999;
            Underlying.AddByteOffset(ref TypeHelper.Unbox <string>(obj), string_offset) = "F**k";

            AreEqual(obj.public_int64, 999);
            AreEqual(obj.public_string, "F**k");

            Underlying.AddByteOffset(ref Underlying.AsRef <int>(non_gc_statics_base_pointer), static_int_offset)   = 123;
            Underlying.AddByteOffset(ref Underlying.AsRef <string>(gc_statics_base_pointer), static_string_offset) = "Dogwei";
            Underlying.AddByteOffset(ref Underlying.AsRef <object>(gc_statics_base_pointer), static_object_offset) = obj;

            AreEqual(Tester.static_int, 123);
            AreEqual(Tester.static_string, "Dogwei");
            AreEqual(Tester.static_object, obj);


            var value = new Tester_Struct();


            Underlying.AddByteOffset(ref Underlying.As <Tester_Struct, long>(ref value), struct_int64_offset)    = 999;
            Underlying.AddByteOffset(ref Underlying.As <Tester_Struct, string>(ref value), struct_string_offset) = "F**k";

            AreEqual(value.public_int64, 999);
            AreEqual(value.public_string, "F**k");

            Underlying.AddByteOffset(ref Underlying.AsRef <bool>(struct_non_gc_statics_base_pointer), struct_static_bool_offset) = true;
            Underlying.AddByteOffset(ref Underlying.AsRef <byte>(struct_non_gc_statics_base_pointer), struct_static_byte_offset) = 128;

            AreEqual(Tester_Struct.static_bool, true);
            AreEqual(Tester_Struct.static_byte, 128);
        }
コード例 #6
0
        public static int GetUtf8Bytes(ref char chars, int length, byte *bytes)
        {
            var offset = bytes;

            while (length >= 4 && (Underlying.As <char, ulong>(ref chars) & 0xff80ff80ff80ff80) == 0)
            {
                *(uint *)offset = Close(Underlying.As <char, ulong>(ref chars));

                chars   = ref Underlying.Add(ref chars, 4);
                length -= 4;
                offset += 4;
            }

            for (int i = 0; i < length; i++)
            {
                int @char = Underlying.Add(ref chars, i);

                if (@char <= 0x7f)
                {
                    *offset = (byte)@char; ++offset;
                }
                else if (@char <= 0x7ff)
                {
                    offset[0] = (byte)(0xc0 | (@char >> 6));
                    offset[1] = (byte)(0x80 | (@char & 0x3f));

                    offset += 2;
                }
                else if (@char >= 0xd800 && @char <= 0xdbff)
                {
                    @char = (((@char & 0x3ff) << 10) | (Underlying.Add(ref chars, ++i) & 0x3ff)) + 0x10000;

                    offset[0] = (byte)(0xf0 | (@char >> 18));
                    offset[1] = (byte)(0x80 | ((@char >> 12) & 0x3f));
                    offset[2] = (byte)(0x80 | ((@char >> 6) & 0x3f));
                    offset[3] = (byte)(0x80 | (@char & 0x3f));

                    offset += 4;
                }
                else
                {
                    offset[0] = (byte)(0xe0 | (@char >> 12));
                    offset[1] = (byte)(0x80 | ((@char >> 6) & 0x3f));
                    offset[2] = (byte)(0x80 | (@char & 0x3f));

                    offset += 3;
                }
            }

            return((int)(offset - bytes));
        }
コード例 #7
0
        public static unsafe void GetAllFieldOffsetByIndexOfInstance(Type declaringType)
        {
            object obj = null;

Loop:

            try
            {
                obj = TypeHelper.Allocate(declaringType);
            }
            catch
            {
                if (declaringType.IsAbstract && TypeHelper.GetTypesForAllAssembly().FirstOrDefault(type => declaringType.IsAssignableFrom(type) && !type.IsAbstract) is Type subClass)
                {
                    declaringType = subClass;

                    goto Loop;
                }
            }

            if (obj is null)
            {
                return;
            }

            var fields = TypeHelper.GetFields(declaringType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
            var length = TypeHelper.GetAlignedNumInstanceFieldBytes(declaringType);

            fixed(byte *ptr = &Underlying.As <StructBox <byte> >(obj).Value)
            {
                foreach (var fieldInfo in fields)
                {
                    Underlying.InitBlock(ptr, 0xff, (uint)length);

                    fieldInfo.SetValue(obj, TypeHelper.GetDefaultValue(fieldInfo.FieldType));

                    for (int i = 0; i < length; i++)
                    {
                        if (ptr[i] == 0)
                        {
                            Add(fieldInfo.FieldHandle.Value, i);

                            break;
                        }
                    }
                }

                Underlying.InitBlock(ptr, 0, (uint)length);
            }
        }
コード例 #8
0
 static bool Equals(T x, T y)
 {
     if (typeof(T) == typeof(char))
     {
         return(Underlying.As <T, char>(ref x) == Underlying.As <T, char>(ref y));
     }
     else if (typeof(T) == typeof(byte) || typeof(T) == typeof(Utf8Byte))
     {
         return(Underlying.As <T, byte>(ref x) == Underlying.As <T, byte>(ref y));
     }
     else
     {
         return(EqualityComparer <T> .Default.Equals(x, y));
     }
 }
コード例 #9
0
        /// <summary>
        /// 生成 Switch(IntPtr) 代码块。
        /// </summary>
        /// <param name="ilGen">ILGenerator IL 指令生成器</param>
        /// <param name="emitLoadValue">生成加载 Switch 参数的指令的委托</param>
        /// <param name="cases">case 标签块集合</param>
        /// <param name="defaultLabel">默认标签块</param>
        public static void Switch(this ILGenerator ilGen,
                                  Action <ILGenerator> emitLoadValue,
                                  CaseInfo <IntPtr>[] cases,
                                  Label defaultLabel)
        {
            cases = Underlying.As <CaseInfo <IntPtr>[]>(cases.Clone());

            Array.Sort(cases, (Before, After) => ((long)Before.Value).CompareTo((long)After.Value));

            SwitchNumber(
                ilGen,
                emitLoadValue,
                (il, value) => { il.LoadConstant((long)value); il.ConvertPointer(); },
                cases,
                defaultLabel,
                0,
                (cases.Length - 1) / 2,
                cases.Length - 1
                );
        }
コード例 #10
0
        private protected override void InitializeByValue(PropertyInfo propertyInfo, XBindingFlags flags)
        {
            base.InitializeByValue(propertyInfo, flags);

            if ((flags & XBindingFlags.RWAutoPropertyDirectRW) != 0 && TypeHelper.IsAutoProperty(propertyInfo, out var fieldInfo) && fieldInfo != null)
            {
                try
                {
                    var offset = TypeHelper.OffsetOf(fieldInfo);

                    _get = (ref TStruct obj) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset);
                    _set = (ref TStruct obj, TValue value) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset) = value;

                    return;
                }
                catch
                {
                }
            }

            if (_get is null)
            {
                var getMethod = propertyInfo.GetGetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (getMethod != null)
                {
                    _get = MethodHelper.CreateDelegate <XStructGetValueHandler <TStruct, TValue> >(getMethod, false);
                }
            }

            if (_set is null)
            {
                var setMethod = propertyInfo.GetSetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (setMethod != null)
                {
                    _set = MethodHelper.CreateDelegate <XStructSetValueHandler <TStruct, TValue> >(setMethod, false);
                }
            }
        }
コード例 #11
0
        public static int GetUtf8Chars(byte *bytes, int length, ref char chars)
        {
            var num = 0;

            while (length >= 4 && (*(uint *)bytes & 0x80808080) == 0)
            {
                Underlying.As <char, ulong>(ref Underlying.Add(ref chars, num)) = Open(*(uint *)bytes);

                bytes  += 4;
                length -= 4;
                num    += 4;
            }

            for (var end = bytes + length; bytes < end; bytes++, num++)
            {
                int @byte = *bytes;

                if (@byte <= 0x7f)
                {
                    Underlying.Add(ref chars, num) = (char)@byte;
                }
                else if (@byte <= 0xdf)
                {
                    Underlying.Add(ref chars, num) = (char)(((@byte & 0x1f) << 6) | (*(++bytes) & 0x3f));
                }
                else if (@byte <= 0xef)
                {
                    Underlying.Add(ref chars, num) = (char)(((@byte & 0xf) << 12) | ((*(++bytes) & 0x3f) << 6) + (*(++bytes) & 0x3f));
                }
                else
                {
                    @byte = (((@byte & 0x7) << 18) | ((*(++bytes) & 0x3f) << 12) | ((*(++bytes) & 0x3f) << 6) + (*(++bytes) & 0x3f)) - 0x10000;

                    Underlying.Add(ref chars, num) = (char)(0xd800 | (@byte >> 10)); ++num;
                    Underlying.Add(ref chars, num) = (char)(0xdc00 | (@byte & 0x3ff));
                }
            }

            return(num);
        }
コード例 #12
0
ファイル: JsonCode.cs プロジェクト: shunfy/Swifter.Json
        public static T SlowReadParse <T>(string str)
        {
            if (typeof(T) == typeof(DateTime))
            {
                return(Underlying.As <DateTime, T>(ref Underlying.AsRef(DateTime.Parse(str))));
            }
            else if (typeof(T) == typeof(DateTimeOffset))
            {
                return(Underlying.As <DateTimeOffset, T>(ref Underlying.AsRef(DateTimeOffset.Parse(str))));
            }
            else if (typeof(T) == typeof(Guid))
            {
                return(Underlying.As <Guid, T>(ref Underlying.AsRef(new Guid(str))));
            }
            else if (typeof(T) == typeof(long))
            {
                return(Underlying.As <long, T>(ref Underlying.AsRef(long.Parse(str, NumberStyle))));
            }
            else if (typeof(T) == typeof(ulong))
            {
                return(Underlying.As <ulong, T>(ref Underlying.AsRef(ulong.Parse(str, NumberStyle))));
            }
            else if (typeof(T) == typeof(double))
            {
                return(Underlying.As <double, T>(ref Underlying.AsRef(double.Parse(str, NumberStyle))));
            }
            else if (typeof(T) == typeof(decimal))
            {
                return(Underlying.As <decimal, T>(ref Underlying.AsRef(decimal.Parse(str, NumberStyle))));
            }
            else if (typeof(T) == typeof(RWPathInfo))
            {
                fixed(char *chars = str)
                {
                    return((T)(object)ParseReference(chars, str.Length));
                }
            }

            return(default);
コード例 #13
0
        public IValueInterface <T> TryMap <T>()
        {
            if (typeof(T).IsArray)
            {
                var elementType = typeof(T).GetElementType();

                Type interfaceType;

                if (typeof(T).GetArrayRank() == 1 && typeof(T) == elementType.MakeArrayType())
                {
                    interfaceType = typeof(ArrayInterface <>).MakeGenericType(elementType);
                }
                else
                {
                    interfaceType = typeof(MultiDimArrayInterface <,>).MakeGenericType(typeof(T), elementType);
                }

                return(Underlying.As <IValueInterface <T> >(Activator.CreateInstance(interfaceType)));
            }

            return(null);
        }
コード例 #14
0
        public static bool IsSpecialValue(float value)
        {
            const uint SpecialValue = 0x7F800000;

            return((Underlying.As <float, uint>(ref value) & SpecialValue) == SpecialValue);
        }
コード例 #15
0
        public static bool IsSpecialValue(double value)
        {
            const ulong SpecialValue = 0x7FF0000000000000;

            return((Underlying.As <double, ulong>(ref value) & SpecialValue) == SpecialValue);
        }
コード例 #16
0
        public static (ParseCode code, int length, Guid value) ParseGuid(char *chars, int length)
        {
            GuidStruct value = default;

            var offset = chars;

            if (length < 32)
            {
                goto Error;
            }

            if (*offset == '{')
            {
                ++offset;
                --length;
            }

            if (!TryParseHexByte(ref offset, ref value._a1))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._a2))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._a3))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._a4))
            {
                goto False;
            }


            if (*offset == '-')
            {
                ++offset;
                --length;
            }

            if (!TryParseHexByte(ref offset, ref value._b1))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._b2))
            {
                goto False;
            }

            if (*offset == '-')
            {
                ++offset;
                --length;
            }

            if (!TryParseHexByte(ref offset, ref value._c1))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._c2))
            {
                goto False;
            }

            if (*offset == '-')
            {
                ++offset;
                --length;
            }

            if (!TryParseHexByte(ref offset, ref value._d))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._e))
            {
                goto False;
            }

            if (*offset == '-')
            {
                ++offset;
                --length;
            }

            if (length < 32)
            {
                goto Error;
            }

            if (!TryParseHexByte(ref offset, ref value._f))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._g))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._h))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._i))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._j))
            {
                goto False;
            }
            if (!TryParseHexByte(ref offset, ref value._k))
            {
                goto False;
            }

            if (*offset == '}')
            {
                ++offset;
                --length;
            }

            return(ParseCode.Success, (int)(offset - chars), Underlying.As <GuidStruct, Guid>(ref value));

Error:
            return(ParseCode.WrongFormat, 0, default);
コード例 #17
0
 public static void StoreFieldValue <TValue>(object obj, TValue value, int offset)
 {
     Underlying.As <byte, TValue>(ref Underlying.Add(ref TypeHelper.Unbox <byte>(obj), offset)) = value;
 }
コード例 #18
0
 public void AppendD2(ref char chars, ulong value)
 {
     Underlying.As <char, int>(ref chars) = *(int *)(((char *)(threeDigitals + value)) + 1);;
 }
コード例 #19
0
 public static int GetScale(decimal value)
 {
     return(Underlying.As <decimal, DecimalStruct>(ref value).Scale);
 }
コード例 #20
0
 public void AppendD3(ref char chars, ulong value)
 {
     Underlying.As <char, long>(ref chars) = *(long *)(threeDigitals + value);
 }
コード例 #21
0
 public static void StoreStructFieldValue <TValue>(ref byte obj, TValue value, int offset)
 {
     Underlying.As <byte, TValue>(ref Underlying.Add(ref obj, offset)) = value;
 }
コード例 #22
0
 public static TValue LoadStructFieldValue <TValue>(ref byte obj, int offset)
 {
     return(Underlying.As <byte, TValue>(ref Underlying.Add(ref obj, offset)));
 }
コード例 #23
0
 /// <summary>
 /// 创建一个指定类型的委托。
 /// </summary>
 /// <typeparam name="T">委托类型</typeparam>
 /// <param name="methodInfo">需要创建委托的方法</param>
 /// <param name="throwExceptions">当参数或返回值类型不兼容时是否发生异常。</param>
 /// <returns>返回一个委托或 Null。</returns>
 public static T CreateDelegate <T>(MethodBase methodInfo, bool throwExceptions = true) where T : Delegate
 {
     return(Underlying.As <T>(CreateDelegate(typeof(T), methodInfo, throwExceptions)));
 }
コード例 #24
0
        public void FastIgnoreCaseTest()
        {
            var chars = stackalloc char[100];
            var bytes = stackalloc byte[100];

            var rw = FastObjectRW <IgnoreCaseTester> .Create();

            AreEqual(FastObjectRW <IgnoreCaseTester> .CurrentOptions & FastObjectRWOptions.IgnoreCase, FastObjectRWOptions.IgnoreCase);

            rw.Initialize();


            rw["name"].WriteString("low");

            AreEqual(rw["Name"].ReadString(), "low");

            rw["NAME"].WriteString("upp");

            AreEqual(rw["Name"].ReadString(), "upp");

            Catch <MissingMemberException>(() => rw["EMAN"].WriteString("err"));
            Catch <MissingMemberException>(() => rw["eman"].ReadString());
            Catch <MemberAccessException>(() => rw["READONLY"].WriteString("err"));
            rw["readonly"].ReadString();
            rw["WRITEONLY"].WriteString("err");
            Catch <MemberAccessException>(() => rw["writeonly"].ReadString());

            rw[ToUtf16s("name")].WriteString("low");

            AreEqual(rw[ToUtf16s("Name")].ReadString(), "low");

            rw[ToUtf16s("NAME")].WriteString("upp");

            AreEqual(rw[ToUtf16s("Name")].ReadString(), "upp");

            Catch <MissingMemberException>(() => rw[ToUtf16s("EMAN")].WriteString("err"));
            Catch <MissingMemberException>(() => rw[ToUtf16s("eman")].ReadString());
            Catch <MemberAccessException>(() => rw[ToUtf8s("READONLY")].WriteString("err"));
            rw[ToUtf8s("readonly")].ReadString();
            rw[ToUtf8s("WRITEONLY")].WriteString("err");
            Catch <MemberAccessException>(() => rw[ToUtf8s("writeonly")].ReadString());


            rw[ToUtf8s("name")].WriteString("low");

            AreEqual(rw[ToUtf8s("Name")].ReadString(), "low");

            rw[ToUtf8s("NAME")].WriteString("upp");

            AreEqual(rw[ToUtf8s("Name")].ReadString(), "upp");

            Catch <MissingMemberException>(() => rw[ToUtf8s("EMAN")].WriteString("err"));
            Catch <MissingMemberException>(() => rw[ToUtf8s("eman")].ReadString());
            Catch <MemberAccessException>(() => rw[ToUtf8s("READONLY")].WriteString("err"));
            rw[ToUtf8s("readonly")].ReadString();
            rw[ToUtf8s("WRITEONLY")].WriteString("err");
            Catch <MemberAccessException>(() => rw[ToUtf8s("writeonly")].ReadString());



            var nicrw = FastObjectRW <NoIgnoreCaseTester> .Create();

            AreEqual(FastObjectRW <NoIgnoreCaseTester> .CurrentOptions & FastObjectRWOptions.IgnoreCase, default(FastObjectRWOptions));

            nicrw.Initialize();

            nicrw["Name"].WriteString("ok");
            Catch <MissingMemberException>(() => nicrw["name"].WriteString("err"));
            Catch <MissingMemberException>(() => nicrw["NAME"].WriteString("err"));

            nicrw[ToUtf16s("Name")].WriteString("ok");
            Catch <MissingMemberException>(() => nicrw[ToUtf16s("name")].WriteString("err"));
            Catch <MissingMemberException>(() => nicrw[ToUtf16s("NAME")].WriteString("err"));

            nicrw[ToUtf8s("Name")].WriteString("ok");
            Catch <MissingMemberException>(() => nicrw[ToUtf8s("name")].WriteString("err"));
            Catch <MissingMemberException>(() => nicrw[ToUtf8s("NAME")].WriteString("err"));

            Ps <char> ToUtf16s(string str)
            {
                Underlying.CopyBlock(
                    ref Underlying.As <char, byte>(ref *chars),
                    ref Underlying.As <char, byte>(ref StringHelper.GetRawStringData(str)),
                    (uint)(str.Length * sizeof(char))
                    );

                return(new Ps <char>(chars, str.Length));
            }

            Ps <Utf8Byte> ToUtf8s(string str)
            {
                var length = StringHelper.GetUtf8Bytes(ref StringHelper.GetRawStringData(str), str.Length, bytes);

                return(new Ps <Utf8Byte>((Utf8Byte *)bytes, length));
            }
        }
コード例 #25
0
 /// <summary>
 /// 获取字段的值的引用。
 /// </summary>
 /// <param name="obj">对象的引用</param>
 /// <returns>返回字段的值的引用</returns>
 public ref TValue GetReference(ref TStruct obj)
 => ref Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset);
コード例 #26
0
ファイル: CloneHelper.cs プロジェクト: shunfy/Swifter.Json
 public static Array CloneArray(Array array)
 {
     return(Underlying.As <Array>(array.Clone()));
 }
コード例 #27
0
        /// <summary>
        /// 对枚举进行标识符格式化。
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="value">枚举值</param>
        /// <param name="chars">字符串</param>
        /// <param name="length">字符串长度</param>
        /// <param name="charsWritten">写入的字符串长度</param>
        /// <returns>返回剩余的枚举值</returns>
        public static unsafe T FormatEnumFlags <T>(T value, char *chars, int length, out int charsWritten) where T : struct, Enum
        {
            var result = AsUInt64(value);

            var items = EnumInterface <T> .Items;

            int offset = 0;

            var firstTime = true;

            // 得出格式化所需的字符串长度。
            for (int i = items.Length - 1; i >= 0; i--)
            {
                var(val, name) = items[i];

                if ((val & result) == val && val != 0)
                {
                    if (!firstTime)
                    {
                        offset += EnumSeperator.Length;
                    }

                    offset += name.Length;

                    result -= val;

                    if (result == 0)
                    {
                        break;
                    }

                    firstTime = false;
                }
            }

            if (offset <= length)
            {
                result = AsUInt64(value);

                charsWritten = offset;

                firstTime = true;

                for (int i = items.Length - 1; i >= 0; i--)
                {
                    var(val, name) = items[i];

                    if ((val & result) == val && val != 0)
                    {
                        if (!firstTime)
                        {
                            Insert(EnumSeperator);
                        }

                        Insert(name);

                        result -= val;

                        if (result == 0)
                        {
                            break;
                        }

                        firstTime = false;
                    }
                }

                return(AsEnum <T>(result));

                void Insert(string str)
                {
                    offset -= str.Length;

                    Underlying.CopyBlock(
                        ref Underlying.As <char, byte>(ref chars[offset]),
                        ref Underlying.As <char, byte>(ref StringHelper.GetRawStringData(str)),
                        (uint)(str.Length * sizeof(char))
                        );
                }
            }
            else
            {
                charsWritten = 0;

                return(value);
            }
        }
コード例 #28
0
 public static TValue LoadFieldValue <TValue>(object obj, int offset)
 {
     return(Underlying.As <byte, TValue>(ref Underlying.Add(ref TypeHelper.Unbox <byte>(obj), offset)));
 }
コード例 #29
0
        private protected override void InitializeByValue(PropertyInfo propertyInfo, XBindingFlags flags)
        {
            base.InitializeByValue(propertyInfo, flags);

            if ((flags & XBindingFlags.RWAutoPropertyDirectRW) != 0 /* || !VersionDifferences.IsSupportEmit */)
            {
                if (TypeHelper.IsAutoProperty(propertyInfo, out var fieldInfo) && fieldInfo != null)
                {
                    try
                    {
                        var offset = TypeHelper.OffsetOf(fieldInfo);

                        _get = (ref TStruct obj) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset);
                        _set = (ref TStruct obj, TValue value) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset) = value;

                        return;
                    }
                    catch
                    {
                    }
                }
            }

            if (_get is null)
            {
                var getMethod = propertyInfo.GetGetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (getMethod != null)
                {
                    var __get = MethodHelper.CreateDelegate <GetValueHandler>(getMethod);

                    _get = VersionDifferences.IsSupportEmit ? __get : AOTCheck;

                    TValue AOTCheck(ref TStruct obj)
                    {
                        try
                        {
                            return(__get(ref obj));
                        }
                        catch (ExecutionEngineException)
                        {
                            __get = AOT;

                            return(AOT(ref obj));
                        }
                        finally
                        {
                            _get = __get;
                        }
                    }

                    TValue AOT(ref TStruct obj)
                    {
                        fixed(byte *ptr = &Underlying.As <TStruct, byte>(ref obj))
                        {
                            return((TValue)getMethod.Invoke(TypeHelper.CamouflageBox(ptr), null));
                        }
                    }
                }
            }

            if (_set is null)
            {
                var setMethod = propertyInfo.GetSetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (setMethod != null)
                {
                    var __set = (SetValueHandler)Delegate.CreateDelegate(typeof(SetValueHandler), setMethod);

                    _set = VersionDifferences.IsSupportEmit ? __set : AOTCheck;

                    void AOTCheck(ref TStruct obj, TValue value)
                    {
                        try
                        {
                            __set(ref obj, value);
                        }
                        catch (ExecutionEngineException)
                        {
                            __set = AOT;

                            AOT(ref obj, value);
                        }
                        finally
                        {
                            _set = __set;
                        }
                    }

                    void AOT(ref TStruct obj, TValue value)
                    {
                        fixed(byte *ptr = &Underlying.As <TStruct, byte>(ref obj))
                        {
                            setMethod.Invoke(TypeHelper.CamouflageBox(ptr), new object[] { value });
                        }
                    }
                }
            }
        }
コード例 #30
0
        public void DecimalTest()
        {
            fixed(char *chars = &__("3.1415926535897", out var length))
            {
                Less(Math.Abs(NumberHelper.Decimal.ParseDouble(chars, length).value / 3.1415926535897 - 1), 0.00000000000001);
            }

            fixed(char *chars = &__(ulong.MaxValue.ToString(), out var length))
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(chars, length).value, ulong.MaxValue);
            }

            fixed(char *chars = &__(ulong.MinValue.ToString(), out var length))
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(chars, length).value, ulong.MinValue);
            }

            fixed(char *chars = &__(long.MaxValue.ToString(), out var length))
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(chars, length).value, long.MaxValue);
            }

            fixed(char *chars = &__(long.MinValue.ToString(), out var length))
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(chars, length).value, long.MinValue);
            }

            var str = stackalloc char[100];

            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(3.1415926535897, str)), "3.1415926535897");
            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(3.1415F, str)), "3.1415");

            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(ulong.MaxValue, str)), ulong.MaxValue.ToString());
            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(long.MaxValue, str)), long.MaxValue.ToString());
            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(ulong.MinValue, str)), ulong.MinValue.ToString());
            AreEqual(StringHelper.ToString(str, NumberHelper.Decimal.ToString(long.MinValue, str)), long.MinValue.ToString());

            for (long i = 0, value = 2; i < 1000; value *= 2, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (long i = 0, value = 10; i < 1000; value *= 10, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (long i = 0, value = 9; i < 1000; value *= 9, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (long i = 0, value = 7; i < 1000; value *= 7, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (ulong i = 0, value = 2; i < 1000; value *= 2, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (ulong i = 0, value = 10; i < 1000; value *= 10, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (ulong i = 0, value = 9; i < 1000; value *= 9, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (ulong i = 0, value = 7; i < 1000; value *= 7, i++)
            {
                AreEqual(NumberHelper.Decimal.ParseUInt64(str, NumberHelper.Decimal.ToString(value, str)).value, value);
            }

            for (ulong i = 0, value = 3; i < 1000; value *= 3, i++)
            {
                var dval = Underlying.As <ulong, double>(ref value);

                if (dval >= double.MinValue && dval <= double.MaxValue && Math.Abs(dval) > 1e-300)
                {
                    // AreAlmost(NumberHelper.Decimal.ParseDouble(str, NumberHelper.Decimal.ToString(dval, str)).value, dval);
                }
            }

            for (uint i = 0, value = 3; i < 1000; value *= 3, i++)
            {
                var fval = Underlying.As <uint, float>(ref value);

                if (fval >= float.MinValue && fval <= float.MaxValue && Math.Abs(fval) > 1e-30)
                {
                    // AreAlmost((float)NumberHelper.Decimal.ParseDouble(str, NumberHelper.Decimal.ToString(fval, str)).value, fval);
                }
            }
        }