@@ -13,12 +13,10 @@ use std::io::{Cursor, Read, Write};
13
13
use std:: iter:: Peekable ;
14
14
15
15
use byteorder:: { ReadBytesExt , WriteBytesExt } ;
16
- use num_bigint:: BigInt ;
17
- use num_traits:: ToPrimitive ;
18
16
19
17
use crate :: function:: PyFuncArgs ;
20
- use crate :: obj:: { objbool , objbytes, objfloat , objint , objstr, objtype} ;
21
- use crate :: pyobject:: { PyObjectRef , PyResult } ;
18
+ use crate :: obj:: { objbytes, objstr, objtype} ;
19
+ use crate :: pyobject:: { PyObjectRef , PyResult , TryFromObject } ;
22
20
use crate :: VirtualMachine ;
23
21
24
22
#[ derive( Debug ) ]
@@ -130,144 +128,54 @@ fn is_supported_format_character(c: char) -> bool {
130
128
}
131
129
}
132
130
133
- fn get_int ( vm : & VirtualMachine , arg : & PyObjectRef ) -> PyResult < BigInt > {
134
- objint:: to_int ( vm, arg, & BigInt :: from ( 10 ) )
135
- }
136
-
137
- fn pack_i8 ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
138
- let v = get_int ( vm, arg) ?. to_i8 ( ) . unwrap ( ) ;
139
- data. write_i8 ( v) . unwrap ( ) ;
140
- Ok ( ( ) )
131
+ macro_rules! make_pack_no_endianess {
132
+ ( $T: ty) => {
133
+ paste:: item! {
134
+ fn [ <pack_ $T>] ( vm: & VirtualMachine , arg: & PyObjectRef , data: & mut dyn Write ) -> PyResult <( ) > {
135
+ let v = $T:: try_from_object( vm, arg. clone( ) ) ?;
136
+ data. [ <write_$T>] ( v) . unwrap( ) ;
137
+ Ok ( ( ) )
138
+ }
139
+ }
140
+ } ;
141
+ }
142
+
143
+ macro_rules! make_pack_with_endianess {
144
+ ( $T: ty) => {
145
+ paste:: item! {
146
+ fn [ <pack_ $T>] <Endianness >( vm: & VirtualMachine , arg: & PyObjectRef , data: & mut dyn Write ) -> PyResult <( ) >
147
+ where
148
+ Endianness : byteorder:: ByteOrder ,
149
+ {
150
+ let v = $T:: try_from_object( vm, arg. clone( ) ) ?;
151
+ data. [ <write_$T>] :: <Endianness >( v) . unwrap( ) ;
152
+ Ok ( ( ) )
153
+ }
154
+ }
155
+ } ;
141
156
}
142
157
143
- fn pack_u8 ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
144
- let v = get_int ( vm, arg) ?. to_u8 ( ) . unwrap ( ) ;
145
- data. write_u8 ( v) . unwrap ( ) ;
146
- Ok ( ( ) )
147
- }
158
+ make_pack_no_endianess ! ( i8 ) ;
159
+ make_pack_no_endianess ! ( u8 ) ;
160
+ make_pack_with_endianess ! ( i16 ) ;
161
+ make_pack_with_endianess ! ( u16 ) ;
162
+ make_pack_with_endianess ! ( i32 ) ;
163
+ make_pack_with_endianess ! ( u32 ) ;
164
+ make_pack_with_endianess ! ( i64 ) ;
165
+ make_pack_with_endianess ! ( u64 ) ;
166
+ make_pack_with_endianess ! ( f32 ) ;
167
+ make_pack_with_endianess ! ( f64 ) ;
148
168
149
169
fn pack_bool ( vm : & VirtualMachine , arg : & PyObjectRef , data : & mut dyn Write ) -> PyResult < ( ) > {
150
- if objtype:: isinstance ( & arg, & vm. ctx . bool_type ( ) ) {
151
- let v = if objbool:: get_value ( arg) { 1 } else { 0 } ;
152
- data. write_u8 ( v) . unwrap ( ) ;
153
- Ok ( ( ) )
170
+ let v = if bool:: try_from_object ( vm, arg. clone ( ) ) ? {
171
+ 1
154
172
} else {
155
- Err ( vm. new_type_error ( "Expected boolean" . to_string ( ) ) )
156
- }
157
- }
158
-
159
- fn pack_i16 < Endianness > (
160
- vm : & VirtualMachine ,
161
- arg : & PyObjectRef ,
162
- data : & mut dyn Write ,
163
- ) -> PyResult < ( ) >
164
- where
165
- Endianness : byteorder:: ByteOrder ,
166
- {
167
- let v = get_int ( vm, arg) ?. to_i16 ( ) . unwrap ( ) ;
168
- data. write_i16 :: < Endianness > ( v) . unwrap ( ) ;
169
- Ok ( ( ) )
170
- }
171
-
172
- fn pack_u16 < Endianness > (
173
- vm : & VirtualMachine ,
174
- arg : & PyObjectRef ,
175
- data : & mut dyn Write ,
176
- ) -> PyResult < ( ) >
177
- where
178
- Endianness : byteorder:: ByteOrder ,
179
- {
180
- let v = get_int ( vm, arg) ?. to_u16 ( ) . unwrap ( ) ;
181
- data. write_u16 :: < Endianness > ( v) . unwrap ( ) ;
182
- Ok ( ( ) )
183
- }
184
-
185
- fn pack_i32 < Endianness > (
186
- vm : & VirtualMachine ,
187
- arg : & PyObjectRef ,
188
- data : & mut dyn Write ,
189
- ) -> PyResult < ( ) >
190
- where
191
- Endianness : byteorder:: ByteOrder ,
192
- {
193
- let v = get_int ( vm, arg) ?. to_i32 ( ) . unwrap ( ) ;
194
- data. write_i32 :: < Endianness > ( v) . unwrap ( ) ;
195
- Ok ( ( ) )
196
- }
197
-
198
- fn pack_u32 < Endianness > (
199
- vm : & VirtualMachine ,
200
- arg : & PyObjectRef ,
201
- data : & mut dyn Write ,
202
- ) -> PyResult < ( ) >
203
- where
204
- Endianness : byteorder:: ByteOrder ,
205
- {
206
- let v = get_int ( vm, arg) ?. to_u32 ( ) . unwrap ( ) ;
207
- data. write_u32 :: < Endianness > ( v) . unwrap ( ) ;
208
- Ok ( ( ) )
209
- }
210
-
211
- fn pack_i64 < Endianness > (
212
- vm : & VirtualMachine ,
213
- arg : & PyObjectRef ,
214
- data : & mut dyn Write ,
215
- ) -> PyResult < ( ) >
216
- where
217
- Endianness : byteorder:: ByteOrder ,
218
- {
219
- let v = get_int ( vm, arg) ?. to_i64 ( ) . unwrap ( ) ;
220
- data. write_i64 :: < Endianness > ( v) . unwrap ( ) ;
221
- Ok ( ( ) )
222
- }
223
-
224
- fn pack_u64 < Endianness > (
225
- vm : & VirtualMachine ,
226
- arg : & PyObjectRef ,
227
- data : & mut dyn Write ,
228
- ) -> PyResult < ( ) >
229
- where
230
- Endianness : byteorder:: ByteOrder ,
231
- {
232
- let v = get_int ( vm, arg) ?. to_u64 ( ) . unwrap ( ) ;
233
- data. write_u64 :: < Endianness > ( v) . unwrap ( ) ;
234
- Ok ( ( ) )
235
- }
236
-
237
- fn pack_f32 < Endianness > (
238
- vm : & VirtualMachine ,
239
- arg : & PyObjectRef ,
240
- data : & mut dyn Write ,
241
- ) -> PyResult < ( ) >
242
- where
243
- Endianness : byteorder:: ByteOrder ,
244
- {
245
- let v = get_float ( vm, arg) ? as f32 ;
246
- data. write_f32 :: < Endianness > ( v) . unwrap ( ) ;
247
- Ok ( ( ) )
248
- }
249
-
250
- fn pack_f64 < Endianness > (
251
- vm : & VirtualMachine ,
252
- arg : & PyObjectRef ,
253
- data : & mut dyn Write ,
254
- ) -> PyResult < ( ) >
255
- where
256
- Endianness : byteorder:: ByteOrder ,
257
- {
258
- let v = get_float ( vm, arg) ?;
259
- data. write_f64 :: < Endianness > ( v) . unwrap ( ) ;
173
+ 0
174
+ } ;
175
+ data. write_u8 ( v) . unwrap ( ) ;
260
176
Ok ( ( ) )
261
177
}
262
178
263
- fn get_float ( vm : & VirtualMachine , arg : & PyObjectRef ) -> PyResult < f64 > {
264
- if objtype:: isinstance ( & arg, & vm. ctx . float_type ( ) ) {
265
- Ok ( objfloat:: get_value ( arg) )
266
- } else {
267
- Err ( vm. new_type_error ( "Expected float" . to_string ( ) ) )
268
- }
269
- }
270
-
271
179
fn pack_item < Endianness > (
272
180
vm : & VirtualMachine ,
273
181
code : & FormatCode ,
0 commit comments