~ubuntu-branches/debian/sid/php-cassandra/sid

« back to all changes in this revision

Viewing changes to cassandra-1.3.0/src/Set.c

  • Committer: Package Import Robot
  • Author(s): Ondřej Surý
  • Date: 2017-04-18 17:16:30 UTC
  • Revision ID: package-import@ubuntu.com-20170418171630-fw8udixss0879s32
Tags: upstream-1.3.0
Import upstream version 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright 2015-2016 DataStax, Inc.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 * http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include "php_driver.h"
 
18
#include "php_driver_types.h"
 
19
#include "util/collections.h"
 
20
#include "util/hash.h"
 
21
#include "util/types.h"
 
22
#include "src/Set.h"
 
23
 
 
24
zend_class_entry *php_driver_set_ce = NULL;
 
25
 
 
26
int
 
27
php_driver_set_add(php_driver_set *set, zval *object TSRMLS_DC)
 
28
{
 
29
  php_driver_set_entry *entry;
 
30
  php_driver_type *type;
 
31
 
 
32
  if (Z_TYPE_P(object) == IS_NULL) {
 
33
    zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
 
34
                            "Invalid value: null is not supported inside sets");
 
35
    return 0;
 
36
  }
 
37
 
 
38
  type = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(set->type));
 
39
 
 
40
  if (!php_driver_validate_object(object, PHP5TO7_ZVAL_MAYBE_P(type->data.set.value_type) TSRMLS_CC)) {
 
41
    return 0;
 
42
  }
 
43
 
 
44
  HASH_FIND_ZVAL(set->entries, object, entry);
 
45
  if (entry == NULL) {
 
46
    set->dirty = 1;
 
47
    entry = (php_driver_set_entry *) emalloc(sizeof(php_driver_set_entry));
 
48
    PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(entry->value), object);
 
49
    HASH_ADD_ZVAL(set->entries, value, entry);
 
50
  }
 
51
 
 
52
  return 1;
 
53
}
 
54
 
 
55
static int
 
56
php_driver_set_del(php_driver_set *set, zval *object TSRMLS_DC)
 
57
{
 
58
  php_driver_set_entry *entry;
 
59
  php_driver_type *type;
 
60
  int result = 0;
 
61
 
 
62
  type = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(set->type));
 
63
 
 
64
  if (!php_driver_validate_object(object, PHP5TO7_ZVAL_MAYBE_P(type->data.set.value_type) TSRMLS_CC)) {
 
65
    return 0;
 
66
  }
 
67
 
 
68
  HASH_FIND_ZVAL(set->entries, object, entry);
 
69
  if (entry != NULL) {
 
70
    set->dirty = 1;
 
71
    if (entry == set->iter_temp) {
 
72
      set->iter_temp = (php_driver_set_entry *)set->iter_temp->hh.next;
 
73
    }
 
74
    HASH_DEL(set->entries, entry);
 
75
    zval_ptr_dtor(&entry->value);
 
76
    efree(entry);
 
77
    result = 1;
 
78
  }
 
79
 
 
80
  return result;
 
81
}
 
82
 
 
83
static int
 
84
php_driver_set_has(php_driver_set *set, zval *object TSRMLS_DC)
 
85
{
 
86
  php_driver_set_entry *entry;
 
87
  php_driver_type *type;
 
88
  int result = 0;
 
89
 
 
90
  type = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(set->type));
 
91
 
 
92
  if (!php_driver_validate_object(object, PHP5TO7_ZVAL_MAYBE_P(type->data.set.value_type) TSRMLS_CC)) {
 
93
    return 0;
 
94
  }
 
95
 
 
96
  HASH_FIND_ZVAL(set->entries, object, entry);
 
97
  if (entry != NULL) {
 
98
    result = 1;
 
99
  }
 
100
 
 
101
  return result;
 
102
}
 
103
 
 
104
static void
 
