forked from Rust-related/RustPython
Add repeat count support to struct.pack() (#1518)
* Add struct.pack() repeat count test * Add repeat count support to struct.pack() * Refactor parse_format_codes() * Refactor parse_format_codes() again
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
|
||||
from testutils import assert_raises
|
||||
import struct
|
||||
|
||||
data = struct.pack('IH', 14, 12)
|
||||
@@ -22,3 +23,18 @@ v1, v2 = struct.unpack('>IH', data)
|
||||
assert v1 == 14
|
||||
assert v2 == 12
|
||||
|
||||
data = struct.pack('3B', 65, 66, 67)
|
||||
assert data == bytes([65, 66, 67])
|
||||
|
||||
v1, v2, v3 = struct.unpack('3B', data)
|
||||
assert v1 == 65
|
||||
assert v2 == 66
|
||||
assert v3 == 67
|
||||
|
||||
with assert_raises(Exception):
|
||||
data = struct.pack('B0B', 65, 66)
|
||||
|
||||
with assert_raises(Exception):
|
||||
data = struct.pack('B2B', 65, 66)
|
||||
|
||||
data = struct.pack('B1B', 65, 66)
|
||||
|
||||
@@ -88,20 +88,48 @@ where
|
||||
I: Sized + Iterator<Item = char>,
|
||||
{
|
||||
let mut codes = vec![];
|
||||
for c in chars {
|
||||
while chars.peek().is_some() {
|
||||
// determine repeat operator:
|
||||
let repeat = match chars.peek() {
|
||||
Some('0'..='9') => {
|
||||
let mut repeat = 0;
|
||||
while let Some('0'..='9') = chars.peek() {
|
||||
if let Some(c) = chars.next() {
|
||||
let current_digit = c.to_digit(10).unwrap();
|
||||
repeat = repeat * 10 + current_digit;
|
||||
}
|
||||
}
|
||||
Some(repeat)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
// determine format char:
|
||||
let c = chars.next();
|
||||
match c {
|
||||
'b' | 'B' | 'h' | 'H' | 'i' | 'I' | 'l' | 'L' | 'q' | 'Q' | 'f' | 'd' => {
|
||||
codes.push(FormatCode { code: c })
|
||||
}
|
||||
c => {
|
||||
return Err(format!("Illegal format code {:?}", c));
|
||||
Some(c) if is_supported_format_character(c) => {
|
||||
if let Some(repeat) = repeat {
|
||||
for _ in 0..repeat {
|
||||
codes.push(FormatCode { code: c })
|
||||
}
|
||||
} else {
|
||||
codes.push(FormatCode { code: c })
|
||||
}
|
||||
}
|
||||
_ => return Err(format!("Illegal format code {:?}", c)),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(codes)
|
||||
}
|
||||
|
||||
fn is_supported_format_character(c: char) -> bool {
|
||||
match c {
|
||||
'b' | 'B' | 'h' | 'H' | 'i' | 'I' | 'l' | 'L' | 'q' | 'Q' | 'f' | 'd' => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_int(vm: &VirtualMachine, arg: &PyObjectRef) -> PyResult<BigInt> {
|
||||
objint::to_int(vm, arg, &BigInt::from(10))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user