Skip to content

Commit 32b93db

Browse files
committed
Move cursor iterator handlers into Cursor.c
1 parent 4d2b8f2 commit 32b93db

File tree

3 files changed

+175
-179
lines changed

3 files changed

+175
-179
lines changed

php_phongo.c

Lines changed: 0 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,182 +1677,6 @@ void php_phongo_new_regex_from_regex_and_options(zval *object, const char *patte
16771677
intern->flags = estrndup(flags, intern->flags_len);
16781678
} /* }}} */
16791679

1680-
static void php_phongo_cursor_free_current(php_phongo_cursor_t *cursor) /* {{{ */
1681-
{
1682-
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
1683-
zval_ptr_dtor(&cursor->visitor_data.zchild);
1684-
#if PHP_VERSION_ID >= 70000
1685-
ZVAL_UNDEF(&cursor->visitor_data.zchild);
1686-
#else
1687-
cursor->visitor_data.zchild = NULL;
1688-
#endif
1689-
}
1690-
} /* }}} */
1691-
1692-
void php_phongo_cursor_free(php_phongo_cursor_t *cursor) /* {{{ */
1693-
{
1694-
if (cursor->cursor) {
1695-
mongoc_cursor_destroy(cursor->cursor);
1696-
cursor->cursor = NULL;
1697-
}
1698-
1699-
php_phongo_cursor_free_current(cursor);
1700-
} /* }}} */
1701-
1702-
/* {{{ Iterator */
1703-
static void php_phongo_cursor_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
1704-
{
1705-
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
1706-
1707-
if (!Z_ISUNDEF(cursor_it->intern.data)) {
1708-
#if PHP_VERSION_ID >= 70000
1709-
zval_ptr_dtor(&cursor_it->intern.data);
1710-
#else
1711-
zval_ptr_dtor((zval**)&cursor_it->intern.data);
1712-
cursor_it->intern.data = NULL;
1713-
#endif
1714-
}
1715-
1716-
#if PHP_VERSION_ID < 70000
1717-
efree(cursor_it);
1718-
#endif
1719-
} /* }}} */
1720-
1721-
static int php_phongo_cursor_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
1722-
{
1723-
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
1724-
1725-
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
1726-
return SUCCESS;
1727-
}
1728-
1729-
return FAILURE;
1730-
} /* }}} */
1731-
1732-
#if PHP_VERSION_ID < 50500
1733-
static int php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
1734-
{
1735-
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
1736-
1737-
*int_key = (ulong) cursor->current;
1738-
return HASH_KEY_IS_LONG;
1739-
} /* }}} */
1740-
#else
1741-
static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
1742-
{
1743-
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
1744-
1745-
ZVAL_LONG(key, cursor->current);
1746-
} /* }}} */
1747-
#endif
1748-
1749-
#if PHP_VERSION_ID < 70000
1750-
static void php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
1751-
{
1752-
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
1753-
1754-
*data = &cursor->visitor_data.zchild;
1755-
} /* }}} */
1756-
#else
1757-
static zval* php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter) /* {{{ */
1758-
{
1759-
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
1760-
1761-
return &cursor->visitor_data.zchild;
1762-
} /* }}} */
1763-
#endif
1764-
1765-
static void php_phongo_cursor_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
1766-
{
1767-
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
1768-
php_phongo_cursor_t *cursor = cursor_it->cursor;
1769-
const bson_t *doc;
1770-
1771-
php_phongo_cursor_free_current(cursor);
1772-
cursor->current++;
1773-
1774-
if (mongoc_cursor_next(cursor->cursor, &doc)) {
1775-
phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data);
1776-
} else {
1777-
bson_error_t error;
1778-
1779-
if (mongoc_cursor_error(cursor->cursor, &error)) {
1780-
/* Intentionally not destroying the cursor as it will happen
1781-
* naturally now that there are no more results */
1782-
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
1783-
}
1784-
}
1785-
} /* }}} */
1786-
1787-
static void php_phongo_cursor_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
1788-
{
1789-
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
1790-
php_phongo_cursor_t *cursor = cursor_it->cursor;
1791-
const bson_t *doc;
1792-
1793-
if (cursor->current > 0) {
1794-
phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot rewind after starting iteration");
1795-
return;
1796-
}
1797-
1798-
php_phongo_cursor_free_current(cursor);
1799-
1800-
doc = mongoc_cursor_current(cursor->cursor);
1801-
1802-
if (doc) {
1803-
phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data);
1804-
}
1805-
} /* }}} */
1806-
1807-
/* iterator handler table */
1808-
zend_object_iterator_funcs php_phongo_cursor_iterator_funcs = {
1809-
php_phongo_cursor_iterator_dtor,
1810-
php_phongo_cursor_iterator_valid,
1811-
php_phongo_cursor_iterator_get_current_data,
1812-
php_phongo_cursor_iterator_get_current_key,
1813-
php_phongo_cursor_iterator_move_forward,
1814-
php_phongo_cursor_iterator_rewind,
1815-
NULL /* invalidate_current is not used */
1816-
};
1817-
1818-
zend_object_iterator *php_phongo_cursor_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
1819-
{
1820-
php_phongo_cursor_iterator *cursor_it = NULL;
1821-
php_phongo_cursor_t *cursor = Z_CURSOR_OBJ_P(object);
1822-
1823-
if (by_ref) {
1824-
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
1825-
}
1826-
1827-
if (cursor->got_iterator) {
1828-
phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot yield multiple iterators");
1829-
return NULL;
1830-
}
1831-
1832-
cursor->got_iterator = 1;
1833-
1834-
cursor_it = ecalloc(1, sizeof(php_phongo_cursor_iterator));
1835-
#if PHP_VERSION_ID >= 70000
1836-
zend_iterator_init(&cursor_it->intern);
1837-
#endif
1838-
1839-
#if PHP_VERSION_ID >= 70000
1840-
ZVAL_COPY(&cursor_it->intern.data, object);
1841-
#else
1842-
Z_ADDREF_P(object);
1843-
cursor_it->intern.data = (void*)object;
1844-
#endif
1845-
cursor_it->intern.funcs = &php_phongo_cursor_iterator_funcs;
1846-
cursor_it->cursor = cursor;
1847-
/* cursor_it->current should already be allocated to zero */
1848-
1849-
php_phongo_cursor_free_current(cursor_it->cursor);
1850-
1851-
return &cursor_it->intern;
1852-
} /* }}} */
1853-
/* }}} */
1854-
1855-
18561680
/* {{{ Memory allocation wrappers */
18571681
static void* php_phongo_malloc(size_t num_bytes) /* {{{ */
18581682
{

php_phongo.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,6 @@ void php_phongo_new_regex_from_regex_and_options(zval *object, const char *patte
154154
zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC);
155155
zend_bool phongo_writeconcernerror_init(zval *return_value, bson_t *bson TSRMLS_DC);
156156

157-
void php_phongo_cursor_free(php_phongo_cursor_t *cursor);
158-
zend_object_iterator* php_phongo_cursor_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
159-
160157
#if PHP_VERSION_ID >= 70000
161158
#define PHONGO_CE_FINAL(ce) do { \
162159
ce->ce_flags |= ZEND_ACC_FINAL; \

src/MongoDB/Cursor.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,181 @@ PHONGO_API zend_class_entry *php_phongo_cursor_ce;
4646

4747
zend_object_handlers php_phongo_handler_cursor;
4848

49+
static void php_phongo_cursor_free_current(php_phongo_cursor_t *cursor) /* {{{ */
50+
{
51+
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
52+
zval_ptr_dtor(&cursor->visitor_data.zchild);
53+
#if PHP_VERSION_ID >= 70000
54+
ZVAL_UNDEF(&cursor->visitor_data.zchild);
55+
#else
56+
cursor->visitor_data.zchild = NULL;
57+
#endif
58+
}
59+
} /* }}} */
60+
61+
void php_phongo_cursor_free(php_phongo_cursor_t *cursor) /* {{{ */
62+
{
63+
if (cursor->cursor) {
64+
mongoc_cursor_destroy(cursor->cursor);
65+
cursor->cursor = NULL;
66+
}
67+
68+
php_phongo_cursor_free_current(cursor);
69+
} /* }}} */
70+
71+
/* {{{ Iterator handlers */
72+
static void php_phongo_cursor_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
73+
{
74+
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
75+
76+
if (!Z_ISUNDEF(cursor_it->intern.data)) {
77+
#if PHP_VERSION_ID >= 70000
78+
zval_ptr_dtor(&cursor_it->intern.data);
79+
#else
80+
zval_ptr_dtor((zval**)&cursor_it->intern.data);
81+
cursor_it->intern.data = NULL;
82+
#endif
83+
}
84+
85+
#if PHP_VERSION_ID < 70000
86+
efree(cursor_it);
87+
#endif
88+
} /* }}} */
89+
90+
static int php_phongo_cursor_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
91+
{
92+
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
93+
94+
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
95+
return SUCCESS;
96+
}
97+
98+
return FAILURE;
99+
} /* }}} */
100+
101+
#if PHP_VERSION_ID < 50500
102+
static int php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
103+
{
104+
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
105+
106+
*int_key = (ulong) cursor->current;
107+
return HASH_KEY_IS_LONG;
108+
} /* }}} */
109+
#else
110+
static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
111+
{
112+
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
113+
114+
ZVAL_LONG(key, cursor->current);
115+
} /* }}} */
116+
#endif
117+
118+
#if PHP_VERSION_ID < 70000
119+
static void php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
120+
{
121+
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
122+
123+
*data = &cursor->visitor_data.zchild;
124+
} /* }}} */
125+
#else
126+
static zval* php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter) /* {{{ */
127+
{
128+
php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor;
129+
130+
return &cursor->visitor_data.zchild;
131+
} /* }}} */
132+
#endif
133+
134+
static void php_phongo_cursor_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
135+
{
136+
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
137+
php_phongo_cursor_t *cursor = cursor_it->cursor;
138+
const bson_t *doc;
139+
140+
php_phongo_cursor_free_current(cursor);
141+
cursor->current++;
142+
143+
if (mongoc_cursor_next(cursor->cursor, &doc)) {
144+
phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data);
145+
} else {
146+
bson_error_t error;
147+
148+
if (mongoc_cursor_error(cursor->cursor, &error)) {
149+
/* Intentionally not destroying the cursor as it will happen
150+
* naturally now that there are no more results */
151+
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
152+
}
153+
}
154+
} /* }}} */
155+
156+
static void php_phongo_cursor_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
157+
{
158+
php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter;
159+
php_phongo_cursor_t *cursor = cursor_it->cursor;
160+
const bson_t *doc;
161+
162+
if (cursor->current > 0) {
163+
phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot rewind after starting iteration");
164+
return;
165+
}
166+
167+
php_phongo_cursor_free_current(cursor);
168+
169+
doc = mongoc_cursor_current(cursor->cursor);
170+
171+
if (doc) {
172+
phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data);
173+
}
174+
} /* }}} */
175+
176+
/* iterator handler table */
177+
zend_object_iterator_funcs php_phongo_cursor_iterator_funcs = {
178+
php_phongo_cursor_iterator_dtor,
179+
php_phongo_cursor_iterator_valid,
180+
php_phongo_cursor_iterator_get_current_data,
181+
php_phongo_cursor_iterator_get_current_key,
182+
php_phongo_cursor_iterator_move_forward,
183+
php_phongo_cursor_iterator_rewind,
184+
NULL /* invalidate_current is not used */
185+
};
186+
187+
zend_object_iterator *php_phongo_cursor_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
188+
{
189+
php_phongo_cursor_iterator *cursor_it = NULL;
190+
php_phongo_cursor_t *cursor = Z_CURSOR_OBJ_P(object);
191+
192+
if (by_ref) {
193+
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
194+
}
195+
196+
if (cursor->got_iterator) {
197+
phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot yield multiple iterators");
198+
return NULL;
199+
}
200+
201+
cursor->got_iterator = 1;
202+
203+
cursor_it = ecalloc(1, sizeof(php_phongo_cursor_iterator));
204+
#if PHP_VERSION_ID >= 70000
205+
zend_iterator_init(&cursor_it->intern);
206+
#endif
207+
208+
#if PHP_VERSION_ID >= 70000
209+
ZVAL_COPY(&cursor_it->intern.data, object);
210+
#else
211+
Z_ADDREF_P(object);
212+
cursor_it->intern.data = (void*)object;
213+
#endif
214+
cursor_it->intern.funcs = &php_phongo_cursor_iterator_funcs;
215+
cursor_it->cursor = cursor;
216+
/* cursor_it->current should already be allocated to zero */
217+
218+
php_phongo_cursor_free_current(cursor_it->cursor);
219+
220+
return &cursor_it->intern;
221+
} /* }}} */
222+
/* }}} */
223+
49224
/* {{{ proto void Cursor::setTypeMap(array $typemap)
50225
Sets a type map to use for BSON unserialization */
51226
PHP_METHOD(Cursor, setTypeMap)

0 commit comments

Comments
 (0)