105
php_driver_set_populate(php_driver_set *set, zval *array TSRMLS_DC)
 
106
{
 
107
  php_driver_set_entry *curr, *temp;
 
108
  HASH_ITER(hh, set->entries, curr, temp) {
 
109
    if (add_next_index_zval(array, PHP5TO7_ZVAL_MAYBE_P(curr->value)) != SUCCESS) {
 
110
      break;
 
111
    }
 
112
    Z_TRY_ADDREF_P(PHP5TO7_ZVAL_MAYBE_P(curr->value));
 
113
  }
 
114
}
 
115
 
 
116
/* {{{ Set::__construct(type) */
 
117
PHP_METHOD(Set, __construct)
 
118
{
 
119
  php_driver_set *self;
 
120
  zval *type;
 
121
 
 
122
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &type) == FAILURE)
 
123
    return;
 
124
 
 
125
  self = PHP_DRIVER_GET_SET(getThis());
 
126
 
 
127
  if (Z_TYPE_P(type) == IS_STRING) {
 
128
    CassValueType value_type;
 
129
    if (!php_driver_value_type(Z_STRVAL_P(type), &value_type TSRMLS_CC))
 
130
      return;
 
131
    self->type = php_driver_type_set_from_value_type(value_type TSRMLS_CC);
 
132
  } else if (Z_TYPE_P(type) == IS_OBJECT &&
 
133
             instanceof_function(Z_OBJCE_P(type), php_driver_type_ce TSRMLS_CC)) {
 
134
    if (!php_driver_type_validate(type, "type" TSRMLS_CC)) {
 
135
      return;
 
136
    }
 
137
    self->type = php_driver_type_set(type TSRMLS_CC);
 
138
    Z_ADDREF_P(type);
 
139
  } else {
 
140
    INVALID_ARGUMENT(type, "a string or an instance of " PHP_DRIVER_NAMESPACE "\\Type");
 
141
  }
 
142
}
 
143
/* }}} */
 
144
 
 
145
/* {{{ Set::type() */
 
146
PHP_METHOD(Set, type)
 
147
{
 
148
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
149
  RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(self->type), 1, 0);
 
150
}
 
151
/* }}} */
 
152
 
 
153
/* {{{ Set::values() */
 
154
PHP_METHOD(Set, values)
 
155
{
 
156
  php_driver_set *set = NULL;
 
157
  array_init(return_value);
 
158
  set = PHP_DRIVER_GET_SET(getThis());
 
159
  php_driver_set_populate(set, return_value TSRMLS_CC);
 
160
}
 
161
/* }}} */
 
162
 
 
163
/* {{{ Set::add(value) */
 
164
PHP_METHOD(Set, add)
 
165
{
 
166
  php_driver_set *self = NULL;
 
167
 
 
168
  zval *object;
 
169
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &object) == FAILURE)
 
170
    return;
 
171
 
 
172
  self = PHP_DRIVER_GET_SET(getThis());
 
173
 
 
174
  if (php_driver_set_add(self, object TSRMLS_CC))
 
175
    RETURN_TRUE;
 
176
 
 
177
  RETURN_FALSE;
 
178
}
 
179
/* }}} */
 
180
 
 
181
/* {{{ Set::remove(value) */
 
182
PHP_METHOD(Set, remove)
 
183
{
 
184
  php_driver_set *self = NULL;
 
185
 
 
186
  zval *object;
 
187
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &object) == FAILURE)
 
188
    return;
 
189
 
 
190
  self = PHP_DRIVER_GET_SET(getThis());
 
191
 
 
192
  if (php_driver_set_del(self, object TSRMLS_CC))
 
193
    RETURN_TRUE;
 
194
 
 
195
  RETURN_FALSE;
 
196
}
 
197
/* }}} */
 
198
 
 
199
/* {{{ Set::has(value) */
 
200
PHP_METHOD(Set, has)
 
