diff options
Diffstat (limited to 'crates/shirabe-php-shim/src')
| -rw-r--r-- | crates/shirabe-php-shim/src/string.rs | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/crates/shirabe-php-shim/src/string.rs b/crates/shirabe-php-shim/src/string.rs index 9563d614..aad5c884 100644 --- a/crates/shirabe-php-shim/src/string.rs +++ b/crates/shirabe-php-shim/src/string.rs @@ -598,149 +598,6 @@ fn hex_digit_value(b: u8) -> Option<u8> { } } -pub fn pack(_format: &str, _values: &[PhpMixed]) -> Vec<u8> { - let fb = _format.as_bytes(); - let mut out: Vec<u8> = Vec::new(); - let mut vi = 0usize; - let mut i = 0; - while i < fb.len() { - let code = fb[i]; - i += 1; - // Repeat count: a number, '*' (consume the rest), or implicitly 1. - let mut repeat: usize = 1; - let mut star = false; - if i < fb.len() && fb[i] == b'*' { - star = true; - i += 1; - } else { - let start = i; - while i < fb.len() && fb[i].is_ascii_digit() { - i += 1; - } - if i > start { - repeat = _format[start..i].parse().unwrap_or(1); - } - } - match code { - b'C' | b'c' | b'n' | b'v' | b'N' | b'V' => { - let count = if star { - _values.len().saturating_sub(vi) - } else { - repeat - }; - for _ in 0..count { - let val = crate::intval(_values.get(vi).unwrap_or(&PhpMixed::Null)); - vi += 1; - match code { - b'C' | b'c' => out.push(val as u8), - b'n' => out.extend_from_slice(&(val as u16).to_be_bytes()), - b'v' => out.extend_from_slice(&(val as u16).to_le_bytes()), - b'N' => out.extend_from_slice(&(val as u32).to_be_bytes()), - b'V' => out.extend_from_slice(&(val as u32).to_le_bytes()), - _ => unreachable!(), - } - } - } - b'a' | b'A' => { - let s = crate::php_to_string(_values.get(vi).unwrap_or(&PhpMixed::Null)); - vi += 1; - let bytes = s.as_bytes(); - let len = if star { bytes.len() } else { repeat }; - let pad = if code == b'A' { b' ' } else { 0 }; - for j in 0..len { - out.push(bytes.get(j).copied().unwrap_or(pad)); - } - } - _ => { - // TODO(phase-d): only the C/c/n/v/N/V/a/A pack format codes are ported; the - // machine-size and floating-point codes are not. - todo!("pack format code {}", code as char) - } - } - } - out -} - -pub fn unpack(_format: &str, _data: &[u8]) -> Option<IndexMap<String, PhpMixed>> { - let mut result = IndexMap::new(); - let mut offset = 0usize; - for group in _format.split('/') { - if group.is_empty() { - continue; - } - let gb = group.as_bytes(); - let code = gb[0]; - let mut j = 1; - let mut repeat: usize = 1; - let mut star = false; - if j < gb.len() && gb[j] == b'*' { - star = true; - j += 1; - } else { - let start = j; - while j < gb.len() && gb[j].is_ascii_digit() { - j += 1; - } - if j > start { - repeat = group[start..j].parse().unwrap_or(1); - } - } - let name = &group[j..]; - // `i`/`I` are the native int (4 bytes on the LP64 targets in use); `s`/`S` are the native - // short (2 bytes). - let size = match code { - b'C' | b'c' => 1, - b'n' | b'v' | b's' | b'S' => 2, - b'N' | b'V' | b'i' | b'I' => 4, - _ => { - // TODO(phase-d): only C/c/n/v/N/V/s/S/i/I unpack format codes are ported; the - // machine-size long/quad and floating-point codes are not. - todo!("unpack format code {}", code as char) - } - }; - let count = if star { - _data.len().saturating_sub(offset) / size - } else { - repeat - }; - for idx in 0..count { - if offset + size > _data.len() { - break; - } - let chunk = &_data[offset..offset + size]; - offset += size; - let value: i64 = match code { - b'C' => chunk[0] as i64, - b'c' => chunk[0] as i8 as i64, - b'n' => u16::from_be_bytes([chunk[0], chunk[1]]) as i64, - b'v' => u16::from_le_bytes([chunk[0], chunk[1]]) as i64, - b's' => i16::from_ne_bytes([chunk[0], chunk[1]]) as i64, - b'S' => u16::from_ne_bytes([chunk[0], chunk[1]]) as i64, - b'N' => u32::from_be_bytes(chunk.try_into().unwrap()) as i64, - b'V' => u32::from_le_bytes(chunk.try_into().unwrap()) as i64, - b'i' => i32::from_ne_bytes(chunk.try_into().unwrap()) as i64, - b'I' => u32::from_ne_bytes(chunk.try_into().unwrap()) as i64, - _ => unreachable!(), - }; - // PHP keys: "name" for a single element; "name1", "name2", ... for repeats; the 1-based - // index alone when the name is empty. - let key = if star || repeat > 1 { - if name.is_empty() { - (idx + 1).to_string() - } else { - format!("{}{}", name, idx + 1) - } - } else if name.is_empty() { - "1".to_string() - } else { - name.to_string() - }; - result.insert(key, PhpMixed::Int(value)); - } - } - Some(result) -} - pub fn sscanf(_subject: &str, _format: &str, _a: &mut i64, _b: &mut i64) -> i64 { // TODO(phase-d): a general sscanf format-string parser is not ported; this specialized two-int // overload has no current callers. |
