mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-10-06 18:45:45 +08:00
65 lines
1.8 KiB
Rust
65 lines
1.8 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use utils::codec::{base32_custom::BASE32_INVERSE, leb128::Leb128Iterator};
|
|
|
|
use super::json::Parser;
|
|
|
|
#[derive(Debug)]
|
|
pub struct JsonBase32Reader<'x, 'y> {
|
|
bytes: &'y mut Parser<'x>,
|
|
last_byte: u8,
|
|
pos: usize,
|
|
}
|
|
|
|
impl<'x, 'y> JsonBase32Reader<'x, 'y> {
|
|
pub fn new(bytes: &'y mut Parser<'x>) -> Self {
|
|
JsonBase32Reader {
|
|
bytes,
|
|
pos: 0,
|
|
last_byte: 0,
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn map_byte(&mut self) -> Option<u8> {
|
|
match self.bytes.next_unescaped() {
|
|
Ok(Some(byte)) => match BASE32_INVERSE[byte as usize] {
|
|
decoded_byte if decoded_byte != u8::MAX => {
|
|
self.last_byte = decoded_byte;
|
|
Some(decoded_byte)
|
|
}
|
|
_ => None,
|
|
},
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
pub fn error(&mut self) -> trc::Error {
|
|
self.bytes.error_value()
|
|
}
|
|
}
|
|
|
|
impl<'x, 'y> Iterator for JsonBase32Reader<'x, 'y> {
|
|
type Item = u8;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let pos = self.pos % 5;
|
|
let last_byte = self.last_byte;
|
|
let byte = self.map_byte()?;
|
|
self.pos += 1;
|
|
|
|
match pos {
|
|
0 => ((byte << 3) | (self.map_byte().unwrap_or(0) >> 2)).into(),
|
|
1 => ((last_byte << 6) | (byte << 1) | (self.map_byte().unwrap_or(0) >> 4)).into(),
|
|
2 => ((last_byte << 4) | (byte >> 1)).into(),
|
|
3 => ((last_byte << 7) | (byte << 2) | (self.map_byte().unwrap_or(0) >> 3)).into(),
|
|
4 => ((last_byte << 5) | byte).into(),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'x, 'y> Leb128Iterator<u8> for JsonBase32Reader<'x, 'y> {}
|