@@ -31,6 +31,8 @@ use std::{
31
31
pub enum Key < ' a > {
32
32
Index ( u64 ) ,
33
33
Str ( & ' a str ) ,
34
+ Bytes ( & ' a [ u8 ] ) ,
35
+ ZStr ( & ' a ZStr ) ,
34
36
}
35
37
36
38
/// Insert key for [Array].
@@ -39,6 +41,8 @@ pub enum InsertKey<'a> {
39
41
NextIndex ,
40
42
Index ( u64 ) ,
41
43
Str ( & ' a str ) ,
44
+ Bytes ( & ' a [ u8 ] ) ,
45
+ ZStr ( & ' a ZStr ) ,
42
46
}
43
47
44
48
#[ repr( transparent) ]
@@ -65,27 +69,50 @@ impl ZArr {
65
69
& mut self . inner
66
70
}
67
71
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
+
68
83
/// Add or update item by key.
69
84
pub fn insert < ' a > ( & mut self , key : impl Into < InsertKey < ' a > > , value : ZVal ) {
70
85
let key = key. into ( ) ;
71
- let value = EBox :: new ( value) ;
72
86
unsafe {
73
87
match key {
74
88
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 ( ) ) ;
79
90
}
80
91
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 ( ) ) ;
82
93
}
83
94
InsertKey :: Str ( s) => {
84
95
phper_zend_hash_str_update (
85
- & mut self . inner ,
96
+ self . as_mut_ptr ( ) ,
86
97
s. as_ptr ( ) . cast ( ) ,
87
98
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 ( ) ,
89
116
) ;
90
117
}
91
118
}
@@ -94,30 +121,31 @@ impl ZArr {
94
121
95
122
// Get item by key.
96
123
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)
111
125
}
112
126
113
127
// Get item by key.
114
128
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 > {
115
133
let key = key. into ( ) ;
116
134
unsafe {
117
135
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 ( ) )
121
149
}
122
150
} ;
123
151
if value. is_null ( ) {
@@ -128,15 +156,6 @@ impl ZArr {
128
156
}
129
157
}
130
158
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
-
140
159
pub fn exists < ' a > ( & self , key : impl Into < Key < ' a > > ) -> bool {
141
160
let key = key. into ( ) ;
142
161
unsafe {
@@ -147,6 +166,16 @@ impl ZArr {
147
166
s. as_ptr ( ) . cast ( ) ,
148
167
s. len ( ) . try_into ( ) . unwrap ( ) ,
149
168
) ,
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
+ ) ,
150
179
}
151
180
}
152
181
}
@@ -161,10 +190,22 @@ impl ZArr {
161
190
s. as_ptr ( ) . cast ( ) ,
162
191
s. len ( ) . try_into ( ) . unwrap ( ) ,
163
192
) ,
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
+ ) ,
164
203
} ) == ZEND_RESULT_CODE_SUCCESS
165
204
}
166
205
}
167
206
207
+ pub fn clear ( & mut self ) { }
208
+
168
209
pub fn iter ( & self ) -> Iter < ' _ > {
169
210
Iter {
170
211
index : 0 ,
@@ -204,9 +245,16 @@ pub struct ZArray {
204
245
}
205
246
206
247
impl ZArray {
248
+ #[ inline]
207
249
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 {
208
256
unsafe {
209
- let ptr = phper_zend_new_array ( 0 ) ;
257
+ let ptr = phper_zend_new_array ( n . try_into ( ) . unwrap ( ) ) ;
210
258
Self :: from_raw ( ptr)
211
259
}
212
260
}
@@ -266,14 +314,21 @@ impl Drop for ZArray {
266
314
}
267
315
}
268
316
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
+
269
324
/// Iter created by [Array::iter].
270
325
pub struct Iter < ' a > {
271
326
index : isize ,
272
327
array : & ' a ZArr ,
273
328
}
274
329
275
330
impl < ' a > Iterator for Iter < ' a > {
276
- type Item = ( Key < ' a > , & ' a ZVal ) ;
331
+ type Item = ( IterKey < ' a > , & ' a ZVal ) ;
277
332
278
333
fn next ( & mut self ) -> Option < Self :: Item > {
279
334
loop {
@@ -285,11 +340,10 @@ impl<'a> Iterator for Iter<'a> {
285
340
let bucket = self . array . inner . arData . offset ( self . index ) ;
286
341
287
342
let key = if ( * bucket) . key . is_null ( ) {
288
- Key :: Index ( ( * bucket) . h )
343
+ IterKey :: Index ( ( * bucket) . h )
289
344
} else {
290
345
let s = ZStr :: from_ptr ( ( * bucket) . key ) ;
291
- let s = s. to_str ( ) . unwrap ( ) ;
292
- Key :: Str ( s)
346
+ IterKey :: ZStr ( s)
293
347
} ;
294
348
295
349
let val = & mut ( * bucket) . val ;
0 commit comments