1
1
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
2
2
3
- use crate :: ffi:: { pylong_fits_in_i32, pylong_get_inline_value, pylong_is_unsigned, pylong_is_zero} ;
4
3
use crate :: opt:: { Opt , STRICT_INTEGER } ;
5
4
use crate :: serialize:: error:: SerializeError ;
6
5
use serde:: ser:: { Serialize , Serializer } ;
7
6
8
- use core:: ffi:: c_uchar;
9
- use core:: mem:: transmute;
10
-
11
7
// https://tools.ietf.org/html/rfc7159#section-6
12
8
// "[-(2**53)+1, (2**53)-1]"
13
9
const STRICT_INT_MIN : i64 = -9007199254740991 ;
@@ -29,26 +25,27 @@ impl IntSerializer {
29
25
30
26
impl Serialize for IntSerializer {
31
27
#[ inline( always) ]
28
+ #[ cfg( feature = "inline_int" ) ]
32
29
fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
33
30
where
34
31
S : Serializer ,
35
32
{
36
33
unsafe {
37
- if pylong_is_zero ( self . ptr ) {
34
+ if crate :: ffi :: pylong_is_zero ( self . ptr ) {
38
35
return serializer. serialize_bytes ( b"0" ) ;
39
36
}
40
- let is_signed = !pylong_is_unsigned ( self . ptr ) as i32 ;
41
- if pylong_fits_in_i32 ( self . ptr ) {
37
+ let is_signed = !crate :: ffi :: pylong_is_unsigned ( self . ptr ) as i32 ;
38
+ if crate :: ffi :: pylong_fits_in_i32 ( self . ptr ) {
42
39
if is_signed == 0 {
43
- serializer. serialize_u64 ( pylong_get_inline_value ( self . ptr ) as u64 )
40
+ serializer. serialize_u64 ( crate :: ffi :: pylong_get_inline_value ( self . ptr ) as u64 )
44
41
} else {
45
- serializer. serialize_i64 ( pylong_get_inline_value ( self . ptr ) as i64 )
42
+ serializer. serialize_i64 ( crate :: ffi :: pylong_get_inline_value ( self . ptr ) as i64 )
46
43
}
47
44
} else {
48
45
let mut buffer: [ u8 ; 8 ] = [ 0 ; 8 ] ;
49
46
let ret = pyo3_ffi:: _PyLong_AsByteArray (
50
47
self . ptr as * mut pyo3_ffi:: PyLongObject ,
51
- buffer. as_mut_ptr ( ) as * mut c_uchar ,
48
+ buffer. as_mut_ptr ( ) as * mut core :: ffi :: c_uchar ,
52
49
8 ,
53
50
1 ,
54
51
is_signed,
@@ -58,15 +55,15 @@ impl Serialize for IntSerializer {
58
55
err ! ( SerializeError :: Integer64Bits )
59
56
}
60
57
if is_signed == 0 {
61
- let val = transmute :: < [ u8 ; 8 ] , u64 > ( buffer) ;
58
+ let val = core :: mem :: transmute :: < [ u8 ; 8 ] , u64 > ( buffer) ;
62
59
if unlikely ! ( opt_enabled!( self . opts, STRICT_INTEGER ) )
63
60
&& val > STRICT_INT_MAX as u64
64
61
{
65
62
err ! ( SerializeError :: Integer53Bits )
66
63
}
67
64
serializer. serialize_u64 ( val)
68
65
} else {
69
- let val = transmute :: < [ u8 ; 8 ] , i64 > ( buffer) ;
66
+ let val = core :: mem :: transmute :: < [ u8 ; 8 ] , i64 > ( buffer) ;
70
67
if unlikely ! ( opt_enabled!( self . opts, STRICT_INTEGER ) )
71
68
&& !( STRICT_INT_MIN ..=STRICT_INT_MAX ) . contains ( & val)
72
69
{
@@ -77,4 +74,39 @@ impl Serialize for IntSerializer {
77
74
}
78
75
}
79
76
}
77
+
78
+ #[ inline( always) ]
79
+ #[ cfg( not( feature = "inline_int" ) ) ]
80
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
81
+ where
82
+ S : Serializer ,
83
+ {
84
+ unsafe {
85
+ if crate :: ffi:: pylong_is_unsigned ( self . ptr ) {
86
+ let val = ffi ! ( PyLong_AsUnsignedLongLong ( self . ptr) ) ;
87
+ if unlikely ! ( val == u64 :: MAX ) && !ffi ! ( PyErr_Occurred ( ) ) . is_null ( ) {
88
+ ffi ! ( PyErr_Clear ( ) ) ;
89
+ err ! ( SerializeError :: Integer64Bits )
90
+ } else if unlikely ! ( opt_enabled!( self . opts, STRICT_INTEGER ) )
91
+ && val > STRICT_INT_MAX as u64
92
+ {
93
+ err ! ( SerializeError :: Integer53Bits )
94
+ } else {
95
+ serializer. serialize_u64 ( val)
96
+ }
97
+ } else {
98
+ let val = ffi ! ( PyLong_AsLongLong ( self . ptr) ) ;
99
+ if unlikely ! ( val == -1 ) && !ffi ! ( PyErr_Occurred ( ) ) . is_null ( ) {
100
+ ffi ! ( PyErr_Clear ( ) ) ;
101
+ err ! ( SerializeError :: Integer64Bits )
102
+ } else if unlikely ! ( opt_enabled!( self . opts, STRICT_INTEGER ) )
103
+ && !( STRICT_INT_MIN ..=STRICT_INT_MAX ) . contains ( & val)
104
+ {
105
+ err ! ( SerializeError :: Integer53Bits )
106
+ } else {
107
+ serializer. serialize_i64 ( val)
108
+ }
109
+ }
110
+ }
111
+ }
80
112
}
0 commit comments