Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7843292

Browse files
committed
wip PHPC-2474: BinaryVector support
1 parent f15d862 commit 7843292

11 files changed

+443
-12
lines changed

‎php_phongo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ PHP_MINIT_FUNCTION(mongodb) /* {{{ */
235235
php_phongo_document_init_ce(INIT_FUNC_ARGS_PASSTHRU);
236236

237237
php_phongo_binary_init_ce(INIT_FUNC_ARGS_PASSTHRU);
238+
php_phongo_binaryvector_init_ce(INIT_FUNC_ARGS_PASSTHRU);
238239
php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS_PASSTHRU);
239240
php_phongo_decimal128_init_ce(INIT_FUNC_ARGS_PASSTHRU);
240241
php_phongo_int64_init_ce(INIT_FUNC_ARGS_PASSTHRU);

‎src/BSON/Binary.c

Lines changed: 257 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020

2121
#include "php_phongo.h"
2222
#include "phongo_error.h"
23+
#include "Binary.h"
2324
#include "Binary_arginfo.h"
24-
25-
#define PHONGO_BINARY_UUID_SIZE 16
25+
#include "BinaryVector_arginfo.h"
2626

2727
zend_class_entry* php_phongo_binary_ce;
2828

29+
static phongo_bson_vector_type_t phongo_binary_get_vector_type_from_data(const uint8_t* data, uint32_t data_len);
30+
2931
/* Initialize the object and return whether it was successful. An exception will
3032
* be thrown on error. */
3133
static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data, size_t data_len, zend_long type)
@@ -40,6 +42,11 @@ static bool php_phongo_binary_init(php_phongo_binary_t* intern, const char* data
4042
return false;
4143
}
4244

