| 428 | } |
| 429 | |
| 430 | pub fn pack_into( |
| 431 | &self, |
| 432 | mut buffer: &mut [u8], |
| 433 | args: Vec<PyObjectRef>, |
| 434 | vm: &VirtualMachine, |
| 435 | ) -> PyResult<()> { |
| 436 | if self.arg_count != args.len() { |
| 437 | return Err(new_struct_error( |
| 438 | vm, |
| 439 | format!( |
| 440 | "pack expected {} items for packing (got {})", |
| 441 | self.codes.len(), |
| 442 | args.len() |
| 443 | ), |
| 444 | )); |
| 445 | } |
| 446 | |
| 447 | let mut args = args.into_iter(); |
| 448 | // Loop over all opcodes: |
| 449 | for code in &self.codes { |
| 450 | buffer = &mut buffer[code.pre_padding..]; |
| 451 | debug!("code: {code:?}"); |
| 452 | match code.code { |
| 453 | FormatType::Str => { |
| 454 | let (buf, rest) = buffer.split_at_mut(code.repeat); |
| 455 | pack_string(vm, args.next().unwrap(), buf)?; |
| 456 | buffer = rest; |
| 457 | } |
| 458 | FormatType::Pascal => { |
| 459 | let (buf, rest) = buffer.split_at_mut(code.repeat); |
| 460 | pack_pascal(vm, args.next().unwrap(), buf)?; |
| 461 | buffer = rest; |
| 462 | } |
| 463 | FormatType::Pad => { |
| 464 | let (pad_buf, rest) = buffer.split_at_mut(code.repeat); |
| 465 | for el in pad_buf { |
| 466 | *el = 0 |
| 467 | } |
| 468 | buffer = rest; |
| 469 | } |
| 470 | _ => { |
| 471 | let pack = code.info.pack.unwrap(); |
| 472 | for arg in args.by_ref().take(code.repeat) { |
| 473 | let (item_buf, rest) = buffer.split_at_mut(code.info.size); |
| 474 | pack(vm, arg, item_buf)?; |
| 475 | buffer = rest; |
| 476 | } |
| 477 | } |
| 478 | } |
| 479 | } |
| 480 | |
| 481 | Ok(()) |
| 482 | } |
| 483 | |
| 484 | pub fn unpack(&self, mut data: &[u8], vm: &VirtualMachine) -> PyResult<PyTupleRef> { |
| 485 | if self.size != data.len() { |