-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathphp_iterator.cpp
More file actions
136 lines (114 loc) · 2.92 KB
/
php_iterator.cpp
File metadata and controls
136 lines (114 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* PhpIterator.cpp
*
* Implementation file for the PhpIterator class
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2025 Copernica BV
*/
/**
* Dependencies
*/
#include "php_iterator.h"
#include "scope.h"
#include "php_variable.h"
/**
* Begin of namespace
*/
namespace JS {
/**
* Constructor
* @param base The base that PHP-CPP insists on
* @param core The javascript core
* @param object The object to iterate
*/
PhpIterator::PhpIterator(Php::Base *base, const std::shared_ptr<Core> &core, const v8::Local<v8::Object> &object) : Php::Iterator(base),
_core(core),
_object(core->isolate(), object)
{
// get a scope (we already have one when we are called, but ok)
Scope scope(core);
// get the key (this is a maybe)
auto maybe = object->GetPropertyNames(scope);
if (maybe.IsEmpty()) return;
// convert to a v8::Local
auto keys = maybe.ToLocalChecked();
// store in _keys, which is a v8::Global
_keys.Reset(core->isolate(), keys);
// size can be helpful to have in a cached form
_size = keys->Length();
}
/**
* Destructor
*/
PhpIterator::~PhpIterator()
{
// destruct handles
_object.Reset();
_keys.Reset();
}
/**
* Is the iterator still valid?
* @return is an element present at the current offset
*/
bool PhpIterator::valid()
{
// we should not be out of bounds
return _position < _size;
}
/**
* Retrieve the current value
* @return value at current offset
*/
Php::Value PhpIterator::current()
{
// make sure there is a scope
Scope scope(_core);
// get the object and keys in a local variables
v8::Local<v8::Object> object(_object.Get(_core->isolate()));
v8::Local<v8::Array> keys(_keys.Get(_core->isolate()));
// retrieve the current key
auto key = keys->Get(scope, _position);
if (key.IsEmpty()) return nullptr;
// retrieve the current key, the value and convert it
auto value = object->Get(scope, key.ToLocalChecked());
if (key.IsEmpty()) return nullptr;
// expose to php space
return PhpVariable(_core->isolate(), value.ToLocalChecked());
}
/**
* Retrieve the current key
* @return the current key
*/
Php::Value PhpIterator::key()
{
// make sure there is a scope
Scope scope(_core);
// get the keys in a local variable
v8::Local<v8::Array> keys(_keys.Get(_core->isolate()));
// retrieve the current key
auto key = keys->Get(scope, _position);
if (key.IsEmpty()) return nullptr;
// retrieve the current key, the value and convert it
return PhpVariable(_core->isolate(), key.ToLocalChecked());
}
/**
* Move ahead to the next item
*/
void PhpIterator::next()
{
// move to the next position
++_position;
}
/**
* Start over at the beginning
*/
void PhpIterator::rewind()
{
// move back to the beginning
_position = 0;
}
/**
* End of namespace
*/
}