Skip to content

Commit 00cb5ca

Browse files
authored
add fn Binascii rlecode_hqx rledecode_hqx (RustPython#3809)
1 parent a2f77bb commit 00cb5ca

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

Lib/test/test_binascii.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,6 @@ def test_hqx(self):
220220
res = binascii.rledecode_hqx(b)
221221
self.assertEqual(res, self.rawdata)
222222

223-
# TODO: RUSTPYTHON
224-
@unittest.expectedFailure
225223
def test_rle(self):
226224
# test repetition with a repetition longer than the limit of 255
227225
data = (b'a' * 100 + b'b' + b'c' * 300)

stdlib/src/binascii.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,73 @@ mod decl {
182182
Ok((*c - 0x20) & 0x3f)
183183
}
184184

185+
#[pyfunction]
186+
fn rlecode_hqx(s: ArgAsciiBuffer) -> PyResult<Vec<u8>> {
187+
const RUNCHAR: u8 = 0x90; // b'\x90'
188+
s.with_ref(|buffer| {
189+
let len = buffer.len();
190+
let mut out_data = Vec::<u8>::with_capacity((len * 2) + 2);
191+
192+
let mut idx = 0;
193+
while idx < len {
194+
let ch = buffer[idx];
195+
196+
if ch == RUNCHAR {
197+
out_data.push(RUNCHAR);
198+
out_data.push(0);
199+
return Ok(out_data);
200+
} else {
201+
let mut inend = idx + 1;
202+
while inend < len && buffer[inend] == ch && inend < idx + 255 {
203+
inend += 1;
204+
}
205+
if inend - idx > 3 {
206+
out_data.push(ch);
207+
out_data.push(RUNCHAR);
208+
out_data.push(((inend - idx) % 256) as u8);
209+
idx = inend - 1;
210+
} else {
211+
out_data.push(ch);
212+
}
213+
}
214+
idx += 1;
215+
}
216+
Ok(out_data)
217+
})
218+
}
219+
220+
#[pyfunction]
221+
fn rledecode_hqx(s: ArgAsciiBuffer) -> PyResult<Vec<u8>> {
222+
const RUNCHAR: u8 = 0x90; //b'\x90'
223+
s.with_ref(|buffer| {
224+
let len = buffer.len();
225+
let mut out_data = Vec::<u8>::with_capacity(len);
226+
let mut idx = 0;
227+
228+
out_data.push(buffer[idx]);
229+
idx += 1;
230+
231+
while idx < len {
232+
if buffer[idx] == RUNCHAR {
233+
if buffer[idx + 1] == 0 {
234+
out_data.push(RUNCHAR);
235+
} else {
236+
let ch = buffer[idx - 1];
237+
let range = buffer[idx + 1];
238+
idx += 1;
239+
for _ in 1..range {
240+
out_data.push(ch);
241+
}
242+
}
243+
} else {
244+
out_data.push(buffer[idx]);
245+
}
246+
idx += 1;
247+
}
248+
Ok(out_data)
249+
})
250+
}
251+
185252
#[pyfunction]
186253
fn a2b_uu(s: ArgAsciiBuffer, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
187254
s.with_ref(|b| {

0 commit comments

Comments
 (0)