lib0/
number.rs

1use crate::decoding::Read;
2use crate::encoding::Write;
3use crate::error::Error;
4use std::convert::TryInto;
5use std::mem::size_of;
6
7pub const F64_MAX_SAFE_INTEGER: f64 = (i64::pow(2, 53) - 1) as f64;
8pub const F64_MIN_SAFE_INTEGER: f64 = -F64_MAX_SAFE_INTEGER;
9
10pub trait VarInt: Sized + Copy {
11    fn write<W: Write>(&self, w: &mut W);
12    fn read<R: Read>(r: &mut R) -> Result<Self, Error>;
13}
14
15impl VarInt for usize {
16    #[inline]
17    fn write<W: Write>(&self, w: &mut W) {
18        write_var_u64(*self as u64, w)
19    }
20
21    #[inline]
22    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
23        Ok(read_var_u64(r)? as Self)
24    }
25}
26
27impl VarInt for u128 {
28    fn write<W: Write>(&self, w: &mut W) {
29        let mut value = *self;
30        while value >= 0b10000000 {
31            let b = ((value & 0b01111111) as u8) | 0b10000000;
32            w.write_u8(b);
33            value = value >> 7;
34        }
35
36        w.write_u8((value & 0b01111111) as u8)
37    }
38
39    #[inline]
40    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
41        let mut num = 0u128;
42        let mut len: usize = 0;
43        loop {
44            let r = r.read_u8()?;
45            num |= u128::wrapping_shl((r & 0b01111111) as u128, len as u32);
46            len += 7;
47            if r < 0b10000000 {
48                return Ok(num);
49            }
50            if len > 180 {
51                return Err(Error::VarIntSizeExceeded(180));
52            }
53        }
54    }
55}
56
57impl VarInt for u64 {
58    #[inline]
59    fn write<W: Write>(&self, w: &mut W) {
60        write_var_u64(*self, w)
61    }
62
63    #[inline]
64    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
65        read_var_u64(r)
66    }
67}
68
69impl VarInt for u32 {
70    #[inline]
71    fn write<W: Write>(&self, w: &mut W) {
72        write_var_u32(*self, w)
73    }
74
75    #[inline]
76    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
77        read_var_u32(r)
78    }
79}
80
81impl VarInt for u16 {
82    #[inline]
83    fn write<W: Write>(&self, w: &mut W) {
84        write_var_u32(*self as u32, w)
85    }
86
87    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
88        let value = read_var_u32(r)?;
89        if let Ok(value) = value.try_into() {
90            Ok(value)
91        } else {
92            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
93        }
94    }
95}
96
97impl VarInt for u8 {
98    #[inline]
99    fn write<W: Write>(&self, w: &mut W) {
100        write_var_u32(*self as u32, w)
101    }
102
103    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
104        let value = read_var_u32(r)?;
105        if let Ok(value) = value.try_into() {
106            Ok(value)
107        } else {
108            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
109        }
110    }
111}
112
113impl VarInt for isize {
114    #[inline]
115    fn write<W: Write>(&self, w: &mut W) {
116        write_var_i64(*self as i64, w)
117    }
118
119    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
120        let value = read_var_i64(r)?;
121        if let Ok(value) = value.try_into() {
122            Ok(value)
123        } else {
124            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
125        }
126    }
127}
128
129impl VarInt for i64 {
130    #[inline]
131    fn write<W: Write>(&self, w: &mut W) {
132        write_var_i64(*self, w)
133    }
134
135    #[inline]
136    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
137        read_var_i64(r)
138    }
139}
140
141impl VarInt for i32 {
142    #[inline]
143    fn write<W: Write>(&self, w: &mut W) {
144        write_var_i64(*self as i64, w)
145    }
146
147    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
148        let value = read_var_i64(r)?;
149        if let Ok(value) = value.try_into() {
150            Ok(value)
151        } else {
152            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
153        }
154    }
155}
156
157impl VarInt for i16 {
158    #[inline]
159    fn write<W: Write>(&self, w: &mut W) {
160        write_var_i64(*self as i64, w)
161    }
162
163    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
164        let value = read_var_i64(r)?;
165        if let Ok(value) = value.try_into() {
166            Ok(value)
167        } else {
168            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
169        }
170    }
171}
172
173impl VarInt for i8 {
174    #[inline]
175    fn write<W: Write>(&self, w: &mut W) {
176        write_var_i64(*self as i64, w)
177    }
178
179    fn read<R: Read>(r: &mut R) -> Result<Self, Error> {
180        let value = read_var_i64(r)?;
181        if let Ok(value) = value.try_into() {
182            Ok(value)
183        } else {
184            Err(Error::VarIntSizeExceeded((size_of::<Self>() * 8) as u8))
185        }
186    }
187}
188
189fn write_var_u32<W: Write>(mut value: u32, w: &mut W) {
190    while value >= 0b10000000 {
191        let b = ((value & 0b01111111) as u8) | 0b10000000;
192        w.write_u8(b);
193        value = value >> 7;
194    }
195
196    w.write_u8((value & 0b01111111) as u8)
197}
198
199fn write_var_u64<W: Write>(mut value: u64, w: &mut W) {
200    while value >= 0b10000000 {
201        let b = ((value & 0b01111111) as u8) | 0b10000000;
202        w.write_u8(b);
203        value = value >> 7;
204    }
205
206    w.write_u8((value & 0b01111111) as u8)
207}
208
209fn write_var_i64<W: Write>(mut value: i64, w: &mut W) {
210    let is_negative = value < 0;
211    value = if is_negative { -value } else { value };
212    w.write_u8(
213        // whether to continue reading
214        (if value > 0b00111111 as i64 { 0b10000000 as u8 } else { 0 })
215            // whether number is negative
216            | (if is_negative { 0b01000000 as u8 } else { 0 })
217            // number
218            | (0b00111111 as i64 & value) as u8,
219    );
220    value >>= 6;
221    while value > 0 {
222        w.write_u8(
223            if value > 0b01111111 as i64 {
224                0b10000000 as u8
225            } else {
226                0
227            } | (0b01111111 as i64 & value) as u8,
228        );
229        value >>= 7;
230    }
231}
232
233fn read_var_u64<R: Read>(r: &mut R) -> Result<u64, Error> {
234    let mut num = 0;
235    let mut len: usize = 0;
236    loop {
237        let r = r.read_u8()?;
238        num |= u64::wrapping_shl((r & 0b01111111) as u64, len as u32);
239        len += 7;
240        if r < 0b10000000 {
241            return Ok(num);
242        }
243        if len > 70 {
244            return Err(Error::VarIntSizeExceeded(70));
245        }
246    }
247}
248
249fn read_var_u32<R: Read>(r: &mut R) -> Result<u32, Error> {
250    let mut num = 0;
251    let mut len: usize = 0;
252    loop {
253        let r = r.read_u8()?;
254        num |= u32::wrapping_shl((r & 0b01111111) as u32, len as u32);
255        len += 7;
256        if r < 0b10000000 {
257            return Ok(num);
258        }
259        if len > 70 {
260            // a proper setting for 32bit int would be 35 bits, however for Yjs compatibility
261            // we allow wrap up up to 64bit ints (with int overflow wrap)
262            return Err(Error::VarIntSizeExceeded(70));
263        }
264    }
265}
266
267fn read_var_i64<R: Read>(reader: &mut R) -> Result<i64, Error> {
268    let mut r = reader.read_u8()?;
269    let mut num = (r & 0b00111111 as u8) as i64;
270    let mut len: u32 = 6;
271    let is_negative = r & 0b01000000 as u8 > 0;
272    if r & 0b10000000 as u8 == 0 {
273        return Ok(if is_negative { -num } else { num });
274    }
275    loop {
276        r = reader.read_u8()?;
277        num |= (r as i64 & 0b01111111 as i64) << len;
278        len += 7;
279        if r < 0b10000000 as u8 {
280            return Ok(if is_negative { -num } else { num });
281        }
282        if len > 70 {
283            return Err(Error::VarIntSizeExceeded(70));
284        }
285    }
286}
287
288pub trait SignedVarInt: Sized + Copy {
289    fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W);
290    fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error>;
291}
292
293/// Struct which recognizes signed integer values. This special case has been build for Yjs encoding
294/// compatibility, which recognizes differences between `0` and `-0`, which is used in some
295/// cases (eg. `UIntOptRleDecoder`).
296#[derive(Debug, Clone, Eq, PartialEq)]
297pub struct Signed<T: Sized + Copy> {
298    value: T,
299    is_negative: bool,
300}
301
302impl<T: Sized + Copy> Signed<T> {
303    pub fn new(value: T, is_negative: bool) -> Self {
304        Signed { value, is_negative }
305    }
306
307    /// Returns true is stored number is a positive value.
308    pub fn is_positive(&self) -> bool {
309        !self.is_negative
310    }
311
312    /// Returns true is stored number is a negative value (including `-0` as a special case).
313    pub fn is_negative(&self) -> bool {
314        self.is_negative
315    }
316
317    /// Returns a stored value.
318    pub fn value(&self) -> T {
319        self.value
320    }
321
322    /// Maps contents of a [Signed] value container to a new data type, retaining the sign
323    /// information.
324    pub fn map<F, U>(&self, f: F) -> Signed<U>
325    where
326        F: FnOnce(T) -> U,
327        U: Sized + Copy,
328    {
329        let mapped = f(self.value);
330        Signed::new(mapped, self.is_negative)
331    }
332}
333
334impl SignedVarInt for i64 {
335    fn write_signed<W: Write>(s: &Signed<Self>, w: &mut W) {
336        let mut value = s.value;
337        let is_negative = s.is_negative;
338        value = if is_negative { -value } else { value };
339        w.write_u8(
340            // whether to continue reading
341            (if value > 0b00111111 as i64 { 0b10000000 as u8 } else { 0 })
342                // whether number is negative
343                | (if is_negative { 0b01000000 as u8 } else { 0 })
344                // number
345                | (0b00111111 as i64 & value) as u8,
346        );
347        value >>= 6;
348        while value > 0 {
349            w.write_u8(
350                if value > 0b01111111 as i64 {
351                    0b10000000 as u8
352                } else {
353                    0
354                } | (0b01111111 as i64 & value) as u8,
355            );
356            value >>= 7;
357        }
358    }
359
360    fn read_signed<R: Read>(reader: &mut R) -> Result<Signed<Self>, Error> {
361        let mut r = reader.read_u8()?;
362        let mut num = (r & 0b00111111 as u8) as i64;
363        let mut len: u32 = 6;
364        let is_negative = r & 0b01000000 as u8 > 0;
365        if r & 0b10000000 as u8 == 0 {
366            let num = if is_negative { -num } else { num };
367            return Ok(Signed::new(num, is_negative));
368        }
369        loop {
370            r = reader.read_u8()?;
371            num |= (r as i64 & 0b01111111 as i64) << len;
372            len += 7;
373            if r < 0b10000000 as u8 {
374                let num = if is_negative { -num } else { num };
375                return Ok(Signed::new(num, is_negative));
376            }
377            if len > 70 {
378                return Err(Error::VarIntSizeExceeded(70));
379            }
380        }
381    }
382}
383
384impl SignedVarInt for isize {
385    fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
386        let value = value.map(|v| v as i64);
387        i64::write_signed(&value, w)
388    }
389
390    fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
391        let result = i64::read_signed(r)?;
392        match result.value.try_into() {
393            Ok(i) => Ok(Signed::new(i, result.is_negative)),
394            Err(_) => Err(Error::VarIntSizeExceeded(70)),
395        }
396    }
397}
398
399impl SignedVarInt for i32 {
400    fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
401        let value = value.map(|v| v as i64);
402        i64::write_signed(&value, w)
403    }
404
405    fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
406        let result = i64::read_signed(r)?;
407        match result.value.try_into() {
408            Ok(i) => Ok(Signed::new(i, result.is_negative)),
409            Err(_) => Err(Error::VarIntSizeExceeded(35)),
410        }
411    }
412}
413
414impl SignedVarInt for i16 {
415    fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
416        let value = value.map(|v| v as i64);
417        i64::write_signed(&value, w)
418    }
419
420    fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
421        let result = i64::read_signed(r)?;
422        match result.value.try_into() {
423            Ok(i) => Ok(Signed::new(i, result.is_negative)),
424            Err(_) => Err(Error::VarIntSizeExceeded(21)),
425        }
426    }
427}
428
429impl SignedVarInt for i8 {
430    fn write_signed<W: Write>(value: &Signed<Self>, w: &mut W) {
431        let value = value.map(|v| v as i64);
432        i64::write_signed(&value, w)
433    }
434
435    fn read_signed<R: Read>(r: &mut R) -> Result<Signed<Self>, Error> {
436        let result = i64::read_signed(r)?;
437        match result.value.try_into() {
438            Ok(i) => Ok(Signed::new(i, result.is_negative)),
439            Err(_) => Err(Error::VarIntSizeExceeded(14)),
440        }
441    }
442}