1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
//! Config settings for lexical.
// GLOBALS
/// Not a Number literal
///
/// To change the expected representation of NaN as a string,
/// change this value during before using lexical.
///
/// Do not modify this value in threaded-code, as it is not thread-safe.
pub static mut NAN_STRING: &str = "NaN";
/// Short infinity literal
///
/// To change the expected representation of Infinity as a string,
/// change this value during before using lexical.
pub static mut INF_STRING: &str = "inf";
/// Long infinity literal
///
/// To change the expected backup representation of Infinity as a string,
/// change this value during before using lexical.
pub static mut INFINITY_STRING: &str = "infinity";
/// Default character for scientific notation, used when the radix < 15.
///
/// To change the expected, default character for an exponent,
/// change this value during before using lexical.
pub static mut EXPONENT_DEFAULT_CHAR: u8 = b'e';
/// Backup character for scientific notation, used when the radix >= 15.
///
/// For numerical strings of radix >= 15, 'e' or 'E' is a valid digit,
/// and therefore may no longer be used as a marker for the exponent.
///
/// To change the expected, default character for an exponent,
/// change this value during before using lexical.
pub static mut EXPONENT_BACKUP_CHAR: u8 = b'^';
// CONSTANTS
// Simple, fast optimization.
// Since we're declaring a variable on the stack, and our power-of-two
// alignment dramatically improved atoi performance, do it.
cfg_if! {
if #[cfg(feature = "radix")] {
// Use 256, actually, since we seem to have memory issues with f64.
// Clearly not sufficient memory allocated for non-base10 values.
/// The minimum buffer size required to serialize any i8 value.
pub const MAX_I8_SIZE: usize = 16;
/// The minimum buffer size required to serialize any i16 value.
pub const MAX_I16_SIZE: usize = 32;
/// The minimum buffer size required to serialize any i32 value.
pub const MAX_I32_SIZE: usize = 64;
/// The minimum buffer size required to serialize any i64 value.
pub const MAX_I64_SIZE: usize = 128;
/// The minimum buffer size required to serialize any i128 value.
pub const MAX_I128_SIZE: usize = 256;
/// The minimum buffer size required to serialize any u8 value.
pub const MAX_U8_SIZE: usize = 16;
/// The minimum buffer size required to serialize any u16 value.
pub const MAX_U16_SIZE: usize = 32;
/// The minimum buffer size required to serialize any u32 value.
pub const MAX_U32_SIZE: usize = 64;
/// The minimum buffer size required to serialize any u64 value.
pub const MAX_U64_SIZE: usize = 128;
/// The minimum buffer size required to serialize any u128 value.
pub const MAX_U128_SIZE: usize = 256;
/// The minimum buffer size required to serialize any f32 value.
pub const MAX_F32_SIZE: usize = 256;
/// The minimum buffer size required to serialize any f64 value.
pub const MAX_F64_SIZE: usize = 256;
} else {
// The f64 buffer is actually a size of 60, but use 64 since it's a
// power of 2.
/// The minimum buffer size required to serialize any i8 value.
pub const MAX_I8_SIZE: usize = 4;
/// The minimum buffer size required to serialize any i16 value.
pub const MAX_I16_SIZE: usize = 6;
/// The minimum buffer size required to serialize any i32 value.
pub const MAX_I32_SIZE: usize = 11;
/// The minimum buffer size required to serialize any i64 value.
pub const MAX_I64_SIZE: usize = 20;
/// The minimum buffer size required to serialize any i128 value.
pub const MAX_I128_SIZE: usize = 40;
/// The minimum buffer size required to serialize any u8 value.
pub const MAX_U8_SIZE: usize = 3;
/// The minimum buffer size required to serialize any u16 value.
pub const MAX_U16_SIZE: usize = 5;
/// The minimum buffer size required to serialize any u32 value.
pub const MAX_U32_SIZE: usize = 10;
/// The minimum buffer size required to serialize any u64 value.
pub const MAX_U64_SIZE: usize = 20;
/// The minimum buffer size required to serialize any u128 value.
pub const MAX_U128_SIZE: usize = 39;
/// The minimum buffer size required to serialize any f32 value.
pub const MAX_F32_SIZE: usize = 64;
/// The minimum buffer size required to serialize any f64 value.
pub const MAX_F64_SIZE: usize = 64;
}} // cfg_if
cfg_if! {
if #[cfg(target_pointer_width = "16")] {
/// The minimum buffer size required to serialize any isize value.
pub const MAX_ISIZE_SIZE: usize = MAX_I16_SIZE;
/// The minimum buffer size required to serialize any usize value.
pub const MAX_USIZE_SIZE: usize = MAX_U16_SIZE;
} else if #[cfg(target_pointer_width = "32")] {
/// The minimum buffer size required to serialize any isize value.
pub const MAX_ISIZE_SIZE: usize = MAX_I32_SIZE;
/// The minimum buffer size required to serialize any usize value.
pub const MAX_USIZE_SIZE: usize = MAX_U32_SIZE;
} else if #[cfg(target_pointer_width = "64")] {
/// The minimum buffer size required to serialize any isize value.
pub const MAX_ISIZE_SIZE: usize = MAX_I64_SIZE;
/// The minimum buffer size required to serialize any usize value.
pub const MAX_USIZE_SIZE: usize = MAX_U64_SIZE;
}} // cfg_if
/// The maximum number of bytes that any number-to-string function may write.
pub const BUFFER_SIZE: usize = MAX_F64_SIZE;
// FUNCTIONS
/// Get the exponent notation character.
pub(crate) extern "C" fn exponent_notation_char(radix: u32)
-> u8
{
unsafe {
if radix >= 15 { EXPONENT_BACKUP_CHAR } else { EXPONENT_DEFAULT_CHAR }
}
}
// TEST
// ----
#[cfg(test)]
mod tests {
use atof::*;
use ftoa::*;
use util::*;
use util::test::*;
use super::*;
#[test]
fn exponent_notation_char_test() {
unsafe {
assert_eq!(exponent_notation_char(2), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(8), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(10), EXPONENT_DEFAULT_CHAR);
assert_eq!(exponent_notation_char(15), EXPONENT_BACKUP_CHAR);
assert_eq!(exponent_notation_char(16), EXPONENT_BACKUP_CHAR);
assert_eq!(exponent_notation_char(32), EXPONENT_BACKUP_CHAR);
}
}
// Only enable when no other threads touch NAN_STRING or INFINITY_STRING.
#[test]
#[ignore]
fn special_bytes_test() {
let mut buffer = new_buffer();
// Test serializing and deserializing special strings.
assert!(try_atof32_slice(10, b"NaN").value.is_nan());
assert!(try_atof32_slice(10, b"nan").value.is_nan());
assert!(try_atof32_slice(10, b"NAN").value.is_nan());
assert!(try_atof32_slice(10, b"inf").value.is_infinite());
assert!(try_atof32_slice(10, b"INF").value.is_infinite());
assert!(try_atof32_slice(10, b"Infinity").value.is_infinite());
assert_eq!(f64toa_slice(f64::NAN, 10, &mut buffer), b"NaN");
assert_eq!(f64toa_slice(f64::INFINITY, 10, &mut buffer), b"inf");
unsafe {
NAN_STRING = "nan";
INF_STRING = "Infinity";
}
assert!(try_atof32_slice(10, b"inf").error.code == ErrorCode::InvalidDigit);
assert!(try_atof32_slice(10, b"Infinity").value.is_infinite());
assert_eq!(f64toa_slice(f64::NAN, 10, &mut buffer), b"nan");
assert_eq!(f64toa_slice(f64::INFINITY, 10, &mut buffer), b"Infinity");
unsafe {
NAN_STRING = "NaN";
INF_STRING = "inf";
}
}
}