45+
if ((type == BSON_SUBTYPE_VECTOR) && phongo_binary_get_vector_type_from_data((const uint8_t*) data, data_len) == PHONGO_BSON_VECTOR_TYPE_INVALID) {
46+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Binary vector data is invalid");
47+
return false;
48+
}
49+
4350
intern->data = estrndup(data, data_len);
4451
intern->data_len = data_len;
4552
intern->type = (uint8_t) type;
@@ -299,6 +306,7 @@ bool phongo_binary_new(zval* object, const char* data, size_t data_len, bson_sub
299306
{
300307
php_phongo_binary_t* intern;
301308

309+
// TODO: Support BinaryVector
302310
object_init_ex(object, php_phongo_binary_ce);
303311

304312
intern = Z_BINARY_OBJ_P(object);
@@ -308,3 +316,250 @@ bool phongo_binary_new(zval* object, const char* data, size_t data_len, bson_sub
308316

309317
return true;
310318
}
319+
320+
/* MongoDB\BSON\BinaryVector implementation */
321+
322+
zend_class_entry* php_phongo_binaryvector_ce;
323+
324+
static PHP_METHOD(MongoDB_BSON_BinaryVector, __construct)
325+
{
326+
php_phongo_binary_t* intern;
327+
zval* vector;
328+
zend_long vector_type;
329+
330+
intern = Z_BINARY_OBJ_P(getThis());
331+
332+
PHONGO_PARSE_PARAMETERS_START(2, 2)
333+
Z_PARAM_ARRAY(vector)
334+
Z_PARAM_LONG(vector_type)
335+
PHONGO_PARSE_PARAMETERS_END();
336+
337+
if (!zend_array_is_list(Z_ARRVAL_P(vector))) {
338+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector to be a list");
339+
return;
340+
}
341+
342+
const size_t vector_len = zend_array_count(Z_ARRVAL_P(vector));
343+
344+
/*
345+
bson_t doc = BSON_INITIALIZER;
346+
347+
php_phongo_zval_to_bson(vector, PHONGO_BSON_NONE, &doc, NULL);
348+
349+
if (EG(exception)) {
350+
return;
351+
}
352+
353+
bson_iter_t iter;
354+
bson_error_t error;
355+
356+
bson_iter_init(&iter, &doc);
357+
358+
if (!BSON_APPEND_VECTOR_INT8_FROM_ARRAY(&bson, "vector", &iter, &err)) {
359+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s", error.message);
360+
return;
361+
}
362+
*/
363+
364+
bson_t doc = BSON_INITIALIZER;
365+
366+
if (vector_type == PHONGO_BSON_VECTOR_TYPE_INT8) {
367+
bson_vector_int8_view_t view;
368+
369+
if (!BSON_APPEND_VECTOR_INT8_UNINIT(&doc, "vector", vector_len, &view)) {
370+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "BSON_APPEND_VECTOR_INT8_UNINIT failed for vector of size %zu", vector_len);
371+
RETURN_THROWS();
372+
}
373+
374+
zval* val;
375+
size_t i = 0;
376+
377+
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(vector), val)
378+
{
379+
if (Z_TYPE_P(val) != IS_LONG) {
380+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be an integer, %s given", i, zend_zval_type_name(val));
381+
RETURN_THROWS();
382+
}
383+
384+
if (Z_LVAL_P(val) < INT8_MIN || Z_LVAL_P(val) > INT8_MAX) {
385+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected vector[%zu] to be a signed 8-bit integer, %" PHONGO_LONG_FORMAT " given", i, Z_LVAL_P(val));
386+
RETURN_THROWS();
387+
}
388+
389+
int8_t v = (int8_t) Z_LVAL_P(val);
390+
391+
if (!bson_vector_int8_view_write(view, &v, 1, i)) {
392+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "bson_vector_int8_view_write failed to write vector[%zu]", i);
393+
RETURN_THROWS();
394+
}
395+
396+
i += 1;
397+
}
398+
ZEND_HASH_FOREACH_END();
399+
} else {
400+
// TODO: Support PHONGO_BSON_VECTOR_TYPE_FLOAT32 and PHONGO_BSON_VECTOR_TYPE_PACKED_BIT
401+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Unsupported vector type: %" PHONGO_LONG_FORMAT, vector_type);
402+
RETURN_THROWS();
403+
}
404+
405+
bson_iter_t iter;
406+
407+
if (bson_iter_init_find(&iter, &doc, "vector") && BSON_ITER_HOLDS_BINARY(&iter)) {
408+
uint32_t data_len;
409+
const uint8_t* data;
410+
411+
bson_iter_binary(&iter, NULL, &data_len, &data);
412+
php_phongo_binary_init(intern, (const char*) data, data_len, BSON_SUBTYPE_VECTOR);
413+
}
414+
}
415+
416+
static phongo_bson_vector_type_t phongo_binary_get_vector_type_from_data(const uint8_t* data, uint32_t data_len)
417+
{
418+
if (bson_vector_int8_const_view_init(NULL, data, data_len)) {
419+
return PHONGO_BSON_VECTOR_TYPE_INT8;
420+
}
421+
422+
if (bson_vector_float32_const_view_init(NULL, data, data_len)) {
423+
return PHONGO_BSON_VECTOR_TYPE_FLOAT32;
424+
}
425+
426+
if (bson_vector_packed_bit_const_view_init(NULL, data, data_len)) {
427+
return PHONGO_BSON_VECTOR_TYPE_PACKED_BIT;
428+
}
429+
430+
return PHONGO_BSON_VECTOR_TYPE_INVALID;
431+
}
432+
433+
static phongo_bson_vector_type_t phongo_binary_get_vector_type(const php_phongo_binary_t* intern)
434+
{
435+
return phongo_binary_get_vector_type_from_data((const uint8_t*) intern->data, intern->data_len);
436+
}
437+
438+
static PHP_METHOD(MongoDB_BSON_BinaryVector, getVectorType)
439+
{
440+
PHONGO_PARSE_PARAMETERS_NONE();
441+
442+
php_phongo_binary_t* intern = Z_BINARY_OBJ_P(getThis());
443+
phongo_bson_vector_type_t type = phongo_binary_get_vector_type(intern);
444+
445+
// The vector should always be valid by this point, but check for an error
446+
if (type == PHONGO_BSON_VECTOR_TYPE_INVALID) {
447+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Binary vector data is invalid");
448+
RETURN_THROWS();
449+
}
450+
451+
RETURN_LONG(type);
452+
}
453+
454+
static PHP_METHOD(MongoDB_BSON_BinaryVector, toArray)
455+
{
456+
PHONGO_PARSE_PARAMETERS_NONE();
457+
458+
php_phongo_binary_t* intern = Z_BINARY_OBJ_P(getThis());
459+
phongo_bson_vector_type_t type = phongo_binary_get_vector_type(intern);
460+
461+
// The vector should always be valid by this point, but check for an error
462+
if (type == PHONGO_BSON_VECTOR_TYPE_INVALID) {
463+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Binary vector data is invalid");
464+
RETURN_THROWS();
465+
}
466+
467+
bson_t doc = BSON_INITIALIZER;
468+
469+
if (type == PHONGO_BSON_VECTOR_TYPE_INT8) {
470+
bson_vector_int8_const_view_t view;
471+
472+
if (!bson_vector_int8_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) ||
473+
!BSON_APPEND_ARRAY_FROM_VECTOR_INT8(&doc, "vector", view)) {
474+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array");
475+
bson_destroy(&doc);
476+
RETURN_THROWS();
477+
}
478+
} else if (type == PHONGO_BSON_VECTOR_TYPE_FLOAT32) {
479+
bson_vector_float32_const_view_t view;
480+
481+
if (!bson_vector_float32_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) ||
482+
!BSON_APPEND_ARRAY_FROM_VECTOR_FLOAT32(&doc, "vector", view)) {
483+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array");
484+
bson_destroy(&doc);
485+
RETURN_THROWS();
486+
}
487+
} else if (type == PHONGO_BSON_VECTOR_TYPE_PACKED_BIT) {
488+
bson_vector_packed_bit_const_view_t view;
489+
490+
if (!bson_vector_packed_bit_const_view_init(&view, (const uint8_t*) intern->data, intern->data_len) ||
491+
!BSON_APPEND_ARRAY_FROM_VECTOR_PACKED_BIT(&doc, "vector", view)) {
492+
phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE, "Failed to convert binary vector data to an array");
493+
bson_destroy(&doc);
494+
RETURN_THROWS();
495+
}
496+
}
497+
498+
php_phongo_bson_state state;
499+
PHONGO_BSON_INIT_STATE(state);
500+
state.is_visiting_array = true;
501+
502+
if (!php_phongo_bson_to_zval_ex(&doc, &state)) {
503+
// Exception already thrown
504+
bson_destroy(&doc);
505+
zval_ptr_dtor(&state.zchild);
506+
php_phongo_bson_typemap_dtor(&state.map);
507+
RETURN_THROWS();
508+
}
509+
510+
bson_destroy(&doc);
511+
php_phongo_bson_typemap_dtor(&state.map);
512+
513+
RETURN_ZVAL(&state.zchild, 0, 1);
514+
}
515+
516+
static PHP_METHOD(MongoDB_BSON_BinaryVector, __set_state)
517+
{
518+
php_phongo_binary_t* intern;
519+
HashTable* props;
520+
zval* array;
521+
522+
PHONGO_PARSE_PARAMETERS_START(1, 1)
523+
Z_PARAM_ARRAY(array)
524+
PHONGO_PARSE_PARAMETERS_END();
525+
526+
/* This implementation is similar to Binary::__set_state(), except that we
527+
* initialize a BinaryVector object and also validate its data. */
528+
object_init_ex(return_value, php_phongo_binaryvector_ce);
529+
530+
intern = Z_BINARY_OBJ_P(return_value);
531+
props = Z_ARRVAL_P(array);
532+
533+
php_phongo_binary_init_from_hash(intern, props);
534+
535+
if (intern->type != BSON_SUBTYPE_VECTOR || phongo_binary_get_vector_type(intern) == PHONGO_BSON_VECTOR_TYPE_INVALID) {
536+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Binary vector data is invalid");
537+
RETURN_THROWS();
538+
}
539+
}
540+
541+
/* MongoDB\BSON\BinaryVector object handlers */
542+
static zend_object_handlers php_phongo_handler_binaryvector;
543+
544+
static zend_object* php_phongo_binaryvector_create_object(zend_class_entry* class_type)
545+
{
546+
php_phongo_binary_t* intern = zend_object_alloc(sizeof(php_phongo_binary_t), class_type);
547+
548+
zend_object_std_init(&intern->std, class_type);
549+
object_properties_init(&intern->std, class_type);
550+
551+
intern->std.handlers = &php_phongo_handler_binaryvector;
552+
553+
return &intern->std;
554+
}
555+
556+
void php_phongo_binaryvector_init_ce(INIT_FUNC_ARGS)
557+
{
558+
php_phongo_binaryvector_ce = register_class_MongoDB_BSON_BinaryVector(php_phongo_binary_ce);
559+
php_phongo_binaryvector_ce->create_object = php_phongo_binaryvector_create_object;
560+
561+
memcpy(&php_phongo_handler_binaryvector, &php_phongo_handler_binary, sizeof(zend_object_handlers));
562+
// TODO: Override debug and prop handlers to include vector
563+
//php_phongo_handler_binaryvector.get_debug_info = php_phongo_binaryvector_get_debug_info;
564+
//php_phongo_handler_binaryvector.get_properties = php_phongo_binaryvector_get_properties;
565+
}

