Skip to content

Commit c121d23

Browse files
committed
Adjust values and arrays.
1 parent db80c31 commit c121d23

File tree

11 files changed

+213
-101
lines changed

11 files changed

+213
-101
lines changed

examples/hello/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ fn module_init(_args: ModuleContext) -> bool {
2424
}
2525

2626
fn say_hello(arguments: &mut [ZVal]) -> phper::Result<String> {
27-
let name = arguments[0].as_string_value()?;
27+
let name = &mut arguments[0];
28+
name.convert_to_string();
29+
let name = name.as_z_str().unwrap().to_str()?;
2830
Ok(format!("Hello, {}!\n", name))
2931
}
3032

@@ -79,15 +81,15 @@ pub fn get_module() -> Module {
7981
Visibility::Public,
8082
|this: &mut Object<()>, _: &mut [ZVal]| {
8183
let prop = this.get_property("foo");
82-
Ok::<_, phper::Error>(prop.as_string_value()?)
84+
Ok::<_, phper::Error>(prop.clone())
8385
},
8486
vec![],
8587
);
8688
foo_class.add_method(
8789
"setFoo",
8890
Visibility::Public,
8991
|this: &mut Object<()>, arguments: &mut [ZVal]| -> phper::Result<()> {
90-
this.set_property("foo", ZVal::from(arguments[0].as_string_value()?));
92+
this.set_property("foo", arguments[0].clone());
9193
Ok(())
9294
},
9395
vec![Argument::by_val("foo")],

examples/logging/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ license = "MulanPSL-2.0"
1313
crate-type = ["cdylib"]
1414

1515
[dependencies]
16+
anyhow = "1.0.57"
1617
phper = { version = "0.4.0-alpha.2", path = "../../phper" }
1718

1819
[dev-dependencies]

examples/logging/src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
99
// See the Mulan PSL v2 for more details.
1010

11+
use anyhow::Context;
1112
use phper::{
1213
deprecated, echo, error, functions::Argument, modules::Module, notice, php_get_module,
1314
values::ZVal, warning,
@@ -24,7 +25,8 @@ pub fn get_module() -> Module {
2425
module.add_function(
2526
"log_say",
2627
|params: &mut [ZVal]| -> phper::Result<()> {
27-
let message = params[0].as_string_value()?;
28+
params[0].convert_to_string();
29+
let message = params[0].as_z_str().unwrap().to_str().context("to str")?;
2830
echo!("Hello, {}!", message);
2931
Ok(())
3032
},
@@ -34,7 +36,8 @@ pub fn get_module() -> Module {
3436
module.add_function(
3537
"log_notice",
3638
|params: &mut [ZVal]| -> phper::Result<()> {
37-
let message = params[0].as_string_value()?;
39+
params[0].convert_to_string();
40+
let message = params[0].as_z_str().unwrap().to_str().context("to str")?;
3841
notice!("Something happened: {}", message);
3942
Ok(())
4043
},
@@ -44,7 +47,8 @@ pub fn get_module() -> Module {
4447
module.add_function(
4548
"log_warning",
4649
|params: &mut [ZVal]| -> phper::Result<()> {
47-
let message = params[0].as_string_value()?;
50+
params[0].convert_to_string();
51+
let message = params[0].as_z_str().unwrap().to_str().context("to str")?;
4852
warning!("Something warning: {}", message);
4953
Ok(())
5054
},
@@ -54,7 +58,8 @@ pub fn get_module() -> Module {
5458
module.add_function(
5559
"log_error",
5660
|params: &mut [ZVal]| -> phper::Result<()> {
57-
let message = params[0].as_string_value()?;
61+
params[0].convert_to_string();
62+
let message = params[0].as_z_str().unwrap().to_str().context("to str")?;
5863
error!("Something gone failed: {}", message);
5964
Ok(())
6065
},
@@ -64,7 +69,8 @@ pub fn get_module() -> Module {
6469
module.add_function(
6570
"log_deprecated",
6671
|params: &mut [ZVal]| -> phper::Result<()> {
67-
let message = params[0].as_string_value()?;
72+
params[0].convert_to_string();
73+
let message = params[0].as_z_str().unwrap().to_str().context("to str")?;
6874
deprecated!("Something deprecated: {}", message);
6975
Ok(())
7076
},

phper-sys/php_wrapper.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,11 @@ zend_string *phper_zend_string_copy(zend_string *s) {
297297
const char *phper_get_zend_module_build_id() {
298298
return ZEND_MODULE_BUILD_ID;
299299
}
300+
301+
void phper_convert_to_long(zval *op) {
302+
convert_to_long(op);
303+
}
304+
305+
void phper_convert_to_string(zval *op) {
306+
convert_to_string(op);
307+
}

phper-sys/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,4 @@
1717
#![allow(clippy::all)]
1818
#![doc = include_str!("../README.md")]
1919

20-
use std::os::raw::c_char;
21-
2220
include!(concat!(env!("OUT_DIR"), "/php_bindings.rs"));

phper/src/arrays.rs

Lines changed: 93 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ use std::{
3131
pub enum Key<'a> {
3232
Index(u64),
3333
Str(&'a str),
34+
Bytes(&'a [u8]),
35+
ZStr(&'a ZStr),
3436
}
3537

3638
/// Insert key for [Array].
@@ -39,6 +41,8 @@ pub enum InsertKey<'a> {
3941
NextIndex,
4042
Index(u64),
4143
Str(&'a str),
44+
Bytes(&'a [u8]),
45+
ZStr(&'a ZStr),
4246
}
4347

4448
#[repr(transparent)]
@@ -65,27 +69,50 @@ impl ZArr {
6569
&mut self.inner
6670
}
6771

72+
#[inline]
73+
pub fn is_empty(&mut self) -> bool {
74+
self.len() == 0
75+
}
76+
77+
// Get items length.
78+
#[inline]
79+
pub fn len(&mut self) -> usize {
80+
unsafe { zend_array_count(self.as_mut_ptr()).try_into().unwrap() }
81+
}
82+
6883
/// Add or update item by key.
6984
pub fn insert<'a>(&mut self, key: impl Into<InsertKey<'a>>, value: ZVal) {
7085
let key = key.into();
71-
let value = EBox::new(value);
7286
unsafe {
7387
match key {
7488
InsertKey::NextIndex => {
75-
phper_zend_hash_next_index_insert(
76-
&mut self.inner,
77-
EBox::into_raw(value).cast(),
78-
);
89+
phper_zend_hash_next_index_insert(self.as_mut_ptr(), value.into_raw());
7990
}
8091
InsertKey::Index(i) => {
81-
phper_zend_hash_index_update(&mut self.inner, i, EBox::into_raw(value).cast());
92+
phper_zend_hash_index_update(self.as_mut_ptr(), i, value.into_raw());
8293
}
8394
InsertKey::Str(s) => {
8495
phper_zend_hash_str_update(
85-
&mut self.inner,
96+
self.as_mut_ptr(),
8697
s.as_ptr().cast(),
8798
s.len().try_into().unwrap(),
88-
EBox::into_raw(value).cast(),
99+
value.into_raw(),
100+
);
101+
}
102+
InsertKey::Bytes(b) => {
103+
phper_zend_hash_str_update(
104+
self.as_mut_ptr(),
105+
b.as_ptr().cast(),
106+
b.len().try_into().unwrap(),
107+
value.into_raw(),
108+
);
109+
}
110+
InsertKey::ZStr(s) => {
111+
phper_zend_hash_str_update(
112+
self.as_mut_ptr(),
113+
s.as_c_str_ptr().cast(),
114+
s.len().try_into().unwrap(),
115+
value.into_raw(),
89116
);
90117
}
91118
}
@@ -94,30 +121,31 @@ impl ZArr {
94121

95122
// Get item by key.
96123
pub fn get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&ZVal> {
97-
let key = key.into();
98-
unsafe {
99-
let value = match key {
100-
Key::Index(i) => zend_hash_index_find(&self.inner, i),
101-
Key::Str(s) => {
102-
zend_hash_str_find(&self.inner, s.as_ptr().cast(), s.len().try_into().unwrap())
103-
}
104-
};
105-
if value.is_null() {
106-
None
107-
} else {
108-
Some(ZVal::from_mut_ptr(value))
109-
}
110-
}
124+
self.inner_get(key).map(|v| &*v)
111125
}
112126

113127
// Get item by key.
114128
pub fn get_mut<'a>(&mut self, key: impl Into<Key<'a>>) -> Option<&mut ZVal> {
129+
self.inner_get(key)
130+
}
131+
132+
fn inner_get<'a>(&self, key: impl Into<Key<'a>>) -> Option<&mut ZVal> {
115133
let key = key.into();
116134
unsafe {
117135
let value = match key {
118-
Key::Index(i) => zend_hash_index_find(&self.inner, i),
119-
Key::Str(s) => {
120-
zend_hash_str_find(&self.inner, s.as_ptr().cast(), s.len().try_into().unwrap())
136+
Key::Index(i) => zend_hash_index_find(self.as_ptr(), i),
137+
Key::Str(s) => zend_hash_str_find(
138+
self.as_ptr(),
139+
s.as_ptr().cast(),
140+
s.len().try_into().unwrap(),
141+
),
142+
Key::Bytes(b) => zend_hash_str_find(
143+
self.as_ptr(),
144+
b.as_ptr().cast(),
145+
b.len().try_into().unwrap(),
146+
),
147+
Key::ZStr(s) => {
148+
zend_hash_str_find(self.as_ptr(), s.as_c_str_ptr(), s.len().try_into().unwrap())
121149
}
122150
};
123151
if value.is_null() {
@@ -128,15 +156,6 @@ impl ZArr {
128156
}
129157
}
130158

131-
// Get items length.
132-
pub fn len(&mut self) -> usize {
133-
unsafe { zend_array_count(&mut self.inner) as usize }
134-
}
135-
136-
pub fn is_empty(&mut self) -> bool {
137-
self.len() == 0
138-
}
139-
140159
pub fn exists<'a>(&self, key: impl Into<Key<'a>>) -> bool {
141160
let key = key.into();
142161
unsafe {
@@ -147,6 +166,16 @@ impl ZArr {
147166
s.as_ptr().cast(),
148167
s.len().try_into().unwrap(),
149168
),
169+
Key::Bytes(b) => phper_zend_hash_str_exists(
170+
&self.inner,
171+
b.as_ptr().cast(),
172+
b.len().try_into().unwrap(),
173+
),
174+
Key::ZStr(s) => phper_zend_hash_str_exists(
175+
&self.inner,
176+
s.to_bytes().as_ptr().cast(),
177+
s.len().try_into().unwrap(),
178+
),
150179
}
151180
}
152181
}
@@ -161,10 +190,22 @@ impl ZArr {
161190
s.as_ptr().cast(),
162191
s.len().try_into().unwrap(),
163192
),
193+
Key::Bytes(b) => zend_hash_str_del(
194+
&mut self.inner,
195+
b.as_ptr().cast(),
196+
b.len().try_into().unwrap(),
197+
),
198+
Key::ZStr(s) => zend_hash_str_del(
199+
&mut self.inner,
200+
s.as_c_str_ptr().cast(),
201+
s.len().try_into().unwrap(),
202+
),
164203
}) == ZEND_RESULT_CODE_SUCCESS
165204
}
166205
}
167206

207+
pub fn clear(&mut self) {}
208+
168209
pub fn iter(&self) -> Iter<'_> {
169210
Iter {
170211
index: 0,
@@ -204,9 +245,16 @@ pub struct ZArray {
204245
}
205246

206247
impl ZArray {
248+
#[inline]
207249
pub fn new() -> Self {
250+
Self::with_capacity(0)
251+
}
252+
253+
/// Note that the actual capacity is always a power of two, so if you have
254+
/// 12 elements in a hashtable the actual table capacity will be 16.
255+
pub fn with_capacity(n: usize) -> Self {
208256
unsafe {
209-
let ptr = phper_zend_new_array(0);
257+
let ptr = phper_zend_new_array(n.try_into().unwrap());
210258
Self::from_raw(ptr)
211259
}
212260
}
@@ -266,14 +314,21 @@ impl Drop for ZArray {
266314
}
267315
}
268316

317+
/// Iterator key for [Iter].
318+
#[derive(Debug, Clone, PartialEq, From)]
319+
pub enum IterKey<'a> {
320+
Index(u64),
321+
ZStr(&'a ZStr),
322+
}
323+
269324
/// Iter created by [Array::iter].
270325
pub struct Iter<'a> {
271326
index: isize,
272327
array: &'a ZArr,
273328
}
274329

275330
impl<'a> Iterator for Iter<'a> {
276-
type Item = (Key<'a>, &'a ZVal);
331+
type Item = (IterKey<'a>, &'a ZVal);
277332

278333
fn next(&mut self) -> Option<Self::Item> {
279334
loop {
@@ -285,11 +340,10 @@ impl<'a> Iterator for Iter<'a> {
285340
let bucket = self.array.inner.arData.offset(self.index);
286341

287342
let key = if (*bucket).key.is_null() {
288-
Key::Index((*bucket).h)
343+
IterKey::Index((*bucket).h)
289344
} else {
290345
let s = ZStr::from_ptr((*bucket).key);
291-
let s = s.to_str().unwrap();
292-
Key::Str(s)
346+
IterKey::ZStr(s)
293347
};
294348

295349
let val = &mut (*bucket).val;

0 commit comments

Comments
 (0)