| 1 | use std::io::Write;
|
| 2 | use std::mem::size_of;
|
| 3 |
|
| 4 | use super::Options;
|
| 5 | use de::read::BincodeRead;
|
| 6 | use error::{ErrorKind, Result};
|
| 7 |
|
| 8 | pub trait IntEncoding {
|
| 9 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 10 | fn u16_size(n: u16) -> u64;
|
| 11 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 12 | fn u32_size(n: u32) -> u64;
|
| 13 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 14 | fn u64_size(n: u64) -> u64;
|
| 15 |
|
| 16 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 17 | fn i16_size(n: i16) -> u64;
|
| 18 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 19 | fn i32_size(n: i32) -> u64;
|
| 20 | /// Gets the size (in bytes) that a value would be serialized to.
|
| 21 | fn i64_size(n: i64) -> u64;
|
| 22 |
|
| 23 | #[inline (always)]
|
| 24 | fn len_size(len: usize) -> u64 {
|
| 25 | Self::u64_size(len as u64)
|
| 26 | }
|
| 27 |
|
| 28 | /// Serializes a sequence length.
|
| 29 | #[inline (always)]
|
| 30 | fn serialize_len<W: Write, O: Options>(
|
| 31 | ser: &mut ::ser::Serializer<W, O>,
|
| 32 | len: usize,
|
| 33 | ) -> Result<()> {
|
| 34 | Self::serialize_u64(ser, len as u64)
|
| 35 | }
|
| 36 |
|
| 37 | fn serialize_u16<W: Write, O: Options>(
|
| 38 | ser: &mut ::ser::Serializer<W, O>,
|
| 39 | val: u16,
|
| 40 | ) -> Result<()>;
|
| 41 |
|
| 42 | fn serialize_u32<W: Write, O: Options>(
|
| 43 | ser: &mut ::ser::Serializer<W, O>,
|
| 44 | val: u32,
|
| 45 | ) -> Result<()>;
|
| 46 |
|
| 47 | fn serialize_u64<W: Write, O: Options>(
|
| 48 | ser: &mut ::ser::Serializer<W, O>,
|
| 49 | val: u64,
|
| 50 | ) -> Result<()>;
|
| 51 |
|
| 52 | fn serialize_i16<W: Write, O: Options>(
|
| 53 | ser: &mut ::ser::Serializer<W, O>,
|
| 54 | val: i16,
|
| 55 | ) -> Result<()>;
|
| 56 |
|
| 57 | fn serialize_i32<W: Write, O: Options>(
|
| 58 | ser: &mut ::ser::Serializer<W, O>,
|
| 59 | val: i32,
|
| 60 | ) -> Result<()>;
|
| 61 |
|
| 62 | fn serialize_i64<W: Write, O: Options>(
|
| 63 | ser: &mut ::ser::Serializer<W, O>,
|
| 64 | val: i64,
|
| 65 | ) -> Result<()>;
|
| 66 |
|
| 67 | /// Deserializes a sequence length.
|
| 68 | #[inline (always)]
|
| 69 | fn deserialize_len<'de, R: BincodeRead<'de>, O: Options>(
|
| 70 | de: &mut ::de::Deserializer<R, O>,
|
| 71 | ) -> Result<usize> {
|
| 72 | Self::deserialize_u64(de).and_then(cast_u64_to_usize)
|
| 73 | }
|
| 74 |
|
| 75 | fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
|
| 76 | de: &mut ::de::Deserializer<R, O>,
|
| 77 | ) -> Result<u16>;
|
| 78 |
|
| 79 | fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
|
| 80 | de: &mut ::de::Deserializer<R, O>,
|
| 81 | ) -> Result<u32>;
|
| 82 |
|
| 83 | fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
|
| 84 | de: &mut ::de::Deserializer<R, O>,
|
| 85 | ) -> Result<u64>;
|
| 86 |
|
| 87 | fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
|
| 88 | de: &mut ::de::Deserializer<R, O>,
|
| 89 | ) -> Result<i16>;
|
| 90 |
|
| 91 | fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
|
| 92 | de: &mut ::de::Deserializer<R, O>,
|
| 93 | ) -> Result<i32>;
|
| 94 |
|
| 95 | fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
|
| 96 | de: &mut ::de::Deserializer<R, O>,
|
| 97 | ) -> Result<i64>;
|
| 98 |
|
| 99 | serde_if_integer128! {
|
| 100 | fn u128_size(v: u128) -> u64;
|
| 101 | fn i128_size(v: i128) -> u64;
|
| 102 | fn serialize_u128<W: Write, O: Options>(
|
| 103 | ser: &mut ::Serializer<W, O>,
|
| 104 | val: u128,
|
| 105 | ) -> Result<()>;
|
| 106 | fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
|
| 107 | de: &mut ::Deserializer<R, O>,
|
| 108 | ) -> Result<u128>;
|
| 109 | fn serialize_i128<W: Write, O: Options>(
|
| 110 | ser: &mut ::Serializer<W, O>,
|
| 111 | val: i128,
|
| 112 | ) -> Result<()>;
|
| 113 | fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
|
| 114 | de: &mut ::Deserializer<R, O>,
|
| 115 | ) -> Result<i128>;
|
| 116 | }
|
| 117 | }
|
| 118 |
|
| 119 | /// Fixed-size integer encoding.
|
| 120 | ///
|
| 121 | /// * Fixed size integers are encoded directly
|
| 122 | /// * Enum discriminants are encoded as u32
|
| 123 | /// * Lengths and usize are encoded as u64
|
| 124 | #[derive (Copy, Clone)]
|
| 125 | pub struct FixintEncoding;
|
| 126 |
|
| 127 | /// Variable-size integer encoding (excepting [ui]8).
|
| 128 | ///
|
| 129 | /// Encoding an unsigned integer v (of any type excepting u8) works as follows:
|
| 130 | ///
|
| 131 | /// 1. If `u < 251`, encode it as a single byte with that value.
|
| 132 | /// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`.
|
| 133 | /// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`.
|
| 134 | /// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`.
|
| 135 | /// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a
|
| 136 | /// u128 with value `u`.
|
| 137 | ///
|
| 138 | /// Then, for signed integers, we first convert to unsigned using the zigzag algorithm,
|
| 139 | /// and then encode them as we do for unsigned integers generally. The reason we use this
|
| 140 | /// algorithm is that it encodes those values which are close to zero in less bytes; the
|
| 141 | /// obvious algorithm, where we encode the cast values, gives a very large encoding for all
|
| 142 | /// negative values.
|
| 143 | ///
|
| 144 | /// The zigzag algorithm is defined as follows:
|
| 145 | ///
|
| 146 | /// ```ignore
|
| 147 | /// fn zigzag(v: Signed) -> Unsigned {
|
| 148 | /// match v {
|
| 149 | /// 0 => 0,
|
| 150 | /// v if v < 0 => |v| * 2 - 1
|
| 151 | /// v if v > 0 => v * 2
|
| 152 | /// }
|
| 153 | /// }
|
| 154 | /// ```
|
| 155 | ///
|
| 156 | /// And works such that:
|
| 157 | ///
|
| 158 | /// ```ignore
|
| 159 | /// assert_eq!(zigzag(0), 0);
|
| 160 | /// assert_eq!(zigzag(-1), 1);
|
| 161 | /// assert_eq!(zigzag(1), 2);
|
| 162 | /// assert_eq!(zigzag(-2), 3);
|
| 163 | /// assert_eq!(zigzag(2), 4);
|
| 164 | /// assert_eq!(zigzag(i64::min_value()), u64::max_value());
|
| 165 | /// ```
|
| 166 | ///
|
| 167 | /// Note that u256 and the like are unsupported by this format; if and when they are added to the
|
| 168 | /// language, they may be supported via the extension point given by the 255 byte.
|
| 169 | #[derive (Copy, Clone)]
|
| 170 | pub struct VarintEncoding;
|
| 171 |
|
| 172 | const SINGLE_BYTE_MAX: u8 = 250;
|
| 173 | const U16_BYTE: u8 = 251;
|
| 174 | const U32_BYTE: u8 = 252;
|
| 175 | const U64_BYTE: u8 = 253;
|
| 176 | const U128_BYTE: u8 = 254;
|
| 177 | const DESERIALIZE_EXTENSION_POINT_ERR: &str = r#"
|
| 178 | Byte 255 is treated as an extension point; it should not be encoding anything.
|
| 179 | Do you have a mismatched bincode version or configuration?
|
| 180 | "# ;
|
| 181 |
|
| 182 | impl VarintEncoding {
|
| 183 | fn varint_size(n: u64) -> u64 {
|
| 184 | if n <= SINGLE_BYTE_MAX as u64 {
|
| 185 | 1
|
| 186 | } else if n <= u16::max_value() as u64 {
|
| 187 | (1 + size_of::<u16>()) as u64
|
| 188 | } else if n <= u32::max_value() as u64 {
|
| 189 | (1 + size_of::<u32>()) as u64
|
| 190 | } else {
|
| 191 | (1 + size_of::<u64>()) as u64
|
| 192 | }
|
| 193 | }
|
| 194 |
|
| 195 | #[inline (always)]
|
| 196 | fn zigzag_encode(n: i64) -> u64 {
|
| 197 | if n < 0 {
|
| 198 | // let's avoid the edge case of i64::min_value()
|
| 199 | // !n is equal to `-n - 1`, so this is:
|
| 200 | // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1
|
| 201 | !(n as u64) * 2 + 1
|
| 202 | } else {
|
| 203 | (n as u64) * 2
|
| 204 | }
|
| 205 | }
|
| 206 |
|
| 207 | #[inline (always)]
|
| 208 | fn zigzag_decode(n: u64) -> i64 {
|
| 209 | if n % 2 == 0 {
|
| 210 | // positive number
|
| 211 | (n / 2) as i64
|
| 212 | } else {
|
| 213 | // negative number
|
| 214 | // !m * 2 + 1 = n
|
| 215 | // !m * 2 = n - 1
|
| 216 | // !m = (n - 1) / 2
|
| 217 | // m = !((n - 1) / 2)
|
| 218 | // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2)
|
| 219 | !(n / 2) as i64
|
| 220 | }
|
| 221 | }
|
| 222 |
|
| 223 | fn serialize_varint<W: Write, O: Options>(
|
| 224 | ser: &mut ::ser::Serializer<W, O>,
|
| 225 | n: u64,
|
| 226 | ) -> Result<()> {
|
| 227 | if n <= SINGLE_BYTE_MAX as u64 {
|
| 228 | ser.serialize_byte(n as u8)
|
| 229 | } else if n <= u16::max_value() as u64 {
|
| 230 | ser.serialize_byte(U16_BYTE)?;
|
| 231 | ser.serialize_literal_u16(n as u16)
|
| 232 | } else if n <= u32::max_value() as u64 {
|
| 233 | ser.serialize_byte(U32_BYTE)?;
|
| 234 | ser.serialize_literal_u32(n as u32)
|
| 235 | } else {
|
| 236 | ser.serialize_byte(U64_BYTE)?;
|
| 237 | ser.serialize_literal_u64(n as u64)
|
| 238 | }
|
| 239 | }
|
| 240 |
|
| 241 | fn deserialize_varint<'de, R: BincodeRead<'de>, O: Options>(
|
| 242 | de: &mut ::de::Deserializer<R, O>,
|
| 243 | ) -> Result<u64> {
|
| 244 | #[allow (ellipsis_inclusive_range_patterns)]
|
| 245 | match de.deserialize_byte()? {
|
| 246 | byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u64),
|
| 247 | U16_BYTE => Ok(de.deserialize_literal_u16()? as u64),
|
| 248 | U32_BYTE => Ok(de.deserialize_literal_u32()? as u64),
|
| 249 | U64_BYTE => de.deserialize_literal_u64(),
|
| 250 | U128_BYTE => Err(Box::new(ErrorKind::Custom(
|
| 251 | "Invalid value (u128 range): you may have a version or configuration disagreement?"
|
| 252 | .to_string(),
|
| 253 | ))),
|
| 254 | _ => Err(Box::new(ErrorKind::Custom(
|
| 255 | DESERIALIZE_EXTENSION_POINT_ERR.to_string(),
|
| 256 | ))),
|
| 257 | }
|
| 258 | }
|
| 259 |
|
| 260 | serde_if_integer128! {
|
| 261 | // see zigzag_encode and zigzag_decode for implementation comments
|
| 262 | #[inline (always)]
|
| 263 | fn zigzag128_encode(n: i128) -> u128 {
|
| 264 | if n < 0 {
|
| 265 | !(n as u128) * 2 + 1
|
| 266 | } else {
|
| 267 | (n as u128) * 2
|
| 268 | }
|
| 269 | }
|
| 270 | #[inline (always)]
|
| 271 | fn zigzag128_decode(n: u128) -> i128 {
|
| 272 | if n % 2 == 0 {
|
| 273 | (n / 2) as i128
|
| 274 | } else {
|
| 275 | !(n / 2) as i128
|
| 276 | }
|
| 277 | }
|
| 278 |
|
| 279 | fn varint128_size(n: u128) -> u64 {
|
| 280 | if n <= SINGLE_BYTE_MAX as u128 {
|
| 281 | 1
|
| 282 | } else if n <= u16::max_value() as u128 {
|
| 283 | (1 + size_of::<u16>()) as u64
|
| 284 | } else if n <= u32::max_value() as u128 {
|
| 285 | (1 + size_of::<u32>()) as u64
|
| 286 | } else if n <= u64::max_value() as u128 {
|
| 287 | (1 + size_of::<u64>()) as u64
|
| 288 | } else {
|
| 289 | (1 + size_of::<u128>()) as u64
|
| 290 | }
|
| 291 | }
|
| 292 |
|
| 293 | fn serialize_varint128<W: Write, O: Options>(
|
| 294 | ser: &mut ::ser::Serializer<W, O>,
|
| 295 | n: u128,
|
| 296 | ) -> Result<()> {
|
| 297 | if n <= SINGLE_BYTE_MAX as u128 {
|
| 298 | ser.serialize_byte(n as u8)
|
| 299 | } else if n <= u16::max_value() as u128 {
|
| 300 | ser.serialize_byte(U16_BYTE)?;
|
| 301 | ser.serialize_literal_u16(n as u16)
|
| 302 | } else if n <= u32::max_value() as u128 {
|
| 303 | ser.serialize_byte(U32_BYTE)?;
|
| 304 | ser.serialize_literal_u32(n as u32)
|
| 305 | } else if n <= u64::max_value() as u128 {
|
| 306 | ser.serialize_byte(U64_BYTE)?;
|
| 307 | ser.serialize_literal_u64(n as u64)
|
| 308 | } else {
|
| 309 | ser.serialize_byte(U128_BYTE)?;
|
| 310 | ser.serialize_literal_u128(n)
|
| 311 | }
|
| 312 | }
|
| 313 |
|
| 314 | fn deserialize_varint128<'de, R: BincodeRead<'de>, O: Options>(
|
| 315 | de: &mut ::de::Deserializer<R, O>,
|
| 316 | ) -> Result<u128> {
|
| 317 | #[allow (ellipsis_inclusive_range_patterns)]
|
| 318 | match de.deserialize_byte()? {
|
| 319 | byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u128),
|
| 320 | U16_BYTE => Ok(de.deserialize_literal_u16()? as u128),
|
| 321 | U32_BYTE => Ok(de.deserialize_literal_u32()? as u128),
|
| 322 | U64_BYTE => Ok(de.deserialize_literal_u64()? as u128),
|
| 323 | U128_BYTE => de.deserialize_literal_u128(),
|
| 324 | _ => Err(Box::new(ErrorKind::Custom(DESERIALIZE_EXTENSION_POINT_ERR.to_string()))),
|
| 325 | }
|
| 326 | }
|
| 327 | }
|
| 328 | }
|
| 329 |
|
| 330 | impl IntEncoding for FixintEncoding {
|
| 331 | #[inline (always)]
|
| 332 | fn u16_size(_: u16) -> u64 {
|
| 333 | size_of::<u16>() as u64
|
| 334 | }
|
| 335 | #[inline (always)]
|
| 336 | fn u32_size(_: u32) -> u64 {
|
| 337 | size_of::<u32>() as u64
|
| 338 | }
|
| 339 | #[inline (always)]
|
| 340 | fn u64_size(_: u64) -> u64 {
|
| 341 | size_of::<u64>() as u64
|
| 342 | }
|
| 343 |
|
| 344 | #[inline (always)]
|
| 345 | fn i16_size(_: i16) -> u64 {
|
| 346 | size_of::<i16>() as u64
|
| 347 | }
|
| 348 | #[inline (always)]
|
| 349 | fn i32_size(_: i32) -> u64 {
|
| 350 | size_of::<i32>() as u64
|
| 351 | }
|
| 352 | #[inline (always)]
|
| 353 | fn i64_size(_: i64) -> u64 {
|
| 354 | size_of::<i64>() as u64
|
| 355 | }
|
| 356 |
|
| 357 | #[inline (always)]
|
| 358 | fn serialize_u16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u16) -> Result<()> {
|
| 359 | ser.serialize_literal_u16(val)
|
| 360 | }
|
| 361 | #[inline (always)]
|
| 362 | fn serialize_u32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u32) -> Result<()> {
|
| 363 | ser.serialize_literal_u32(val)
|
| 364 | }
|
| 365 | #[inline (always)]
|
| 366 | fn serialize_u64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u64) -> Result<()> {
|
| 367 | ser.serialize_literal_u64(val)
|
| 368 | }
|
| 369 |
|
| 370 | #[inline (always)]
|
| 371 | fn serialize_i16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i16) -> Result<()> {
|
| 372 | ser.serialize_literal_u16(val as u16)
|
| 373 | }
|
| 374 | #[inline (always)]
|
| 375 | fn serialize_i32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i32) -> Result<()> {
|
| 376 | ser.serialize_literal_u32(val as u32)
|
| 377 | }
|
| 378 | #[inline (always)]
|
| 379 | fn serialize_i64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i64) -> Result<()> {
|
| 380 | ser.serialize_literal_u64(val as u64)
|
| 381 | }
|
| 382 |
|
| 383 | #[inline (always)]
|
| 384 | fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
|
| 385 | de: &mut ::Deserializer<R, O>,
|
| 386 | ) -> Result<u16> {
|
| 387 | de.deserialize_literal_u16()
|
| 388 | }
|
| 389 | #[inline (always)]
|
| 390 | fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
|
| 391 | de: &mut ::Deserializer<R, O>,
|
| 392 | ) -> Result<u32> {
|
| 393 | de.deserialize_literal_u32()
|
| 394 | }
|
| 395 | #[inline (always)]
|
| 396 | fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
|
| 397 | de: &mut ::Deserializer<R, O>,
|
| 398 | ) -> Result<u64> {
|
| 399 | de.deserialize_literal_u64()
|
| 400 | }
|
| 401 |
|
| 402 | #[inline (always)]
|
| 403 | fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
|
| 404 | de: &mut ::Deserializer<R, O>,
|
| 405 | ) -> Result<i16> {
|
| 406 | Ok(de.deserialize_literal_u16()? as i16)
|
| 407 | }
|
| 408 | #[inline (always)]
|
| 409 | fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
|
| 410 | de: &mut ::Deserializer<R, O>,
|
| 411 | ) -> Result<i32> {
|
| 412 | Ok(de.deserialize_literal_u32()? as i32)
|
| 413 | }
|
| 414 | #[inline (always)]
|
| 415 | fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
|
| 416 | de: &mut ::Deserializer<R, O>,
|
| 417 | ) -> Result<i64> {
|
| 418 | Ok(de.deserialize_literal_u64()? as i64)
|
| 419 | }
|
| 420 |
|
| 421 | serde_if_integer128! {
|
| 422 | #[inline (always)]
|
| 423 | fn u128_size(_: u128) -> u64{
|
| 424 | size_of::<u128>() as u64
|
| 425 | }
|
| 426 | #[inline (always)]
|
| 427 | fn i128_size(_: i128) -> u64{
|
| 428 | size_of::<i128>() as u64
|
| 429 | }
|
| 430 |
|
| 431 | #[inline (always)]
|
| 432 | fn serialize_u128<W: Write, O: Options>(
|
| 433 | ser: &mut ::Serializer<W, O>,
|
| 434 | val: u128,
|
| 435 | ) -> Result<()> {
|
| 436 | ser.serialize_literal_u128(val)
|
| 437 | }
|
| 438 | #[inline (always)]
|
| 439 | fn serialize_i128<W: Write, O: Options>(
|
| 440 | ser: &mut ::Serializer<W, O>,
|
| 441 | val: i128,
|
| 442 | ) -> Result<()> {
|
| 443 | ser.serialize_literal_u128(val as u128)
|
| 444 | }
|
| 445 | #[inline (always)]
|
| 446 | fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
|
| 447 | de: &mut ::Deserializer<R, O>,
|
| 448 | ) -> Result<u128> {
|
| 449 | de.deserialize_literal_u128()
|
| 450 | }
|
| 451 | #[inline (always)]
|
| 452 | fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
|
| 453 | de: &mut ::Deserializer<R, O>,
|
| 454 | ) -> Result<i128> {
|
| 455 | Ok(de.deserialize_literal_u128()? as i128)
|
| 456 | }
|
| 457 | }
|
| 458 | }
|
| 459 |
|
| 460 | impl IntEncoding for VarintEncoding {
|
| 461 | #[inline (always)]
|
| 462 | fn u16_size(n: u16) -> u64 {
|
| 463 | Self::varint_size(n as u64)
|
| 464 | }
|
| 465 | #[inline (always)]
|
| 466 | fn u32_size(n: u32) -> u64 {
|
| 467 | Self::varint_size(n as u64)
|
| 468 | }
|
| 469 | #[inline (always)]
|
| 470 | fn u64_size(n: u64) -> u64 {
|
| 471 | Self::varint_size(n)
|
| 472 | }
|
| 473 |
|
| 474 | #[inline (always)]
|
| 475 | fn i16_size(n: i16) -> u64 {
|
| 476 | Self::varint_size(Self::zigzag_encode(n as i64))
|
| 477 | }
|
| 478 | #[inline (always)]
|
| 479 | fn i32_size(n: i32) -> u64 {
|
| 480 | Self::varint_size(Self::zigzag_encode(n as i64))
|
| 481 | }
|
| 482 | #[inline (always)]
|
| 483 | fn i64_size(n: i64) -> u64 {
|
| 484 | Self::varint_size(Self::zigzag_encode(n))
|
| 485 | }
|
| 486 |
|
| 487 | #[inline (always)]
|
| 488 | fn serialize_u16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u16) -> Result<()> {
|
| 489 | Self::serialize_varint(ser, val as u64)
|
| 490 | }
|
| 491 | #[inline (always)]
|
| 492 | fn serialize_u32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u32) -> Result<()> {
|
| 493 | Self::serialize_varint(ser, val as u64)
|
| 494 | }
|
| 495 | #[inline (always)]
|
| 496 | fn serialize_u64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: u64) -> Result<()> {
|
| 497 | Self::serialize_varint(ser, val)
|
| 498 | }
|
| 499 |
|
| 500 | #[inline (always)]
|
| 501 | fn serialize_i16<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i16) -> Result<()> {
|
| 502 | Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
|
| 503 | }
|
| 504 | #[inline (always)]
|
| 505 | fn serialize_i32<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i32) -> Result<()> {
|
| 506 | Self::serialize_varint(ser, Self::zigzag_encode(val as i64))
|
| 507 | }
|
| 508 | #[inline (always)]
|
| 509 | fn serialize_i64<W: Write, O: Options>(ser: &mut ::Serializer<W, O>, val: i64) -> Result<()> {
|
| 510 | Self::serialize_varint(ser, Self::zigzag_encode(val))
|
| 511 | }
|
| 512 |
|
| 513 | #[inline (always)]
|
| 514 | fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>(
|
| 515 | de: &mut ::Deserializer<R, O>,
|
| 516 | ) -> Result<u16> {
|
| 517 | Self::deserialize_varint(de).and_then(cast_u64_to_u16)
|
| 518 | }
|
| 519 | #[inline (always)]
|
| 520 | fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>(
|
| 521 | de: &mut ::Deserializer<R, O>,
|
| 522 | ) -> Result<u32> {
|
| 523 | Self::deserialize_varint(de).and_then(cast_u64_to_u32)
|
| 524 | }
|
| 525 | #[inline (always)]
|
| 526 | fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>(
|
| 527 | de: &mut ::Deserializer<R, O>,
|
| 528 | ) -> Result<u64> {
|
| 529 | Self::deserialize_varint(de)
|
| 530 | }
|
| 531 |
|
| 532 | #[inline (always)]
|
| 533 | fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>(
|
| 534 | de: &mut ::Deserializer<R, O>,
|
| 535 | ) -> Result<i16> {
|
| 536 | Self::deserialize_varint(de)
|
| 537 | .map(Self::zigzag_decode)
|
| 538 | .and_then(cast_i64_to_i16)
|
| 539 | }
|
| 540 | #[inline (always)]
|
| 541 | fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>(
|
| 542 | de: &mut ::Deserializer<R, O>,
|
| 543 | ) -> Result<i32> {
|
| 544 | Self::deserialize_varint(de)
|
| 545 | .map(Self::zigzag_decode)
|
| 546 | .and_then(cast_i64_to_i32)
|
| 547 | }
|
| 548 | #[inline (always)]
|
| 549 | fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>(
|
| 550 | de: &mut ::Deserializer<R, O>,
|
| 551 | ) -> Result<i64> {
|
| 552 | Self::deserialize_varint(de).map(Self::zigzag_decode)
|
| 553 | }
|
| 554 |
|
| 555 | serde_if_integer128! {
|
| 556 | #[inline (always)]
|
| 557 | fn u128_size(n: u128) -> u64 {
|
| 558 | Self::varint128_size(n)
|
| 559 | }
|
| 560 | #[inline (always)]
|
| 561 | fn i128_size(n: i128) -> u64 {
|
| 562 | Self::varint128_size(Self::zigzag128_encode(n))
|
| 563 | }
|
| 564 | #[inline (always)]
|
| 565 | fn serialize_u128<W: Write, O: Options>(
|
| 566 | ser: &mut ::Serializer<W, O>,
|
| 567 | val: u128,
|
| 568 | ) -> Result<()> {
|
| 569 | Self::serialize_varint128(ser, val)
|
| 570 | }
|
| 571 | #[inline (always)]
|
| 572 | fn serialize_i128<W: Write, O: Options>(
|
| 573 | ser: &mut ::Serializer<W, O>,
|
| 574 | val: i128,
|
| 575 | ) -> Result<()> {
|
| 576 | Self::serialize_varint128(ser, Self::zigzag128_encode(val))
|
| 577 | }
|
| 578 | #[inline (always)]
|
| 579 | fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>(
|
| 580 | de: &mut ::Deserializer<R, O>,
|
| 581 | ) -> Result<u128> {
|
| 582 | Self::deserialize_varint128(de)
|
| 583 | }
|
| 584 | #[inline (always)]
|
| 585 | fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>(
|
| 586 | de: &mut ::Deserializer<R, O>,
|
| 587 | ) -> Result<i128> {
|
| 588 | Self::deserialize_varint128(de).map(Self::zigzag128_decode)
|
| 589 | }
|
| 590 | }
|
| 591 | }
|
| 592 |
|
| 593 | fn cast_u64_to_usize(n: u64) -> Result<usize> {
|
| 594 | if n <= usize::max_value() as u64 {
|
| 595 | Ok(n as usize)
|
| 596 | } else {
|
| 597 | Err(Box::new(ErrorKind::Custom(format!(
|
| 598 | "Invalid size {}: sizes must fit in a usize (0 to {})" ,
|
| 599 | n,
|
| 600 | usize::max_value()
|
| 601 | ))))
|
| 602 | }
|
| 603 | }
|
| 604 | fn cast_u64_to_u32(n: u64) -> Result<u32> {
|
| 605 | if n <= u32::max_value() as u64 {
|
| 606 | Ok(n as u32)
|
| 607 | } else {
|
| 608 | Err(Box::new(ErrorKind::Custom(format!(
|
| 609 | "Invalid u32 {}: you may have a version disagreement?" ,
|
| 610 | n,
|
| 611 | ))))
|
| 612 | }
|
| 613 | }
|
| 614 | fn cast_u64_to_u16(n: u64) -> Result<u16> {
|
| 615 | if n <= u16::max_value() as u64 {
|
| 616 | Ok(n as u16)
|
| 617 | } else {
|
| 618 | Err(Box::new(ErrorKind::Custom(format!(
|
| 619 | "Invalid u16 {}: you may have a version disagreement?" ,
|
| 620 | n,
|
| 621 | ))))
|
| 622 | }
|
| 623 | }
|
| 624 |
|
| 625 | fn cast_i64_to_i32(n: i64) -> Result<i32> {
|
| 626 | if n <= i32::max_value() as i64 && n >= i32::min_value() as i64 {
|
| 627 | Ok(n as i32)
|
| 628 | } else {
|
| 629 | Err(Box::new(ErrorKind::Custom(format!(
|
| 630 | "Invalid i32 {}: you may have a version disagreement?" ,
|
| 631 | n,
|
| 632 | ))))
|
| 633 | }
|
| 634 | }
|
| 635 |
|
| 636 | fn cast_i64_to_i16(n: i64) -> Result<i16> {
|
| 637 | if n <= i16::max_value() as i64 && n >= i16::min_value() as i64 {
|
| 638 | Ok(n as i16)
|
| 639 | } else {
|
| 640 | Err(Box::new(ErrorKind::Custom(format!(
|
| 641 | "Invalid i16 {}: you may have a version disagreement?" ,
|
| 642 | n,
|
| 643 | ))))
|
| 644 | }
|
| 645 | }
|
| 646 |
|
| 647 | #[cfg (test)]
|
| 648 | mod test {
|
| 649 | use super::VarintEncoding;
|
| 650 |
|
| 651 | #[test ]
|
| 652 | fn test_zigzag_encode() {
|
| 653 | let zigzag = VarintEncoding::zigzag_encode;
|
| 654 |
|
| 655 | assert_eq!(zigzag(0), 0);
|
| 656 | for x in 1..512 {
|
| 657 | assert_eq!(zigzag(x), (x as u64) * 2);
|
| 658 | assert_eq!(zigzag(-x), (x as u64) * 2 - 1);
|
| 659 | }
|
| 660 | }
|
| 661 |
|
| 662 | #[test ]
|
| 663 | fn test_zigzag_decode() {
|
| 664 | // zigzag'
|
| 665 | let zigzagp = VarintEncoding::zigzag_decode;
|
| 666 | for x in (0..512).map(|x| x * 2) {
|
| 667 | assert_eq!(zigzagp(x), x as i64 / 2);
|
| 668 | assert_eq!(zigzagp(x + 1), -(x as i64) / 2 - 1);
|
| 669 | }
|
| 670 | }
|
| 671 |
|
| 672 | #[test ]
|
| 673 | fn test_zigzag_edge_cases() {
|
| 674 | let (zigzag, zigzagp) = (VarintEncoding::zigzag_encode, VarintEncoding::zigzag_decode);
|
| 675 |
|
| 676 | assert_eq!(zigzag(i64::max_value()), u64::max_value() - 1);
|
| 677 | assert_eq!(zigzag(i64::min_value()), u64::max_value());
|
| 678 |
|
| 679 | assert_eq!(zigzagp(u64::max_value() - 1), i64::max_value());
|
| 680 | assert_eq!(zigzagp(u64::max_value()), i64::min_value());
|
| 681 | }
|
| 682 | }
|
| 683 | |