201
{
 
202
  php_driver_set *self = NULL;
 
203
 
 
204
  zval *object;
 
205
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &object) == FAILURE)
 
206
    return;
 
207
 
 
208
  self = PHP_DRIVER_GET_SET(getThis());
 
209
 
 
210
  if (php_driver_set_has(self, object TSRMLS_CC))
 
211
    RETURN_TRUE;
 
212
 
 
213
  RETURN_FALSE;
 
214
}
 
215
/* }}} */
 
216
 
 
217
/* {{{ Set::count() */
 
218
PHP_METHOD(Set, count)
 
219
{
 
220
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
221
  RETURN_LONG((long)HASH_COUNT(self->entries));
 
222
}
 
223
/* }}} */
 
224
 
 
225
/* {{{ Set::current() */
 
226
PHP_METHOD(Set, current)
 
227
{
 
228
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
229
  if (self->iter_curr != NULL)
 
230
    RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(self->iter_curr->value), 1, 0);
 
231
}
 
232
/* }}} */
 
233
 
 
234
/* {{{ Set::key() */
 
235
PHP_METHOD(Set, key)
 
236
{
 
237
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
238
  RETURN_LONG(self->iter_index);
 
239
}
 
240
/* }}} */
 
241
 
 
242
/* {{{ Set::next() */
 
243
PHP_METHOD(Set, next)
 
244
{
 
245
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
246
  self->iter_curr = self->iter_temp;
 
247
  self->iter_temp = self->iter_temp != NULL ? (php_driver_set_entry *)self->iter_temp->hh.next : NULL;
 
248
  self->iter_index++;
 
249
}
 
250
/* }}} */
 
251
 
 
252
/* {{{ Set::valid() */
 
253
PHP_METHOD(Set, valid)
 
254
{
 
255
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
256
  RETURN_BOOL(self->iter_curr != NULL);
 
257
}
 
258
/* }}} */
 
259
 
 
260
/* {{{ Set::rewind() */
 
261
PHP_METHOD(Set, rewind)
 
262
{
 
263
  php_driver_set *self = PHP_DRIVER_GET_SET(getThis());
 
264
  self->iter_curr = self->entries;
 
265
  self->iter_temp = self->entries != NULL ? (php_driver_set_entry *)self->entries->hh.next : NULL;
 
266
  self->iter_index = 0;
 
267
}
 
268
/* }}} */
 
269
 
 
270
ZEND_BEGIN_ARG_INFO_EX(arginfo__construct, 0, ZEND_RETURN_VALUE, 1)
 
271
  ZEND_ARG_INFO(0, type)
 
272
ZEND_END_ARG_INFO()
 
273
 
 
274
ZEND_BEGIN_ARG_INFO_EX(arginfo_one, 0, ZEND_RETURN_VALUE, 1)
 
275
  ZEND_ARG_INFO(0, value)
 
276
ZEND_END_ARG_INFO()
 
277
 
 
278
ZEND_BEGIN_ARG_INFO_EX(arginfo_none, 0, ZEND_RETURN_VALUE, 0)
 
279
ZEND_END_ARG_INFO()
 
