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); }
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); }
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)); }
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; }
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); }
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)); }
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); } }
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)); } }
/// <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 ); }
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); } } }
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); }
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);
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); }
public static bool IsSpecialValue(float value) { const uint SpecialValue = 0x7F800000; return((Underlying.As <float, uint>(ref value) & SpecialValue) == SpecialValue); }
public static bool IsSpecialValue(double value) { const ulong SpecialValue = 0x7FF0000000000000; return((Underlying.As <double, ulong>(ref value) & SpecialValue) == SpecialValue); }
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);
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; }
public void AppendD2(ref char chars, ulong value) { Underlying.As <char, int>(ref chars) = *(int *)(((char *)(threeDigitals + value)) + 1);; }
public static int GetScale(decimal value) { return(Underlying.As <decimal, DecimalStruct>(ref value).Scale); }
public void AppendD3(ref char chars, ulong value) { Underlying.As <char, long>(ref chars) = *(long *)(threeDigitals + value); }
public static void StoreStructFieldValue <TValue>(ref byte obj, TValue value, int offset) { Underlying.As <byte, TValue>(ref Underlying.Add(ref obj, offset)) = value; }
public static TValue LoadStructFieldValue <TValue>(ref byte obj, int offset) { return(Underlying.As <byte, TValue>(ref Underlying.Add(ref obj, offset))); }
/// <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))); }
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)); } }
/// <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);
public static Array CloneArray(Array array) { return(Underlying.As <Array>(array.Clone())); }
/// <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); } }
public static TValue LoadFieldValue <TValue>(object obj, int offset) { return(Underlying.As <byte, TValue>(ref Underlying.Add(ref TypeHelper.Unbox <byte>(obj), offset))); }
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 }); } } } } }
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); } } }