@@ -141,12 +141,12 @@ public void __init__(CodeContext/*!*/ context, object fmt) {
141141 break ;
142142 case FormatType . UnsignedInt :
143143 for ( int j = 0 ; j < curFormat . Count ; j ++ ) {
144- WriteUInt ( res , _isLittleEndian , GetULongValue ( context , curObj ++ , values , "unsigned int" ) ) ;
144+ WriteUInt ( res , _isLittleEndian , GetULongValue ( context , curObj ++ , values ) ) ;
145145 }
146146 break ;
147147 case FormatType . UnsignedLong :
148148 for ( int j = 0 ; j < curFormat . Count ; j ++ ) {
149- WriteUInt ( res , _isLittleEndian , GetULongValue ( context , curObj ++ , values , "unsigned long" ) ) ;
149+ WriteUInt ( res , _isLittleEndian , GetULongValue ( context , curObj ++ , values ) ) ;
150150 }
151151 break ;
152152 case FormatType . Pointer :
@@ -176,7 +176,7 @@ public void __init__(CodeContext/*!*/ context, object fmt) {
176176 break ;
177177 case FormatType . LongLong :
178178 for ( int j = 0 ; j < curFormat . Count ; j ++ ) {
179- WriteLong ( res , _isLittleEndian , GetLongValue ( context , curObj ++ , values ) ) ;
179+ WriteLong ( res , _isLittleEndian , GetLongLongValue ( context , curObj ++ , values ) ) ;
180180 }
181181 break ;
182182 case FormatType . UnsignedLongLong :
@@ -1066,110 +1066,77 @@ internal static byte GetCharValue(CodeContext/*!*/ context, int index, object[]
10661066 }
10671067
10681068 internal static sbyte GetSByteValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1069- object val = GetValue ( context , index , args ) ;
1070- if ( Converter . TryConvertToSByte ( val , out sbyte res ) ) return res ;
1071- throw Error ( context , "expected sbyte value got " + val . ToString ( ) ) ;
1069+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1070+ if ( ! val . AsInt32 ( out int res ) )
1071+ throw Error ( context , "argument out of range" ) ;
1072+ CheckRange ( context , res , sbyte . MinValue , sbyte . MaxValue , "byte" ) ;
1073+ return ( sbyte ) res ;
10721074 }
10731075
10741076 internal static byte GetByteValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1075- object val = GetValue ( context , index , args ) ;
1076- if ( Converter . TryConvertToByte ( val , out byte res ) ) return res ;
1077- throw Error ( context , "expected byte value got " + val . ToString ( ) ) ;
1077+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1078+ if ( ! val . AsInt32 ( out int res ) )
1079+ throw Error ( context , "argument out of range" ) ;
1080+ CheckRange ( context , res , byte . MinValue , byte . MaxValue , "ubyte" ) ;
1081+ return ( byte ) res ;
10781082 }
10791083
10801084 internal static short GetShortValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1081- object val = GetValue ( context , index , args ) ;
1082- if ( Converter . TryConvertToInt16 ( val , out short res ) ) return res ;
1083- throw Error ( context , "expected short value" ) ;
1085+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1086+ if ( ! val . AsInt32 ( out int res ) )
1087+ throw Error ( context , "argument out of range" ) ;
1088+ CheckRange ( context , res , short . MinValue , short . MaxValue , "short" ) ;
1089+ return ( short ) res ;
10841090 }
10851091
10861092 internal static ushort GetUShortValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1087- object val = GetValue ( context , index , args ) ;
1088- if ( Converter . TryConvertToUInt16 ( val , out ushort res ) ) return res ;
1089- throw Error ( context , "expected ushort value" ) ;
1093+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1094+ if ( ! val . AsInt32 ( out int res ) )
1095+ throw Error ( context , "argument out of range" ) ;
1096+ CheckRange ( context , res , ushort . MinValue , ushort . MaxValue , "ushort" ) ;
1097+ return ( ushort ) res ;
10901098 }
10911099
10921100 internal static int GetIntValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1093- object val = GetValue ( context , index , args ) ;
1094- if ( Converter . TryConvertToInt32 ( val , out int res ) ) return res ;
1095- throw Error ( context , "expected int value" ) ;
1096- }
1097-
1098- internal static uint GetULongValue ( CodeContext /*!*/ context , int index , object [ ] args , string type ) {
1099- object val = GetValue ( context , index , args ) ;
1100- if ( val is int i ) {
1101- CheckRange ( context , i , type ) ;
1102- return ( uint ) i ;
1103- } else if ( val is BigInteger bi ) {
1104- CheckRange ( context , bi , type ) ;
1105- return ( uint ) bi ;
1106- } else if ( val is Extensible < BigInteger > ebi ) {
1107- CheckRange ( context , ebi . Value , type ) ;
1108- return ( uint ) ebi . Value ;
1109- } else {
1110- if ( PythonTypeOps . TryInvokeUnaryOperator ( DefaultContext . Default , val , "__int__" , out object objres ) ) {
1111- if ( objres is int oi ) {
1112- CheckRange ( context , oi , type ) ;
1113- return ( uint ) oi ;
1114- }
1115- }
1116-
1117- if ( Converter . TryConvertToUInt32 ( val , out uint res ) ) {
1118- return res ;
1119- }
1120- }
1121-
1122- throw Error ( context , "cannot convert argument to integer" ) ;
1123- }
1124-
1125- private static void CheckRange ( CodeContext context , int val , string type ) {
1126- if ( val < 0 ) {
1127- OutOfRange ( context , type ) ;
1128- }
1129- }
1130-
1131- private static void CheckRange ( CodeContext context , BigInteger bi , string type ) {
1132- if ( bi < 0 || bi > 4294967295 ) {
1133- OutOfRange ( context , type ) ;
1134- }
1101+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1102+ if ( ! val . AsInt32 ( out int res ) )
1103+ throw Error ( context , "argument out of range" ) ;
1104+ return res ;
11351105 }
11361106
1137- private static void OutOfRange ( CodeContext context , string type ) {
1138- throw Error ( context , $ "integer out of range for '{ ( type == "unsigned long" ? "L" : "I" ) } ' format code") ;
1107+ internal static uint GetULongValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1108+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1109+ if ( ! val . AsUInt32 ( out uint res ) )
1110+ throw Error ( context , "argument out of range" ) ;
1111+ return res ;
11391112 }
11401113
11411114 internal static int GetSignedSizeT ( CodeContext /*!*/ context , int index , object [ ] args ) {
1142- object val = GetValue ( context , index , args ) ;
1143- if ( Converter . TryConvertToInt32 ( val , out int res ) ) return res ;
1144- throw Error ( context , "expected signed size_t(aka ssize_t) value" ) ;
1115+ return GetIntValue ( context , index , args ) ;
11451116 }
11461117
11471118 internal static uint GetSizeT ( CodeContext /*!*/ context , int index , object [ ] args ) {
1148- object val = GetValue ( context , index , args ) ;
1149- if ( Converter . TryConvertToUInt32 ( val , out uint res ) ) return res ;
1150- throw Error ( context , "expected size_t value" ) ;
1119+ return GetULongValue ( context , index , args ) ;
11511120 }
11521121
11531122 internal static ulong GetPointer ( CodeContext /*!*/ context , int index , object [ ] args ) {
1154- object val = GetValue ( context , index , args ) ;
1155- if ( Converter . TryConvertToBigInteger ( val , out BigInteger bi ) ) {
1156- if ( UIntPtr . Size == 4 ) {
1157- if ( bi < 0 ) {
1158- bi += new BigInteger ( UInt32 . MaxValue ) + 1 ;
1159- }
1160- if ( Converter . TryConvertToUInt32 ( bi , out uint res ) ) {
1161- return res ;
1162- }
1163- } else {
1164- if ( bi < 0 ) {
1165- bi += new BigInteger ( UInt64 . MaxValue ) + 1 ;
1166- }
1167- if ( Converter . TryConvertToUInt64 ( bi , out ulong res ) ) {
1168- return res ;
1169- }
1123+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1124+ if ( UIntPtr . Size == 4 ) {
1125+ if ( val < 0 ) {
1126+ val += new BigInteger ( UInt32 . MaxValue ) + 1 ;
1127+ }
1128+ if ( Converter . TryConvertToUInt32 ( val , out uint res ) ) {
1129+ return res ;
1130+ }
1131+ } else {
1132+ if ( val < 0 ) {
1133+ val += new BigInteger ( UInt64 . MaxValue ) + 1 ;
1134+ }
1135+ if ( Converter . TryConvertToUInt64 ( val , out ulong res ) ) {
1136+ return res ;
11701137 }
11711138 }
1172- throw Error ( context , "expected pointer value " ) ;
1139+ throw Error ( context , "int too large to convert " ) ;
11731140 }
11741141
11751142 internal static IntPtr GetSignedNetPointer ( CodeContext /*!*/ context , int index , object [ ] args ) {
@@ -1192,16 +1159,18 @@ internal static UIntPtr GetUnsignedNetPointer(CodeContext/*!*/ context, int inde
11921159 throw Error ( context , "expected .NET pointer value" ) ;
11931160 }
11941161
1195- internal static long GetLongValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1196- object val = GetValue ( context , index , args ) ;
1197- if ( Converter . TryConvertToInt64 ( val , out long res ) ) return res ;
1198- throw Error ( context , "expected long value" ) ;
1162+ internal static long GetLongLongValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1163+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1164+ if ( ! val . AsInt64 ( out long res ) )
1165+ throw Error ( context , "argument out of range" ) ;
1166+ return res ;
11991167 }
12001168
12011169 internal static ulong GetULongLongValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1202- object val = GetValue ( context , index , args ) ;
1203- if ( Converter . TryConvertToUInt64 ( val , out ulong res ) ) return res ;
1204- throw Error ( context , "expected ulong value" ) ;
1170+ BigInteger val = GetIntegerValue ( context , index , args ) ;
1171+ if ( ! val . AsUInt64 ( out ulong res ) )
1172+ throw Error ( context , "argument out of range" ) ;
1173+ return res ;
12051174 }
12061175
12071176 internal static double GetDoubleValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
@@ -1220,6 +1189,19 @@ internal static object GetValue(CodeContext/*!*/ context, int index, object[] ar
12201189 if ( index >= args . Length ) throw Error ( context , "not enough arguments" ) ;
12211190 return args [ index ] ;
12221191 }
1192+
1193+ private static BigInteger GetIntegerValue ( CodeContext /*!*/ context , int index , object [ ] args ) {
1194+ object val = GetValue ( context , index , args ) ;
1195+ if ( PythonOps . TryToIndex ( val , out BigInteger res ) ) return res ;
1196+ throw Error ( context , "required argument is not an integer" ) ;
1197+ }
1198+
1199+ private static void CheckRange ( CodeContext context , int val , int min , int max , string format ) {
1200+ if ( val < min || val > max ) {
1201+ throw Error ( context , $ "{ format } format requires { min } <= number <= { max } ") ;
1202+ }
1203+ }
1204+
12231205 #endregion
12241206
12251207 #region Data creater helpers
0 commit comments