‎src/BSON/Binary.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919

2020
#define PHONGO_BINARY_UUID_SIZE 16
2121

22+
typedef enum {
23+
PHONGO_BSON_VECTOR_TYPE_INVALID = 0,
24+
PHONGO_BSON_VECTOR_TYPE_INT8 = 0x03,
25+
PHONGO_BSON_VECTOR_TYPE_FLOAT32 = 0x27,
26+
PHONGO_BSON_VECTOR_TYPE_PACKED_BIT = 0x10,
27+
} phongo_bson_vector_type_t;
28+
2229
bool phongo_binary_new(zval* object, const char* data, size_t data_len, bson_subtype_t type);
2330

2431
#endif /* PHONGO_BSON_BINARY_H */

‎src/BSON/Binary.stub.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace MongoDB\BSON;
99

10-
finalclass Binary implements BinaryInterface, \JsonSerializable, Type, \Stringable
10+
class Binary implements BinaryInterface, \JsonSerializable, Type, \Stringable
1111
{
1212
/**
1313
* @var int
@@ -63,19 +63,25 @@ final class Binary implements BinaryInterface, \JsonSerializable, Type, \Stringa
6363
*/
6464
public const TYPE_SENSITIVE = UNKNOWN;
6565

66+
/**
67+
* @var int
68+
* @cvalue BSON_SUBTYPE_VECTOR
69+
*/
70+
public const TYPE_VECTOR = UNKNOWN;
71+
6672
/**
6773
* @var int
6874
* @cvalue BSON_SUBTYPE_USER
6975
*/
7076
public const TYPE_USER_DEFINED = UNKNOWN;
7177

72-
finalpublic function __construct(string $data, int $type = Binary::TYPE_GENERIC) {}
78+
public function __construct(string $data, int $type = Binary::TYPE_GENERIC) {}
7379

7480
final public function getData(): string {}
7581

7682
final public function getType(): int {}
7783

78-
finalpublic static function __set_state(array $properties): Binary {}
84+
public static function __set_state(array $properties): Binary {}
7985

8086
final public function __toString(): string {}
8187

‎src/BSON/BinaryVector.stub.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/**
4+
* @generate-class-entries static
5+
* @generate-function-entries static
6+
*/
7+
8+
namespace MongoDB\BSON;
9+
10+
class BinaryVector extends Binary
11+
{
12+
/**
13+
* @var int
14+
* @cvalue PHONGO_BSON_VECTOR_TYPE_INT8
15+
*/
16+
public const VECTOR_TYPE_INT8 = UNKNOWN;
17+
18+
/**
19+
* @var int
20+
* @cvalue PHONGO_BSON_VECTOR_TYPE_FLOAT32
21+
*/
22+
public const VECTOR_TYPE_FLOAT32 = UNKNOWN;
23+
24+
/**
25+
* @var int
26+
* @cvalue PHONGO_BSON_VECTOR_TYPE_PACKED_BIT
27+
*/
28+
public const VECTOR_TYPE_PACKED_BIT = UNKNOWN;
29+
30+
final public function __construct(array $vector, int $type) {}
31+
32+
final public function getVectorType(): int {}
33+
34+
final public function toArray(): array {}
35+
36+
final public static function __set_state(array $properties): BinaryVector {}
37+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /