bfab4101402fb98bdd50bd7aadeb0804ddf94dea
[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)
22 {
23 php_pq_object_t *obj = o;
24
25 ZVAL_OBJ(zv, &obj->zo);
26 Z_ADDREF_P(zv);
27 }
28
29 void php_pq_object_to_zval_no_addref(void *o, zval *zv)
30 {
31 php_pq_object_t *obj = o;
32
33 ZVAL_OBJ(zv, &obj->zo);
34 }
35
36 void php_pq_object_addref(void *o)
37 {
38 php_pq_object_t *obj = o;
39 ++GC_REFCOUNT(&obj->zo);
40 }
41
42 void php_pq_object_delref(void *o TSRMLS_DC)
43 {
44 php_pq_object_t *obj = o;
45 zend_objects_store_del(&obj->zo);
46 }
47
48 struct apply_pi_to_ht_arg {
49 HashTable *ht;
50 zval *object;
51 php_pq_object_t *pq_obj;
52 unsigned addref:1;
53 };
54
55 static int apply_pi_to_ht(zval *p, void *a)
56 {
57 zend_property_info *pi = Z_PTR_P(p);
58 struct apply_pi_to_ht_arg *arg = a;
59 zval tmp_prop, *property = zend_read_property(arg->pq_obj->zo.ce, arg->object, pi->name->val, pi->name->len, 0, &tmp_prop);
60
61 if (arg->addref) {
62 Z_TRY_ADDREF_P(property);
63 }
64 zend_hash_update(arg->ht, pi->name, property);
65
66 return ZEND_HASH_APPLY_KEEP;
67 }
68
69 HashTable *php_pq_object_debug_info(zval *object, int *temp)
70 {
71 struct apply_pi_to_ht_arg arg = {NULL};
72
73 *temp = 1;
74 ALLOC_HASHTABLE(arg.ht);
75 ZEND_INIT_SYMTABLE(arg.ht);
76
77 arg.object = object;
78 arg.pq_obj = PHP_PQ_OBJ(object, NULL);
79 arg.addref = 1;
80
81 zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg);
82
83 return arg.ht;
84 }
85
86 HashTable *php_pq_object_properties(zval *object)
87 {
88 struct apply_pi_to_ht_arg arg = {NULL};
89
90 arg.ht = zend_get_std_object_handlers()->get_properties(object);
91 arg.object = object;
92 arg.pq_obj = PHP_PQ_OBJ(object, NULL);
93 arg.addref = 1;
94
95 zend_hash_apply_with_argument(&arg.pq_obj->zo.ce->properties_info, apply_pi_to_ht, &arg);
96
97 return arg.ht;
98 }
99
100 zend_class_entry *ancestor(zend_class_entry *ce)
101 {
102 while (ce->parent) {
103 ce = ce->parent;
104 }
105 return ce;
106 }
107
108 zval *php_pq_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp)
109 {
110 php_pq_object_t *obj = PHP_PQ_OBJ(object, NULL);
111 php_pq_object_prophandler_t *handler;
112 zval *return_value = NULL;
113
114 if (!obj->intern) {
115 php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name);
116 return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
117 } else if (!(handler= zend_hash_find_ptr(obj->prophandler, Z_STR_P(member))) || !handler->read) {
118 return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
119 } else if (type != BP_VAR_R) {
120 php_error(E_WARNING, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name->val);
121 return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
122 } else {
123 return_value = tmp;
124 handler->read(object, obj, return_value);
125 }
126
127 return return_value;
128 }
129
130 void php_pq_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot)
131 {
132 php_pq_object_t *obj = PHP_PQ_OBJ(object, NULL);
133 php_pq_object_prophandler_t *handler;
134
135 if (!obj->intern) {
136 php_error(E_RECOVERABLE_ERROR, "%s not initialized", ancestor(obj->zo.ce)->name->val);
137 zend_get_std_object_handlers()->write_property(object, member, value, cache_slot);
138 } else if ((handler = zend_hash_find_ptr(obj->prophandler, Z_STR_P(member)))) {
139 if (handler->write) {
140 handler->write(object, obj, value);
141 }
142 } else {
143 zend_get_std_object_handlers()->write_property(object, member, value, cache_slot);
144 }
145 }
146