2using System.Globalization;
10 public static class Comparison
20 Type xType = x.GetType();
21 Type yType = y.GetType();
25 if (x is DateTime TPx &&
27 TPx.Kind != TPy.Kind &&
28 TPx.Kind != DateTimeKind.Unspecified &&
29 TPy.Kind != DateTimeKind.Unspecified)
31 x = TPx.ToLocalTime();
32 y = TPy.ToLocalTime();
41 Upgrade(ref x, ref xTypeCode);
42 Upgrade(ref y, ref yTypeCode);
44 if (xTypeCode == yTypeCode)
59 x = ToString(x, xTypeCode);
68 y = (decimal)((
double)y);
77 x = (decimal)((
double)x);
84 y = ToString(y, yTypeCode);
92 internal static string ToString(
object Value)
100 internal static string ToString(
object Value, uint TypeCode)
108 return ((
double)Value).ToString(CultureInfo.InvariantCulture);
111 return ((decimal)Value).ToString(CultureInfo.InvariantCulture);
114 return ((DateTime)Value).ToUniversalTime().ToString(
"yyyy-MM-ddTHH:mm:ss") +
"z";
117 return ((DateTimeOffset)Value).ToUniversalTime().DateTime.ToString(
"yyyy-MM-ddTHH:mm:ss") +
"z";
120 return Convert.ToBase64String((
byte[])Value);
123 return Value?.ToString() ??
string.Empty;
127 private static void Upgrade(ref
object Value, ref uint TypeCode)
132 Value = (decimal)(((
bool)Value) ? 1 : 0);
137 Value = (decimal)((
byte)Value);
143 Value = (decimal)((
short)Value);
149 Value = (decimal)((
int)Value);
155 Value = (decimal)((
long)Value);
160 Value = (decimal)((sbyte)Value);
166 Value = (decimal)((ushort)Value);
172 Value = (decimal)((uint)Value);
178 Value = (decimal)((ulong)Value);
189 Value = (double)((
float)Value);
194 Value = ((DateTime)Value).ToUniversalTime();
198 Value = ((DateTimeOffset)Value).ToUniversalTime().DateTime;
205 Value = (decimal)((
char)Value);
215 Value = Value.ToString();
231 public static int?
Compare(
object Value1,
object Value2)
233 bool IsNull1 = Value1 is
null;
234 bool IsNull2 = Value2 is
null;
236 if (IsNull1 ^ IsNull2)
249 if (Value1 is IComparable Comparable)
250 return Comparable.CompareTo(Value2);
251 else if (Value1 is
byte[] b1 && Value2 is
byte[] b2)
252 return Storage.IndexRecords.BinaryCompare(b1, b2);
267 Type T = Value.GetType();
281 byte b = (byte)Value;
282 if (b ==
byte.MaxValue)
283 Value = (ushort)(
byte.MaxValue + 1);
293 short i16 = (short)Value;
294 if (i16 ==
short.MaxValue)
295 Value = short.MaxValue + 1;
305 int i32 = (int)Value;
306 if (i32 ==
int.MaxValue)
307 Value = (long)
int.MaxValue + 1;
317 long i64 = (long)Value;
318 if (i64 ==
long.MaxValue)
319 Value = (ulong)
long.MaxValue + 1;
328 sbyte i8 = (sbyte)Value;
329 if (i8 == sbyte.MaxValue)
330 Value = (short)sbyte.MaxValue + 1;
340 ushort ui16 = (ushort)Value;
341 if (ui16 == ushort.MaxValue)
342 Value = (uint)ushort.MaxValue + 1;
352 uint ui32 = (uint)Value;
353 if (ui32 == uint.MaxValue)
354 Value = (ulong)uint.MaxValue + 1;
364 ulong ui64 = (ulong)Value;
365 if (ui64 == ulong.MaxValue)
367 double d = ulong.MaxValue;
368 if (Increment(ref d))
384 decimal dec = (decimal)Value;
385 if (!Increment(ref dec))
394 double dbl = (double)Value;
395 if (!Increment(ref dbl))
404 float sng = (float)Value;
405 if (!Increment(ref sng))
414 DateTime DT = (DateTime)Value;
415 if (DT.Ticks ==
long.MaxValue)
419 Value =
new DateTime(DT.Ticks + 1, DT.Kind);
424 DateTimeOffset DTO = (DateTimeOffset)Value;
425 if (DTO.Ticks ==
long.MaxValue)
429 Value =
new DateTimeOffset(DTO.Ticks + 1, DTO.Offset);
434 TimeSpan TS = (TimeSpan)Value;
435 if (TS.Ticks ==
long.MaxValue)
439 Value =
new TimeSpan(TS.Ticks + 1);
444 char ch = (char)Value;
445 if (ch ==
char.MaxValue)
446 Value = char.MaxValue + 1;
448 Value = (char)(ch + 1);
452 string s = (string)Value;
453 if (Increment(ref s))
464 if (Increment(ref s))
473 s = Value.ToString();
474 if (Increment(ref s))
483 Guid Guid = (Guid)Value;
484 if (Increment(ref Guid))
493 byte[] Bin = (
byte[])((
byte[])Value).Clone();
522 Value =
double.Epsilon;
526 double Eps = Value / Math.Pow(2, 51);
530 while (Value != (Diff = (Value + Eps)))
554 Value =
float.Epsilon;
558 float Eps = Value / (float)Math.Pow(2, 21);
562 while (Value != (Diff = (Value + Eps)))
586 Value = DecimalEpsilon;
590 decimal Eps = Value / (decimal)Math.Pow(2, 92);
592 decimal Last = Value;
594 while (Value != (Diff = (Value + Eps)))
612 public static readonly decimal DecimalEpsilon =
new decimal(1, 0, 0,
false, 28);
632 string s = Value.Value;
645 byte[] A = Value.ToByteArray();
725 Type T = Value.GetType();
739 byte b = (byte)Value;
740 if (b ==
byte.MinValue)
751 short i16 = (short)Value;
752 if (i16 ==
short.MinValue)
753 Value = short.MinValue - 1;
763 int i32 = (int)Value;
764 if (i32 ==
int.MinValue)
765 Value = (long)
int.MinValue - 1;
775 long i64 = (long)Value;
776 if (i64 ==
long.MinValue)
778 double d =
long.MinValue;
779 if (Decrement(ref d))
795 sbyte i8 = (sbyte)Value;
796 if (i8 == sbyte.MinValue)
797 Value = (short)sbyte.MinValue - 1;
807 ushort ui16 = (ushort)Value;
808 if (ui16 == ushort.MinValue)
809 Value = (short)ushort.MinValue - 1;
819 uint ui32 = (uint)Value;
820 if (ui32 == uint.MinValue)
821 Value = (int)uint.MinValue - 1;
831 ulong ui64 = (ulong)Value;
832 if (ui64 == ulong.MinValue)
833 Value = (long)ulong.MinValue - 1;
842 decimal dec = (decimal)Value;
843 if (!Decrement(ref dec))
852 double dbl = (double)Value;
853 if (!Decrement(ref dbl))
862 float sng = (float)Value;
863 if (!Decrement(ref sng))
872 DateTime DT = (DateTime)Value;
873 if (DT.Ticks ==
long.MinValue)
877 Value =
new DateTime(DT.Ticks - 1, DT.Kind);
882 DateTimeOffset DTO = (DateTimeOffset)Value;
883 if (DTO.Ticks ==
long.MinValue)
887 Value =
new DateTimeOffset(DTO.Ticks - 1, DTO.Offset);
892 TimeSpan TS = (TimeSpan)Value;
893 if (TS.Ticks ==
long.MinValue)
897 Value =
new TimeSpan(TS.Ticks - 1);
902 char ch = (char)Value;
903 if (ch ==
char.MinValue)
904 Value = char.MinValue - 1;
906 Value = (char)(ch - 1);
911 string s = (string)Value;
912 if (Decrement(ref s))
923 if (Decrement(ref s))
932 s = Value.ToString();
933 if (Decrement(ref s))
942 Guid Guid = (Guid)Value;
943 if (!Decrement(ref Guid))
952 byte[] Bin = (
byte[])((
byte[])Value).Clone();
981 Value = -
double.Epsilon;
985 double Eps = Value / Math.Pow(2, 51);
989 while (Value != (Diff = (Value + Eps)))
1013 Value = -
float.Epsilon;
1017 float Eps = Value / (float)Math.Pow(2, 21);
1021 while (Value != (Diff = (Value + Eps)))
1045 Value = -DecimalEpsilon;
1049 decimal Eps = Value / (decimal)Math.Pow(2, 92);
1051 decimal Last = Value;
1053 while (Value != (Diff = (Value + Eps)))
1075 if (
string.IsNullOrEmpty(Value))
1078 int c = Value.Length;
1079 char ch = Value[c - 1];
1082 Value = Value.Substring(0, c - 1);
1084 Value = Value.Substring(0, c - 1) + ((char)(ch - 1)) +
char.MaxValue;
1096 string s = Value.Value;
1097 if (!Decrement(ref s))
1111 byte[] A = Value.ToByteArray();
1177 Value =
new Guid(A);
Represents a case-insensitive string.
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
static bool Decrement(ref object Value)
Decrements Value to the largest value smaller than Value .
static bool Decrement(ref CaseInsensitiveString Value)
Decrements Value to the largest value smaller than Value .
static bool Decrement(ref float Value)
Decrements Value to the largest value smaller than Value .
static ? int Compare(object Value1, object Value2)
Compares two values. The values can be of different, but compatible types.
static bool Increment(ref CaseInsensitiveString Value)
Increments Value to the smallest value greater than Value .
static bool Increment(ref string Value)
Increments Value to the smallest value greater than Value .
static bool Decrement(ref Guid Value)
Decrements Value to the largest value smaller than Value .
static bool Decrement(ref double Value)
Decrements Value to the largest value smaller than Value .
static bool TryMakeSameType(ref object x, ref object y)
Tries to make sure x and y have the same type.
static bool Increment(ref object Value)
Increments Value to the smallest value greater than Value .
static bool Increment(ref float Value)
Increments Value to the smallest value greater than Value .
static bool Decrement(ref decimal Value)
Decrements Value to the largest value smaller than Value .
static bool Increment(ref Guid Value)
Increments Value to the smallest value greater than Value .
static bool Decrement(ref string Value)
Decrements Value to the largest value smaller than Value .
static bool Increment(ref double Value)
Increments Value to the smallest value greater than Value .
static bool Increment(ref decimal Value)
Increments Value to the smallest value greater than Value .
Serializes a class, taking into account attributes defined in Attributes.
const uint TYPE_DECIMAL
Represents a Decimal
const uint TYPE_TIMESPAN
Represents a TimeSpan
const uint TYPE_UINT64
Represents a UInt64
const uint TYPE_NULL
Represents a null value.
const uint TYPE_SBYTE
Represents a SByte
const uint TYPE_VARINT64
Variable length INT64
const uint TYPE_INT64
Represents a Int64
const uint TYPE_BOOLEAN
Represents a Boolean
const uint TYPE_BYTE
Represents a Byte
const uint TYPE_CHAR
Represents a Char
const uint TYPE_VARUINT32
Variable length UINT32
const uint TYPE_VARINT16
Variable length INT16
const uint TYPE_STRING
Represents a String
static uint GetFieldDataTypeCode(object Value)
Returns the type code corresponding to a given field data type.
const uint TYPE_UINT16
Represents a UInt16
const uint TYPE_CI_STRING
Represents a CaseInsensitiveString
const uint TYPE_SINGLE
Represents a Single
const uint TYPE_DATETIMEOFFSET
Represents a DateTimeOffset
const uint TYPE_VARUINT16
Variable length UINT16
const uint TYPE_BYTEARRAY
Represents a byte array.
const uint TYPE_VARUINT64
Variable length UINT64
const uint TYPE_INT32
Represents a Int32
const uint TYPE_UINT32
Represents a UInt32
const uint TYPE_DATETIME
Represents a DateTime
const uint TYPE_VARINT32
Variable length INT32
const uint TYPE_GUID
Represents a Guid
const uint TYPE_ENUM
Represents an enumerated value.
const uint TYPE_DOUBLE
Represents a Double
const uint TYPE_INT16
Represents a Int16