split source
[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_add(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 zend_class_entry *ancestor(zend_class_entry *ce)
93 {
94 while (ce->parent) {
95 ce = ce->parent;
96 }
97 return ce;
98 }
99
100 zval *php_pq_object_read_prop(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
101 {
102 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
103 php_pq_object_prophandler_t *handler;
104 zval *return_value;
105
106 if (!obj->intern) {
107 zend_error(E_WARNING, "%s not initialized", ancestor(obj->zo.ce)->name);
108 } else if ((SUCCESS == zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) && handler->read) {
109 if (type == BP_VAR_R) {
110 ALLOC_ZVAL(return_value);
111 Z_SET_REFCOUNT_P(return_value, 0);
112 Z_UNSET_ISREF_P(return_value);
113
114 handler->read(object, obj, return_value TSRMLS_CC);
115 } else {
116 zend_error(E_ERROR, "Cannot access %s properties by reference or array key/index", ancestor(obj->zo.ce)->name);
117 return_value = NULL;
118 }
119 } else {
120 return_value = zend_get_std_object_handlers()->read_property(object, member, type, key TSRMLS_CC);
121 }
122
123 return return_value;
124 }
125
126 void php_pq_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
127 {
128 php_pq_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
129 php_pq_object_prophandler_t *handler;
130
131 if (SUCCESS == zend_hash_find(obj->prophandler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void *) &handler)) {
132 if (handler->write) {
133 handler->write(object, obj, value TSRMLS_CC);
134 }
135 } else {
136 zend_get_std_object_handlers()->write_property(object, member, value, key TSRMLS_CC);
137 }
138 }
139