inline_int · ijl/orjson@4ba2c7f (original) (raw)

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

`// "[-(253)+1, (253)-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(&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(&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

`}

`