280
 
 
281
static zend_function_entry php_driver_set_methods[] = {
 
282
  PHP_ME(Set, __construct, arginfo__construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
 
283
  PHP_ME(Set, type, arginfo_none, ZEND_ACC_PUBLIC)
 
284
  PHP_ME(Set, values, arginfo_none, ZEND_ACC_PUBLIC)
 
285
  PHP_ME(Set, add, arginfo_one, ZEND_ACC_PUBLIC)
 
286
  PHP_ME(Set, has, arginfo_one, ZEND_ACC_PUBLIC)
 
287
  PHP_ME(Set, remove, arginfo_one, ZEND_ACC_PUBLIC)
 
288
  /* Countable */
 
289
  PHP_ME(Set, count, arginfo_none, ZEND_ACC_PUBLIC)
 
290
  /* Iterator */
 
291
  PHP_ME(Set, current, arginfo_none, ZEND_ACC_PUBLIC)
 
292
  PHP_ME(Set, key, arginfo_none, ZEND_ACC_PUBLIC)
 
293
  PHP_ME(Set, next, arginfo_none, ZEND_ACC_PUBLIC)
 
294
  PHP_ME(Set, valid, arginfo_none, ZEND_ACC_PUBLIC)
 
295
  PHP_ME(Set, rewind, arginfo_none, ZEND_ACC_PUBLIC)
 
296
  PHP_FE_END
 
297
};
 
298
 
 
299
static php_driver_value_handlers php_driver_set_handlers;
 
300
 
 
301
static HashTable *
 
302
php_driver_set_gc(zval *object, php5to7_zval_gc table, int *n TSRMLS_DC)
 
303
{
 
304
  *table = NULL;
 
305
  *n = 0;
 
306
  return zend_std_get_properties(object TSRMLS_CC);
 
307
}
 
308
 
 
309
static HashTable *
 
310
php_driver_set_properties(zval *object TSRMLS_DC)
 
311
{
 
312
  php5to7_zval values;
 
313
 
 
314
  php_driver_set *self = PHP_DRIVER_GET_SET(object);
 
315
  HashTable     *props = zend_std_get_properties(object TSRMLS_CC);
 
316
 
 
317
 
 
318
  PHP5TO7_ZEND_HASH_UPDATE(props,
 
319
                           "type", sizeof("type"),
 
320
                           PHP5TO7_ZVAL_MAYBE_P(self->type), sizeof(zval));
 
321
  Z_ADDREF_P(PHP5TO7_ZVAL_MAYBE_P(self->type));
 
322
 
 
323
  PHP5TO7_ZVAL_MAYBE_MAKE(values);
 
324
  array_init(PHP5TO7_ZVAL_MAYBE_P(values));
 
325
  php_driver_set_populate(self , PHP5TO7_ZVAL_MAYBE_P(values) TSRMLS_CC);
 
326
  PHP5TO7_ZEND_HASH_SORT(Z_ARRVAL_P(PHP5TO7_ZVAL_MAYBE_P(values)), php_driver_data_compare, 1);
 
327
  PHP5TO7_ZEND_HASH_UPDATE(props, "values", sizeof("values"), PHP5TO7_ZVAL_MAYBE_P(values), sizeof(zval));
 
328
 
 
329
  return props;
 
330
}
 
331
 
 
332
static int
 
333
php_driver_set_compare(zval *obj1, zval *obj2 TSRMLS_DC)
 
334
{
 
335
  php_driver_set_entry *curr, *temp;
 
336
  php_driver_set *set1;
 
337
  php_driver_set *set2;
 
338
  php_driver_type *type1;
 
339
  php_driver_type *type2;
 
340
  int result;
 
341
 
 
342
  if (Z_OBJCE_P(obj1) != Z_OBJCE_P(obj2))
 
343
    return 1; /* different classes */
 
344
 
 
345
  set1 = PHP_DRIVER_GET_SET(obj1);
 
346
  set2 = PHP_DRIVER_GET_SET(obj2);
 
347
 
 
348
  type1 = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(set1->type));
 
349
  type2 = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(set2->type));
 
350
 
 
351
  result = php_driver_type_compare(type1, type2 TSRMLS_CC);
 
352
  if (result != 0) return result;
 
353
 
 
354
  if (HASH_COUNT(set1->entries) != HASH_COUNT(set1->entries)) {
 
355
   return HASH_COUNT(set1->entries) < HASH_COUNT(set1->entries) ? -1 : 1;
 
356
  }
 
357
 
 
358
  HASH_ITER(hh, set1->entries, curr, temp) {
 
359
    php_driver_set_entry *entry;
 
360
    HASH_FIND_ZVAL(set2->entries, PHP5TO7_ZVAL_MAYBE_P(curr->value), entry);
 
361
    if (entry == NULL) {
 
362
      return 1;
 
363
    }
 
364
  }
 
