Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Comparison.cs
1using System;
2using System.Globalization;
4
6{
10 public static class Comparison
11 {
18 public static bool TryMakeSameType(ref object x, ref object y)
19 {
20 Type xType = x.GetType();
21 Type yType = y.GetType();
22
23 if (xType == yType)
24 {
25 if (x is DateTime TPx &&
26 y is DateTime TPy &&
27 TPx.Kind != TPy.Kind &&
28 TPx.Kind != DateTimeKind.Unspecified &&
29 TPy.Kind != DateTimeKind.Unspecified)
30 {
31 x = TPx.ToLocalTime();
32 y = TPy.ToLocalTime();
33 }
34
35 return true;
36 }
37
38 uint xTypeCode = ObjectSerializer.GetFieldDataTypeCode(xType);
39 uint yTypeCode = ObjectSerializer.GetFieldDataTypeCode(yType);
40
41 Upgrade(ref x, ref xTypeCode);
42 Upgrade(ref y, ref yTypeCode);
43
44 if (xTypeCode == yTypeCode)
45 return true;
46
47 if (xTypeCode == ObjectSerializer.TYPE_CI_STRING)
48 {
49 y = (CaseInsensitiveString)ToString(y, yTypeCode);
50 return true;
51 }
52 else if (yTypeCode == ObjectSerializer.TYPE_CI_STRING)
53 {
54 x = (CaseInsensitiveString)ToString(x, xTypeCode);
55 return true;
56 }
57 else if (yTypeCode == ObjectSerializer.TYPE_STRING)
58 {
59 x = ToString(x, xTypeCode);
60 return true;
61 }
62
63 switch (xTypeCode)
64 {
66 if (yTypeCode == ObjectSerializer.TYPE_DOUBLE)
67 {
68 y = (decimal)((double)y);
69 return true;
70 }
71 else
72 return false;
73
75 if (yTypeCode == ObjectSerializer.TYPE_DECIMAL)
76 {
77 x = (decimal)((double)x);
78 return true;
79 }
80 else
81 return false;
82
84 y = ToString(y, yTypeCode);
85 return true;
86
87 default:
88 return false;
89 }
90 }
91
92 internal static string ToString(object Value)
93 {
94 if (Value is null)
95 return string.Empty;
96 else
97 return ToString(Value, ObjectSerializer.GetFieldDataTypeCode(Value.GetType()));
98 }
99
100 internal static string ToString(object Value, uint TypeCode)
101 {
102 switch (TypeCode)
103 {
105 return string.Empty;
106
108 return ((double)Value).ToString(CultureInfo.InvariantCulture);
109
111 return ((decimal)Value).ToString(CultureInfo.InvariantCulture);
112
114 return ((DateTime)Value).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") + "z";
115
117 return ((DateTimeOffset)Value).ToUniversalTime().DateTime.ToString("yyyy-MM-ddTHH:mm:ss") + "z";
118
120 return Convert.ToBase64String((byte[])Value);
121
122 default:
123 return Value?.ToString() ?? string.Empty;
124 }
125 }
126
127 private static void Upgrade(ref object Value, ref uint TypeCode)
128 {
129 switch (TypeCode)
130 {
132 Value = (decimal)(((bool)Value) ? 1 : 0);
134 break;
135
137 Value = (decimal)((byte)Value);
139 break;
140
143 Value = (decimal)((short)Value);
145 break;
146
149 Value = (decimal)((int)Value);
151 break;
152
155 Value = (decimal)((long)Value);
157 break;
158
160 Value = (decimal)((sbyte)Value);
162 break;
163
166 Value = (decimal)((ushort)Value);
168 break;
169
172 Value = (decimal)((uint)Value);
174 break;
175
178 Value = (decimal)((ulong)Value);
180 break;
181
183 break;
184
186 break;
187
189 Value = (double)((float)Value);
190 TypeCode = ObjectSerializer.TYPE_DOUBLE;
191 break;
192
194 Value = ((DateTime)Value).ToUniversalTime();
195 break;
196
198 Value = ((DateTimeOffset)Value).ToUniversalTime().DateTime;
199 break;
200
202 break;
203
205 Value = (decimal)((char)Value);
207 break;
208
211 break;
212
215 Value = Value.ToString();
216 TypeCode = ObjectSerializer.TYPE_STRING;
217 break;
218 }
219 }
220
231 public static int? Compare(object Value1, object Value2)
232 {
233 bool IsNull1 = Value1 is null;
234 bool IsNull2 = Value2 is null;
235
236 if (IsNull1 ^ IsNull2)
237 {
238 if (IsNull1)
239 return -1;
240 else
241 return 1;
242 }
243 else if (IsNull1)
244 return 0;
245
246 if (!TryMakeSameType(ref Value1, ref Value2))
247 return null;
248
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);
253 else
254 return null;
255 }
256
262 public static bool Increment(ref object Value)
263 {
264 if (Value is null)
265 return false;
266
267 Type T = Value.GetType();
268 uint TypeCode = ObjectSerializer.GetFieldDataTypeCode(T);
269
270 switch (TypeCode)
271 {
273 if ((bool)Value)
274 Value = (byte)2;
275 else
276 Value = true;
277
278 return true;
279
281 byte b = (byte)Value;
282 if (b == byte.MaxValue)
283 Value = (ushort)(byte.MaxValue + 1);
284 else
285 {
286 b++;
287 Value = b;
288 }
289 return true;
290
293 short i16 = (short)Value;
294 if (i16 == short.MaxValue)
295 Value = short.MaxValue + 1;
296 else
297 {
298 i16++;
299 Value = i16;
300 }
301 return true;
302
305 int i32 = (int)Value;
306 if (i32 == int.MaxValue)
307 Value = (long)int.MaxValue + 1;
308 else
309 {
310 i32++;
311 Value = i32;
312 }
313 return true;
314
317 long i64 = (long)Value;
318 if (i64 == long.MaxValue)
319 Value = (ulong)long.MaxValue + 1;
320 else
321 {
322 i64++;
323 Value = i64;
324 }
325 return true;
326
328 sbyte i8 = (sbyte)Value;
329 if (i8 == sbyte.MaxValue)
330 Value = (short)sbyte.MaxValue + 1;
331 else
332 {
333 i8++;
334 Value = i8;
335 }
336 return true;
337
340 ushort ui16 = (ushort)Value;
341 if (ui16 == ushort.MaxValue)
342 Value = (uint)ushort.MaxValue + 1;
343 else
344 {
345 ui16++;
346 Value = ui16;
347 }
348 return true;
349
352 uint ui32 = (uint)Value;
353 if (ui32 == uint.MaxValue)
354 Value = (ulong)uint.MaxValue + 1;
355 else
356 {
357 ui32++;
358 Value = ui32;
359 }
360 return true;
361
364 ulong ui64 = (ulong)Value;
365 if (ui64 == ulong.MaxValue)
366 {
367 double d = ulong.MaxValue;
368 if (Increment(ref d))
369 {
370 Value = d;
371 return true;
372 }
373 else
374 return false;
375 }
376 else
377 {
378 ui64++;
379 Value = ui64;
380 }
381 return true;
382
384 decimal dec = (decimal)Value;
385 if (!Increment(ref dec))
386 return false;
387 else
388 {
389 Value = dec;
390 return true;
391 }
392
394 double dbl = (double)Value;
395 if (!Increment(ref dbl))
396 return false;
397 else
398 {
399 Value = dbl;
400 return true;
401 }
402
404 float sng = (float)Value;
405 if (!Increment(ref sng))
406 return false;
407 else
408 {
409 Value = sng;
410 return true;
411 }
412
414 DateTime DT = (DateTime)Value;
415 if (DT.Ticks == long.MaxValue)
416 return false;
417 else
418 {
419 Value = new DateTime(DT.Ticks + 1, DT.Kind);
420 return true;
421 }
422
424 DateTimeOffset DTO = (DateTimeOffset)Value;
425 if (DTO.Ticks == long.MaxValue)
426 return false;
427 else
428 {
429 Value = new DateTimeOffset(DTO.Ticks + 1, DTO.Offset);
430 return true;
431 }
432
434 TimeSpan TS = (TimeSpan)Value;
435 if (TS.Ticks == long.MaxValue)
436 return false;
437 else
438 {
439 Value = new TimeSpan(TS.Ticks + 1);
440 return true;
441 }
442
444 char ch = (char)Value;
445 if (ch == char.MaxValue)
446 Value = char.MaxValue + 1;
447 else
448 Value = (char)(ch + 1);
449 return true;
450
452 string s = (string)Value;
453 if (Increment(ref s))
454 {
455 Value = s;
456 return true;
457 }
458 else
459 return false;
460
463 s = s2.Value;
464 if (Increment(ref s))
465 {
466 Value = (CaseInsensitiveString)s;
467 return true;
468 }
469 else
470 return false;
471
473 s = Value.ToString();
474 if (Increment(ref s))
475 {
476 Value = s;
477 return true;
478 }
479 else
480 return false;
481
483 Guid Guid = (Guid)Value;
484 if (Increment(ref Guid))
485 {
486 Value = Guid;
487 return true;
488 }
489 else
490 return false;
491
493 byte[] Bin = (byte[])((byte[])Value).Clone();
494 int c = Bin.Length;
495
496 while (--c >= 0)
497 {
498 b = ++Bin[c];
499 if (b != 0)
500 {
501 Value = Bin;
502 return true;
503 }
504 }
505
506 return false;
507
508 default:
509 return false;
510 }
511 }
512
518 public static bool Increment(ref double Value)
519 {
520 if (Value == 0)
521 {
522 Value = double.Epsilon;
523 return true;
524 }
525
526 double Eps = Value / Math.Pow(2, 51);
527 double Diff;
528 double Last = Value;
529
530 while (Value != (Diff = (Value + Eps)))
531 {
532 Last = Diff;
533 Eps /= 2;
534 }
535
536 if (Value != Last)
537 {
538 Value = Last;
539 return true;
540 }
541 else
542 return false;
543 }
544
550 public static bool Increment(ref float Value)
551 {
552 if (Value == 0)
553 {
554 Value = float.Epsilon;
555 return true;
556 }
557
558 float Eps = Value / (float)Math.Pow(2, 21);
559 float Diff;
560 float Last = Value;
561
562 while (Value != (Diff = (Value + Eps)))
563 {
564 Last = Diff;
565 Eps /= 2;
566 }
567
568 if (Value != Last)
569 {
570 Value = Last;
571 return true;
572 }
573 else
574 return false;
575 }
576
582 public static bool Increment(ref decimal Value)
583 {
584 if (Value == 0)
585 {
586 Value = DecimalEpsilon;
587 return true;
588 }
589
590 decimal Eps = Value / (decimal)Math.Pow(2, 92);
591 decimal Diff;
592 decimal Last = Value;
593
594 while (Value != (Diff = (Value + Eps)))
595 {
596 Last = Diff;
597 Eps /= 2;
598 }
599
600 if (Value != Last)
601 {
602 Value = Last;
603 return true;
604 }
605 else
606 return false;
607 }
608
612 public static readonly decimal DecimalEpsilon = new decimal(1, 0, 0, false, 28);
613
619 public static bool Increment(ref string Value)
620 {
621 Value += "\x00";
622 return true;
623 }
624
630 public static bool Increment(ref CaseInsensitiveString Value)
631 {
632 string s = Value.Value;
633 Increment(ref s);
634 Value = (CaseInsensitiveString)s;
635 return true;
636 }
637
643 public static bool Increment(ref Guid Value)
644 {
645 byte[] A = Value.ToByteArray();
646
647 A[15]++;
648 if (A[15] == 0)
649 {
650 A[14]++;
651 if (A[14] == 0)
652 {
653 A[13]++;
654 if (A[13] == 0)
655 {
656 A[12]++;
657 if (A[12] == 0)
658 {
659 A[11]++;
660 if (A[11] == 0)
661 {
662 A[10]++;
663 if (A[10] == 0)
664 {
665 A[9]++;
666 if (A[9] == 0)
667 {
668 A[8]++;
669 if (A[8] == 0)
670 {
671 A[6]++;
672 if (A[6] == 0)
673 {
674 A[7]++;
675 if (A[7] == 0)
676 {
677 A[4]++;
678 if (A[4] == 0)
679 {
680 A[5]++;
681 if (A[5] == 0)
682 {
683 A[0]++;
684 if (A[0] == 0)
685 {
686 A[1]++;
687 if (A[1] == 0)
688 {
689 A[2]++;
690 if (A[2] == 0)
691 {
692 A[3]++;
693 if (A[3] == 0)
694 return false;
695 }
696 }
697 }
698 }
699 }
700 }
701 }
702 }
703 }
704 }
705 }
706 }
707 }
708 }
709 }
710
711 Value = new Guid(A);
712 return true;
713 }
714
720 public static bool Decrement(ref object Value)
721 {
722 if (Value is null)
723 return false;
724
725 Type T = Value.GetType();
726 uint TypeCode = ObjectSerializer.GetFieldDataTypeCode(T);
727
728 switch (TypeCode)
729 {
731 if (!(bool)Value)
732 Value = (sbyte)-1;
733 else
734 Value = false;
735
736 return true;
737
739 byte b = (byte)Value;
740 if (b == byte.MinValue)
741 Value = (sbyte)-1;
742 else
743 {
744 b--;
745 Value = b;
746 }
747 return true;
748
751 short i16 = (short)Value;
752 if (i16 == short.MinValue)
753 Value = short.MinValue - 1;
754 else
755 {
756 i16--;
757 Value = i16;
758 }
759 return true;
760
763 int i32 = (int)Value;
764 if (i32 == int.MinValue)
765 Value = (long)int.MinValue - 1;
766 else
767 {
768 i32--;
769 Value = i32;
770 }
771 return true;
772
775 long i64 = (long)Value;
776 if (i64 == long.MinValue)
777 {
778 double d = long.MinValue;
779 if (Decrement(ref d))
780 {
781 Value = d;
782 return true;
783 }
784 else
785 return false;
786 }
787 else
788 {
789 i64--;
790 Value = i64;
791 }
792 return true;
793
795 sbyte i8 = (sbyte)Value;
796 if (i8 == sbyte.MinValue)
797 Value = (short)sbyte.MinValue - 1;
798 else
799 {
800 i8--;
801 Value = i8;
802 }
803 return true;
804
807 ushort ui16 = (ushort)Value;
808 if (ui16 == ushort.MinValue)
809 Value = (short)ushort.MinValue - 1;
810 else
811 {
812 ui16--;
813 Value = ui16;
814 }
815 return true;
816
819 uint ui32 = (uint)Value;
820 if (ui32 == uint.MinValue)
821 Value = (int)uint.MinValue - 1;
822 else
823 {
824 ui32--;
825 Value = ui32;
826 }
827 return true;
828
831 ulong ui64 = (ulong)Value;
832 if (ui64 == ulong.MinValue)
833 Value = (long)ulong.MinValue - 1;
834 else
835 {
836 ui64--;
837 Value = ui64;
838 }
839 return true;
840
842 decimal dec = (decimal)Value;
843 if (!Decrement(ref dec))
844 return false;
845 else
846 {
847 Value = dec;
848 return true;
849 }
850
852 double dbl = (double)Value;
853 if (!Decrement(ref dbl))
854 return false;
855 else
856 {
857 Value = dbl;
858 return true;
859 }
860
862 float sng = (float)Value;
863 if (!Decrement(ref sng))
864 return false;
865 else
866 {
867 Value = sng;
868 return true;
869 }
870
872 DateTime DT = (DateTime)Value;
873 if (DT.Ticks == long.MinValue)
874 return false;
875 else
876 {
877 Value = new DateTime(DT.Ticks - 1, DT.Kind);
878 return true;
879 }
880
882 DateTimeOffset DTO = (DateTimeOffset)Value;
883 if (DTO.Ticks == long.MinValue)
884 return false;
885 else
886 {
887 Value = new DateTimeOffset(DTO.Ticks - 1, DTO.Offset);
888 return true;
889 }
890
892 TimeSpan TS = (TimeSpan)Value;
893 if (TS.Ticks == long.MinValue)
894 return false;
895 else
896 {
897 Value = new TimeSpan(TS.Ticks - 1);
898 return true;
899 }
900
902 char ch = (char)Value;
903 if (ch == char.MinValue)
904 Value = char.MinValue - 1;
905 else
906 Value = (char)(ch - 1);
907
908 return true;
909
911 string s = (string)Value;
912 if (Decrement(ref s))
913 {
914 Value = s;
915 return true;
916 }
917 else
918 return false;
919
922 s = s2.Value;
923 if (Decrement(ref s))
924 {
925 Value = (CaseInsensitiveString)s;
926 return true;
927 }
928 else
929 return false;
930
932 s = Value.ToString();
933 if (Decrement(ref s))
934 {
935 Value = s;
936 return true;
937 }
938 else
939 return false;
940
942 Guid Guid = (Guid)Value;
943 if (!Decrement(ref Guid))
944 return false;
945 else
946 {
947 Value = Guid;
948 return true;
949 }
950
952 byte[] Bin = (byte[])((byte[])Value).Clone();
953 int c = Bin.Length;
954
955 while (--c >= 0)
956 {
957 b = --Bin[c];
958 if (b != 0xff)
959 {
960 Value = Bin;
961 return true;
962 }
963 }
964
965 return false;
966
967 default:
968 return false;
969 }
970 }
971
977 public static bool Decrement(ref double Value)
978 {
979 if (Value == 0)
980 {
981 Value = -double.Epsilon;
982 return true;
983 }
984
985 double Eps = Value / Math.Pow(2, 51);
986 double Diff;
987 double Last = Value;
988
989 while (Value != (Diff = (Value + Eps)))
990 {
991 Last = Diff;
992 Eps /= 2;
993 }
994
995 if (Value != Last)
996 {
997 Value = Last;
998 return true;
999 }
1000 else
1001 return false;
1002 }
1003
1009 public static bool Decrement(ref float Value)
1010 {
1011 if (Value == 0)
1012 {
1013 Value = -float.Epsilon;
1014 return true;
1015 }
1016
1017 float Eps = Value / (float)Math.Pow(2, 21);
1018 float Diff;
1019 float Last = Value;
1020
1021 while (Value != (Diff = (Value + Eps)))
1022 {
1023 Last = Diff;
1024 Eps /= 2;
1025 }
1026
1027 if (Value != Last)
1028 {
1029 Value = Last;
1030 return true;
1031 }
1032 else
1033 return false;
1034 }
1035
1041 public static bool Decrement(ref decimal Value)
1042 {
1043 if (Value == 0)
1044 {
1045 Value = -DecimalEpsilon;
1046 return true;
1047 }
1048
1049 decimal Eps = Value / (decimal)Math.Pow(2, 92);
1050 decimal Diff;
1051 decimal Last = Value;
1052
1053 while (Value != (Diff = (Value + Eps)))
1054 {
1055 Last = Diff;
1056 Eps /= 2;
1057 }
1058
1059 if (Value != Last)
1060 {
1061 Value = Last;
1062 return true;
1063 }
1064 else
1065 return false;
1066 }
1067
1073 public static bool Decrement(ref string Value)
1074 {
1075 if (string.IsNullOrEmpty(Value))
1076 return false;
1077
1078 int c = Value.Length;
1079 char ch = Value[c - 1];
1080
1081 if (ch == 0)
1082 Value = Value.Substring(0, c - 1);
1083 else
1084 Value = Value.Substring(0, c - 1) + ((char)(ch - 1)) + char.MaxValue;
1085
1086 return true;
1087 }
1088
1094 public static bool Decrement(ref CaseInsensitiveString Value)
1095 {
1096 string s = Value.Value;
1097 if (!Decrement(ref s))
1098 return false;
1099
1100 Value = (CaseInsensitiveString)s;
1101 return true;
1102 }
1103
1109 public static bool Decrement(ref Guid Value)
1110 {
1111 byte[] A = Value.ToByteArray();
1112
1113 A[15]--;
1114 if (A[15] == 0xff)
1115 {
1116 A[14]--;
1117 if (A[14] == 0xff)
1118 {
1119 A[13]--;
1120 if (A[13] == 0xff)
1121 {
1122 A[12]--;
1123 if (A[12] == 0xff)
1124 {
1125 A[11]--;
1126 if (A[11] == 0xff)
1127 {
1128 A[10]--;
1129 if (A[10] == 0xff)
1130 {
1131 A[9]--;
1132 if (A[9] == 0xff)
1133 {
1134 A[8]--;
1135 if (A[8] == 0xff)
1136 {
1137 A[6]--;
1138 if (A[6] == 0xff)
1139 {
1140 A[7]--;
1141 if (A[7] == 0xff)
1142 {
1143 A[4]--;
1144 if (A[4] == 0xff)
1145 {
1146 A[5]--;
1147 if (A[5] == 0xff)
1148 {
1149 A[0]--;
1150 if (A[0] == 0xff)
1151 {
1152 A[1]--;
1153 if (A[1] == 0xff)
1154 {
1155 A[2]--;
1156 if (A[2] == 0xff)
1157 {
1158 A[3]--;
1159 if (A[3] == 0xff)
1160 return false;
1161 }
1162 }
1163 }
1164 }
1165 }
1166 }
1167 }
1168 }
1169 }
1170 }
1171 }
1172 }
1173 }
1174 }
1175 }
1176
1177 Value = new Guid(A);
1178 return true;
1179 }
1180
1181 }
1182}
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 .
Definition: Comparison.cs:720
static bool Decrement(ref CaseInsensitiveString Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:1094
static bool Decrement(ref float Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:1009
static ? int Compare(object Value1, object Value2)
Compares two values. The values can be of different, but compatible types.
Definition: Comparison.cs:231
static bool Increment(ref CaseInsensitiveString Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:630
static bool Increment(ref string Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:619
static bool Decrement(ref Guid Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:1109
static bool Decrement(ref double Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:977
static bool TryMakeSameType(ref object x, ref object y)
Tries to make sure x and y have the same type.
Definition: Comparison.cs:18
static bool Increment(ref object Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:262
static bool Increment(ref float Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:550
static bool Decrement(ref decimal Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:1041
static bool Increment(ref Guid Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:643
static bool Decrement(ref string Value)
Decrements Value to the largest value smaller than Value .
Definition: Comparison.cs:1073
static bool Increment(ref double Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:518
static bool Increment(ref decimal Value)
Increments Value to the smallest value greater than Value .
Definition: Comparison.cs:582
Serializes a class, taking into account attributes defined in Attributes.
const uint TYPE_TIMESPAN
Represents a TimeSpan
const uint TYPE_NULL
Represents a null value.
const uint TYPE_VARINT64
Variable length INT64
const uint TYPE_VARUINT32
Variable length UINT32
const uint TYPE_VARINT16
Variable length INT16
static uint GetFieldDataTypeCode(object Value)
Returns the type code corresponding to a given field data type.
const uint TYPE_CI_STRING
Represents a CaseInsensitiveString
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_DATETIME
Represents a DateTime
const uint TYPE_VARINT32
Variable length INT32
const uint TYPE_ENUM
Represents an enumerated value.