diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index f97df4cb2b..1e04905405 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -220,8 +220,6 @@ def test_hqx(self): res = binascii.rledecode_hqx(b) self.assertEqual(res, self.rawdata) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_rle(self): # test repetition with a repetition longer than the limit of 255 data = (b'a' * 100 + b'b' + b'c' * 300) diff --git a/stdlib/src/binascii.rs b/stdlib/src/binascii.rs index 21f3a80f8b..f38314b13d 100644 --- a/stdlib/src/binascii.rs +++ b/stdlib/src/binascii.rs @@ -182,6 +182,73 @@ mod decl { Ok((*c - 0x20) & 0x3f) } + #[pyfunction] + fn rlecode_hqx(s: ArgAsciiBuffer) -> PyResult> { + const RUNCHAR: u8 = 0x90; // b'\x90' + s.with_ref(|buffer| { + let len = buffer.len(); + let mut out_data = Vec::::with_capacity((len * 2) + 2); + + let mut idx = 0; + while idx < len { + let ch = buffer[idx]; + + if ch == RUNCHAR { + out_data.push(RUNCHAR); + out_data.push(0); + return Ok(out_data); + } else { + let mut inend = idx + 1; + while inend < len && buffer[inend] == ch && inend < idx + 255 { + inend += 1; + } + if inend - idx > 3 { + out_data.push(ch); + out_data.push(RUNCHAR); + out_data.push(((inend - idx) % 256) as u8); + idx = inend - 1; + } else { + out_data.push(ch); + } + } + idx += 1; + } + Ok(out_data) + }) + } + + #[pyfunction] + fn rledecode_hqx(s: ArgAsciiBuffer) -> PyResult> { + const RUNCHAR: u8 = 0x90; //b'\x90' + s.with_ref(|buffer| { + let len = buffer.len(); + let mut out_data = Vec::::with_capacity(len); + let mut idx = 0; + + out_data.push(buffer[idx]); + idx += 1; + + while idx < len { + if buffer[idx] == RUNCHAR { + if buffer[idx + 1] == 0 { + out_data.push(RUNCHAR); + } else { + let ch = buffer[idx - 1]; + let range = buffer[idx + 1]; + idx += 1; + for _ in 1..range { + out_data.push(ch); + } + } + } else { + out_data.push(buffer[idx]); + } + idx += 1; + } + Ok(out_data) + }) + } + #[pyfunction] fn a2b_uu(s: ArgAsciiBuffer, vm: &VirtualMachine) -> PyResult> { s.with_ref(|b| {