/* * SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd * * 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 { 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 { 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 for JsonBase32Reader<'x, 'y> {}