365
 
 
366
  return 0;
 
367
}
 
368
 
 
369
static unsigned
 
370
php_driver_set_hash_value(zval *obj TSRMLS_DC)
 
371
{
 
372
  unsigned hashv = 0;
 
373
  php_driver_set_entry *curr,  *temp;
 
374
  php_driver_set *self = PHP_DRIVER_GET_SET(obj);
 
375
 
 
376
  if (!self->dirty) return self->hashv;
 
377
 
 
378
  HASH_ITER(hh, self->entries, curr, temp) {
 
379
    hashv = php_driver_combine_hash(hashv, php_driver_value_hash(PHP5TO7_ZVAL_MAYBE_P(curr->value) TSRMLS_CC));
 
380
  }
 
381
 
 
382
  self->hashv = hashv;
 
383
  self->dirty = 0;
 
384
 
 
385
  return hashv;
 
386
}
 
387
 
 
388
static void
 
389
php_driver_set_free(php5to7_zend_object_free *object TSRMLS_DC)
 
390
{
 
391
  php_driver_set *self = PHP5TO7_ZEND_OBJECT_GET(set, object);
 
392
  php_driver_set_entry *curr, *temp;
 
393
 
 
394
  HASH_ITER(hh, self->entries, curr, temp) {
 
395
    zval_ptr_dtor(&curr->value);
 
396
    HASH_DEL(self->entries, curr);
 
397
    efree(curr);
 
398
  }
 
399
 
 
400
  PHP5TO7_ZVAL_MAYBE_DESTROY(self->type);
 
401
 
 
402
  zend_object_std_dtor(&self->zval TSRMLS_CC);
 
403
  PHP5TO7_MAYBE_EFREE(self);
 
404
}
 
405
 
 
406
static php5to7_zend_object
 
407
php_driver_set_new(zend_class_entry *ce TSRMLS_DC)
 
408
{
 
409
  php_driver_set *self =
 
410
      PHP5TO7_ZEND_OBJECT_ECALLOC(set, ce);
 
411
 
 
412
  self->entries = self->iter_curr = self->iter_temp = NULL;
 
413
  self->iter_index = 0;
 
414
  self->dirty = 1;
 
415
  PHP5TO7_ZVAL_UNDEF(self->type);
 
416
 
 
417
  PHP5TO7_ZEND_OBJECT_INIT(set, self, ce);
 
418
}
 
419
 
 
420
void php_driver_define_Set(TSRMLS_D)
 
421
{
 
422
  zend_class_entry ce;
 
423
 
 
424
  INIT_CLASS_ENTRY(ce, PHP_DRIVER_NAMESPACE "\\Set", php_driver_set_methods);
 
425
  php_driver_set_ce = zend_register_internal_class(&ce TSRMLS_CC);
 
426
  zend_class_implements(php_driver_set_ce TSRMLS_CC, 1, php_driver_value_ce);
 
427
  memcpy(&php_driver_set_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
 
428
  php_driver_set_handlers.std.get_properties  = php_driver_set_properties;
 
429
#if PHP_VERSION_ID >= 50400
 
430
  php_driver_set_handlers.std.get_gc          = php_driver_set_gc;
 
431
#endif
 
432
  php_driver_set_handlers.std.compare_objects = php_driver_set_compare;
 
433
  php_driver_set_ce->ce_flags |= PHP5TO7_ZEND_ACC_FINAL;
 
434
  php_driver_set_ce->create_object = php_driver_set_new;
 
435
  zend_class_implements(php_driver_set_ce TSRMLS_CC, 2, spl_ce_Countable, zend_ce_iterator);
 
436
 
 
437
  php_driver_set_handlers.hash_value = php_driver_set_hash_value;
 
438
  php_driver_set_handlers.std.clone_obj = NULL;
 
439
}