rmp/encode/uint.rs
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
use super::{write_marker, RmpWrite};
use crate::encode::ValueWriteError;
use crate::Marker;
/// Encodes and attempts to write an unsigned small integer value as a positive fixint into the
/// given write.
///
/// According to the MessagePack specification, a positive fixed integer value is represented using
/// a single byte in `[0x00; 0x7f]` range inclusively, prepended with a special marker mask.
///
/// The function is **strict** with the input arguments - it is the user's responsibility to check
/// if the value fits in the described range, otherwise it will panic.
///
/// If you are not sure if the value fits in the given range use `write_uint` instead, which
/// automatically selects the most compact integer representation.
///
/// # Errors
///
/// This function will return `FixedValueWriteError` on any I/O error occurred while writing the
/// positive integer marker.
///
/// # Panics
///
/// Panics if `val` is greater than 127.
#[inline]
pub fn write_pfix<W: RmpWrite>(wr: &mut W, val: u8) -> Result<(), W::Error> {
assert!(val < 128);
write_marker(wr, Marker::FixPos(val)).map_err(|e| e.0)?;
Ok(())
}
/// Encodes and attempts to write an `u8` value as a 2-byte sequence into the given write.
///
/// The first byte becomes the marker and the second one will represent the data itself.
///
/// Note, that this function will encode the given value in 2-byte sequence no matter what, even if
/// the value can be represented using single byte as a positive fixnum.
///
/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
/// selects the appropriate integer representation.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data.
///
/// # Examples
/// ```
/// let mut buf = [0x00, 0x00];
///
/// rmp::encode::write_u8(&mut &mut buf[..], 146).ok().unwrap();
/// assert_eq!([0xcc, 0x92], buf);
///
/// // Note, that 42 can be represented simply as `[0x2a]`, but the function emits 2-byte sequence.
/// rmp::encode::write_u8(&mut &mut buf[..], 42).ok().unwrap();
/// assert_eq!([0xcc, 0x2a], buf);
/// ```
pub fn write_u8<W: RmpWrite>(wr: &mut W, val: u8) -> Result<(), ValueWriteError<W::Error>> {
write_marker(wr, Marker::U8)?;
wr.write_data_u8(val)?;
Ok(())
}
/// Encodes and attempts to write an `u16` value strictly as a 3-byte sequence into the given write.
///
/// The first byte becomes the marker and the others will represent the data itself.
///
/// Note, that this function will encode the given value in 3-byte sequence no matter what, even if
/// the value can be represented using single byte as a positive fixnum.
///
/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
/// selects the appropriate integer representation.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data.
pub fn write_u16<W: RmpWrite>(wr: &mut W, val: u16) -> Result<(), ValueWriteError<W::Error>> {
write_marker(wr, Marker::U16)?;
wr.write_data_u16(val)?;
Ok(())
}
/// Encodes and attempts to write an `u32` value strictly as a 5-byte sequence into the given write.
///
/// The first byte becomes the marker and the others will represent the data itself.
///
/// Note, that this function will encode the given value in 5-byte sequence no matter what, even if
/// the value can be represented using single byte as a positive fixnum.
///
/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
/// selects the appropriate integer representation.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data.
pub fn write_u32<W: RmpWrite>(wr: &mut W, val: u32) -> Result<(), ValueWriteError<W::Error>> {
write_marker(wr, Marker::U32)?;
wr.write_data_u32(val)?;
Ok(())
}
/// Encodes and attempts to write an `u64` value strictly as a 9-byte sequence into the given write.
///
/// The first byte becomes the marker and the others will represent the data itself.
///
/// Note, that this function will encode the given value in 9-byte sequence no matter what, even if
/// the value can be represented using single byte as a positive fixnum.
///
/// If you need to fit the given buffer efficiently use `write_uint` instead, which automatically
/// selects the appropriate integer representation.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data.
pub fn write_u64<W: RmpWrite>(wr: &mut W, val: u64) -> Result<(), ValueWriteError<W::Error>> {
write_marker(wr, Marker::U64)?;
wr.write_data_u64(val)?;
Ok(())
}
/// Encodes and attempts to write an `u8` value into the given write using the most efficient
/// representation, returning the marker used.
///
/// See [`write_uint`] for more info.
pub fn write_uint8<W: RmpWrite>(wr: &mut W, val: u8) -> Result<Marker, ValueWriteError<W::Error>> {
if val < 128 {
write_pfix(wr, val)
.and(Ok(Marker::FixPos(val)))
.map_err(ValueWriteError::InvalidMarkerWrite)
} else {
write_u8(wr, val).and(Ok(Marker::U8))
}
}
/// Encodes and attempts to write an `u64` value into the given write using the most efficient
/// representation, returning the marker used.
///
/// This function obeys the MessagePack specification, which requires that the serializer SHOULD use
/// the format which represents the data in the smallest number of bytes.
///
/// The first byte becomes the marker and the others (if present, up to 9) will represent the data
/// itself.
///
/// # Errors
///
/// This function will return `ValueWriteError` on any I/O error occurred while writing either the
/// marker or the data.
pub fn write_uint<W: RmpWrite>(wr: &mut W, val: u64) -> Result<Marker, ValueWriteError<W::Error>> {
if val < 256 {
write_uint8(wr, val as u8)
} else if val < 65536 {
write_u16(wr, val as u16).and(Ok(Marker::U16))
} else if val < 4294967296 {
write_u32(wr, val as u32).and(Ok(Marker::U32))
} else {
write_u64(wr, val).and(Ok(Marker::U64))
}
}