mirror of
https://github.com/icewind1991/ivory.git
synced 2026-06-03 18:54:07 +02:00
array handling
This commit is contained in:
parent
b4d2a3a6a3
commit
e4874998f9
1 changed files with 52 additions and 8 deletions
|
|
@ -1,10 +1,11 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str;
|
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use crate::externs::printf;
|
use crate::externs::printf;
|
||||||
|
use crate::zend::bindings::zend_string;
|
||||||
|
|
||||||
use super::bindings::{zend_execute_data, zval};
|
use super::bindings::{zend_execute_data, zval};
|
||||||
|
|
||||||
|
|
@ -61,6 +62,13 @@ impl Iterator for IntoArgIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn zend_str_as_string(str: &zend_string) -> String {
|
||||||
|
let len = str.len;
|
||||||
|
let base: *const c_char = &str.val[0];
|
||||||
|
let slice: &[u8] = std::slice::from_raw_parts(base as *const u8, len);
|
||||||
|
str::from_utf8_unchecked(slice).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct ZVal(zval);
|
pub struct ZVal(zval);
|
||||||
|
|
||||||
|
|
@ -79,10 +87,27 @@ impl ZVal {
|
||||||
|
|
||||||
pub unsafe fn as_str(&self) -> String {
|
pub unsafe fn as_str(&self) -> String {
|
||||||
let str = *self.0.value.str;
|
let str = *self.0.value.str;
|
||||||
let len = str.len;
|
zend_str_as_string(&str)
|
||||||
let base: *const c_char = &str.val[0];
|
}
|
||||||
let slice:&[u8] = std::slice::from_raw_parts(base as *const u8, len);
|
|
||||||
str::from_utf8_unchecked(slice).to_string()
|
pub unsafe fn as_array(&self) -> Vec<(ArrayKey, PhpVal)> {
|
||||||
|
let arr = *self.0.value.arr;
|
||||||
|
let len = arr.nNumUsed;
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for i in 0..len {
|
||||||
|
let elem = *arr.arData.add(i as usize);
|
||||||
|
let key = if elem.key.is_null() {
|
||||||
|
ArrayKey::Int(elem.h)
|
||||||
|
} else {
|
||||||
|
ArrayKey::String(zend_str_as_string(&*elem.key))
|
||||||
|
};
|
||||||
|
let val: PhpVal = (&ZVal(elem.val)).into();
|
||||||
|
match val {
|
||||||
|
PhpVal::Undef => {}
|
||||||
|
_ => result.push((key, val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +136,13 @@ impl From<u8> for ZValType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
|
pub enum ArrayKey {
|
||||||
|
String(String),
|
||||||
|
Int(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum PhpVal {
|
pub enum PhpVal {
|
||||||
Undef,
|
Undef,
|
||||||
Null,
|
Null,
|
||||||
|
|
@ -119,15 +150,27 @@ pub enum PhpVal {
|
||||||
Long(i64),
|
Long(i64),
|
||||||
Double(f64),
|
Double(f64),
|
||||||
String(String),
|
String(String),
|
||||||
Array(Vec<PhpVal>),
|
Array(Vec<(ArrayKey, PhpVal)>),
|
||||||
Object(HashMap<String, PhpVal>),
|
Object(HashMap<String, PhpVal>),
|
||||||
Resource(u64),
|
Resource(u64),
|
||||||
Reference(),
|
Reference(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for PhpVal {
|
||||||
|
fn default() -> Self {
|
||||||
|
PhpVal::Undef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<*const ZVal> for PhpVal {
|
impl From<*const ZVal> for PhpVal {
|
||||||
fn from(val: *const ZVal) -> Self {
|
fn from(val: *const ZVal) -> Self {
|
||||||
let val = unsafe { &*val };
|
let val = unsafe { &*val };
|
||||||
|
val.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ZVal> for PhpVal {
|
||||||
|
fn from(val: &ZVal) -> Self {
|
||||||
match val.get_type() {
|
match val.get_type() {
|
||||||
ZValType::Undef => PhpVal::Undef,
|
ZValType::Undef => PhpVal::Undef,
|
||||||
ZValType::Null => PhpVal::Null,
|
ZValType::Null => PhpVal::Null,
|
||||||
|
|
@ -135,7 +178,8 @@ impl From<*const ZVal> for PhpVal {
|
||||||
ZValType::True => PhpVal::Bool(true),
|
ZValType::True => PhpVal::Bool(true),
|
||||||
ZValType::Long => PhpVal::Long(unsafe { val.as_i64() }),
|
ZValType::Long => PhpVal::Long(unsafe { val.as_i64() }),
|
||||||
ZValType::Double => PhpVal::Double(unsafe { val.as_f64() }),
|
ZValType::Double => PhpVal::Double(unsafe { val.as_f64() }),
|
||||||
ZValType::String=> PhpVal::String(unsafe { val.as_str() }),
|
ZValType::String => PhpVal::String(unsafe { val.as_str() }),
|
||||||
|
ZValType::Array => PhpVal::Array(unsafe { val.as_array() }),
|
||||||
_ => PhpVal::Undef
|
_ => PhpVal::Undef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue