Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 16bb081

Browse files
committed
Move internal classes to DefaultMemory
1 parent d4cd74d commit 16bb081

File tree

2 files changed

+321
-321
lines changed

2 files changed

+321
-321
lines changed

src/ServiceStack.Text/DefaultMemory.cs

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,4 +669,325 @@ private static byte ParseHexByte(char c1, char c2)
669669
}
670670
}
671671
}
672+
673+
enum ParseState
674+
{
675+
LeadingWhite,
676+
Sign,
677+
Number,
678+
DecimalPoint,
679+
FractionNumber,
680+
Exponent,
681+
ExponentSign,
682+
ExponentValue,
683+
TrailingWhite
684+
}
685+
686+
internal static class SignedInteger<T> where T : struct, IComparable<T>, IEquatable<T>, IConvertible
687+
{
688+
private static readonly TypeCode typeCode;
689+
private static readonly long minValue;
690+
private static readonly long maxValue;
691+
692+
static SignedInteger()
693+
{
694+
typeCode = Type.GetTypeCode(typeof(T));
695+
696+
switch (typeCode)
697+
{
698+
case TypeCode.SByte:
699+
minValue = sbyte.MinValue;
700+
maxValue = sbyte.MaxValue;
701+
break;
702+
case TypeCode.Int16:
703+
minValue = short.MinValue;
704+
maxValue = short.MaxValue;
705+
break;
706+
case TypeCode.Int32:
707+
minValue = int.MinValue;
708+
maxValue = int.MaxValue;
709+
break;
710+
case TypeCode.Int64:
711+
minValue = long.MinValue;
712+
maxValue = long.MaxValue;
713+
break;
714+
default:
715+
throw new NotSupportedException($"{typeof(T).Name} is not a signed integer");
716+
}
717+
}
718+
719+
internal static object ParseNullableObject(ReadOnlySpan<char> value)
720+
{
721+
if (value.IsNullOrEmpty())
722+
return null;
723+
724+
return ParseObject(value);
725+
}
726+
727+
internal static object ParseObject(ReadOnlySpan<char> value)
728+
{
729+
var result = ParseInt64(value);
730+
switch (typeCode)
731+
{
732+
case TypeCode.SByte:
733+
return (sbyte) result;
734+
case TypeCode.Int16:
735+
return (short) result;
736+
case TypeCode.Int32:
737+
return (int) result;
738+
default:
739+
return result;
740+
}
741+
}
742+
743+
public static sbyte ParseSByte(ReadOnlySpan<char> value) => (sbyte) ParseInt64(value);
744+
public static short ParseInt16(ReadOnlySpan<char> value) => (short) ParseInt64(value);
745+
public static int ParseInt32(ReadOnlySpan<char> value) => (int) ParseInt64(value);
746+
747+
public static long ParseInt64(ReadOnlySpan<char> value)
748+
{
749+
if (value.IsEmpty)
750+
throw new FormatException(MemoryProvider.BadFormat);
751+
752+
long result = 0;
753+
int i = 0;
754+
int end = value.Length;
755+
var state = ParseState.LeadingWhite;
756+
bool negative = false;
757+
758+
//skip leading whitespaces
759+
while (i < end && JsonUtils.IsWhiteSpace(value[i])) i++;
760+
761+
if (i == end)
762+
throw new FormatException(MemoryProvider.BadFormat);
763+
764+
//skip leading zeros
765+
while (i < end && value[i] == '0')
766+
{
767+
state = ParseState.Number;
768+
i++;
769+
}
770+
771+
while (i < end)
772+
{
773+
var c = value[i++];
774+
775+
switch (state)
776+
{
777+
case ParseState.LeadingWhite:
778+
if (c == '-')
779+
{
780+
negative = true;
781+
state = ParseState.Sign;
782+
}
783+
else if (c == '0')
784+
{
785+
state = ParseState.TrailingWhite;
786+
}
787+
else if (c > '0' && c <= '9')
788+
{
789+
result = -(c - '0');
790+
state = ParseState.Number;
791+
}
792+
else throw new FormatException(MemoryProvider.BadFormat);
793+
794+
break;
795+
case ParseState.Sign:
796+
if (c == '0')
797+
{
798+
state = ParseState.TrailingWhite;
799+
}
800+
else if (c > '0' && c <= '9')
801+
{
802+
result = -(c - '0');
803+
state = ParseState.Number;
804+
}
805+
else throw new FormatException(MemoryProvider.BadFormat);
806+
807+
break;
808+
case ParseState.Number:
809+
if (c >= '0' && c <= '9')
810+
{
811+
checked
812+
{
813+
result = 10 * result - (c - '0');
814+
}
815+
816+
if (result < minValue
817+
) //check only minvalue, because in absolute value it's greater than maxvalue
818+
throw DefaultMemory.CreateOverflowException(maxValue);
819+
}
820+
else if (JsonUtils.IsWhiteSpace(c))
821+
{
822+
state = ParseState.TrailingWhite;
823+
}
824+
else throw new FormatException(MemoryProvider.BadFormat);
825+
826+
break;
827+
case ParseState.TrailingWhite:
828+
if (JsonUtils.IsWhiteSpace(c))
829+
{
830+
state = ParseState.TrailingWhite;
831+
}
832+
else throw new FormatException(MemoryProvider.BadFormat);
833+
834+
break;
835+
}
836+
}
837+
838+
if (state != ParseState.Number && state != ParseState.TrailingWhite)
839+
throw new FormatException(MemoryProvider.BadFormat);
840+
841+
if (negative)
842+
return result;
843+
844+
checked
845+
{
846+
result = -result;
847+
}
848+
849+
if (result > maxValue)
850+
throw DefaultMemory.CreateOverflowException(maxValue);
851+
852+
return result;
853+
}
854+
}
855+
856+
internal static class UnsignedInteger<T> where T : struct, IComparable<T>, IEquatable<T>, IConvertible
857+
{
858+
private static readonly TypeCode typeCode;
859+
private static readonly ulong maxValue;
860+
861+
static UnsignedInteger()
862+
{
863+
typeCode = Type.GetTypeCode(typeof(T));
864+
865+
switch (typeCode)
866+
{
867+
case TypeCode.Byte:
868+
maxValue = byte.MaxValue;
869+
break;
870+
case TypeCode.UInt16:
871+
maxValue = ushort.MaxValue;
872+
break;
873+
case TypeCode.UInt32:
874+
maxValue = uint.MaxValue;
875+
break;
876+
case TypeCode.UInt64:
877+
maxValue = ulong.MaxValue;
878+
break;
879+
default:
880+
throw new NotSupportedException($"{typeof(T).Name} is not a signed integer");
881+
}
882+
}
883+
884+
internal static object ParseNullableObject(ReadOnlySpan<char> value)
885+
{
886+
if (value.IsNullOrEmpty())
887+
return null;
888+
889+
return ParseObject(value);
890+
}
891+
892+
internal static object ParseObject(ReadOnlySpan<char> value)
893+
{
894+
var result = ParseUInt64(value);
895+
switch (typeCode)
896+
{
897+
case TypeCode.Byte:
898+
return (byte) result;
899+
case TypeCode.UInt16:
900+
return (ushort) result;
901+
case TypeCode.UInt32:
902+
return (uint) result;
903+
default:
904+
return result;
905+
}
906+
}
907+
908+
public static byte ParseByte(ReadOnlySpan<char> value) => (byte) ParseUInt64(value);
909+
public static ushort ParseUInt16(ReadOnlySpan<char> value) => (ushort) ParseUInt64(value);
910+
public static uint ParseUInt32(ReadOnlySpan<char> value) => (uint) ParseUInt64(value);
911+
912+
internal static ulong ParseUInt64(ReadOnlySpan<char> value)
913+
{
914+
if (value.IsEmpty)
915+
throw new FormatException(MemoryProvider.BadFormat);
916+
917+
ulong result = 0;
918+
int i = 0;
919+
int end = value.Length;
920+
var state = ParseState.LeadingWhite;
921+
922+
//skip leading whitespaces
923+
while (i < end && JsonUtils.IsWhiteSpace(value[i])) i++;
924+
925+
if (i == end)
926+
throw new FormatException(MemoryProvider.BadFormat);
927+
928+
//skip leading zeros
929+
while (i < end && value[i] == '0')
930+
{
931+
state = ParseState.Number;
932+
i++;
933+
}
934+
935+
while (i < end)
936+
{
937+
var c = value[i++];
938+
939+
switch (state)
940+
{
941+
case ParseState.LeadingWhite:
942+
if (JsonUtils.IsWhiteSpace(c))
943+
break;
944+
if (c == '0')
945+
{
946+
state = ParseState.TrailingWhite;
947+
}
948+
else if (c > '0' && c <= '9')
949+
{
950+
result = (ulong) (c - '0');
951+
state = ParseState.Number;
952+
}
953+
else throw new FormatException(MemoryProvider.BadFormat);
954+
955+
956+
break;
957+
case ParseState.Number:
958+
if (c >= '0' && c <= '9')
959+
{
960+
checked
961+
{
962+
result = 10 * result + (ulong) (c - '0');
963+
}
964+
965+
if (result > maxValue
966+
) //check only minvalue, because in absolute value it's greater than maxvalue
967+
throw DefaultMemory.CreateOverflowException(maxValue);
968+
}
969+
else if (JsonUtils.IsWhiteSpace(c))
970+
{
971+
state = ParseState.TrailingWhite;
972+
}
973+
else throw new FormatException(MemoryProvider.BadFormat);
974+
975+
break;
976+
case ParseState.TrailingWhite:
977+
if (JsonUtils.IsWhiteSpace(c))
978+
{
979+
state = ParseState.TrailingWhite;
980+
}
981+
else throw new FormatException(MemoryProvider.BadFormat);
982+
983+
break;
984+
}
985+
}
986+
987+
if (state != ParseState.Number && state != ParseState.TrailingWhite)
988+
throw new FormatException(MemoryProvider.BadFormat);
989+
990+
return result;
991+
}
992+
}
672993
}

0 commit comments

Comments
 (0)