77207ea82f35136f83f36603ed407b7652e143ee
[m6w6/ext-pq] / src / php_pq_object.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: pq |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <php.h>
18
19 #include "php_pq_object.h"
20
21 void php_pq_object_to_zval(void *o, zval **zv TSRMLS_DC)
22 {
23 php_pq_object_t *obj = o;
24
25 if (!*zv) {
26 MAKE_STD_ZVAL(*zv);
27 }
28
29 zend_objects_store_add_ref_by_handle(obj->zv.handle TSRMLS_CC);
30
31 (*zv)->type = IS_OBJECT;
32 (*zv)->value.obj = obj->zv;
33 }
34
35 void php_pq_object_to_zval_no_addref(void *o, zval **zv TSRMLS_DC)
36 {
37 php_pq_object_t *obj = o;
38
39 if (!*zv) {
40 MAKE_STD_ZVAL(*zv);
41 }
42
43 /* no add ref */
44
45 (*zv)->type = IS_OBJECT;
46 (*zv)->value.obj = obj->zv;
47 }
48
49 void php_pq_object_addref(void *o TSRMLS_DC)
50 {
51 php_pq_object_t *obj = o;
52 zend_objects_store_add_ref_by_handle(obj->zv.handle TSRMLS_CC);
53 }
54
55 void php_pq_object_delref(void *o TSRMLS_DC)
56 {
57 php_pq_object_t *obj = o;
58 zend_objects_store_del_ref_by_handle_ex(obj->zv.handle, obj->zv.handlers TSRMLS_CC);
59 }
60
61 static int apply_pi_to_ht(void *p TSRMLS_DC, int argc, va_list argv, zend_hash_key *key)
62 {
63 zend_property_info *pi = p;
64 HashTable *ht = va_arg(argv, HashTable *);
65 zval *object = va_arg(argv, zval *);
66 php_pq_object_t *obj = va_arg(argv, php_pq_object_t *);
67 int addref = va_arg(argv, int);
68 zval *property = zend_read_property(obj->zo.ce, object, pi->name, pi->name_length, 0 TSRMLS_CC);
69
70 if (addref) {
71 Z_ADDREF_P(property);
72 }
73 zend_hash_update(ht, pi->name, pi->name_length + 1, (void *) &property, sizeof(zval *), NULL);
74
75 return ZEND_HASH_APPLY_KEEP;
76 }
77
78 HashTable *php_pq_object_debug_info(zval *object, int *temp TSRMLS_DC)
79 {
80 HashTable *ht;
81 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
82
83 *temp = 1;
84 ALLOC_HASHTABLE(ht);
85 ZEND_INIT_SYMTABLE(ht);
86
87 zend_hash_apply_with_arguments(&obj->zo.ce->properties_info TSRMLS_CC, apply_pi_to_ht, 4, ht, object, obj, 1);
88
89 return ht;
90 }
91
92 HashTable *php_pq_object_properties(zval *object TSRMLS_DC)
93 {
94 HashTable *ht = zend_get_std_object_handlers()->get_properties(object TSRMLS_CC);
95 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
96
97 zend_hash_apply_with_arguments(&obj->zo.ce->properties_info TSRMLS_CC, apply_pi_to_ht, 4, ht, object, obj, 1);
98
99 return ht;
100 }
101
102 zend_class_entry *ancestor(zend_class_entry *ce)
103 {
104 while (ce->parent) {
105 ce = ce->parent;
106 }
107 return ce;
108 }
109
110 zval *php_pq_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
111 {
112 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
113 php_pq_object_prophandler_t *handler;
114 zval *return_value = NULL;
115
116 if (!obj->intern) {
117 php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name);
118 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
119 } else if ((SUCCESS != zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) || !handler->read) {
120 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
121 } else if (type != BP_VAR_R) {
122 php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name);
123 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
124 } else {
125 ALLOC_ZVAL(return_value);
126 Z_SET_REFCOUNT_P(return_value, 0);
127 Z_UNSET_ISREF_P(return_value);
128
129 handler->read(object, obj, return_value TSRMLS_CC);
130 }
131
132 return return_value;
133 }
134
135 void php_pq_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
136 {
137 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
138 php_pq_object_prophandler_t *handler;
139
140 if (!obj->intern) {
141 php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name);
142 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
143 } else if (SUCCESS == zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
144 if (handler->write) {
145 handler->write(object, obj, value TSRMLS_CC);
146 }
147 } else {
148 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
149 }
150 }
151