Files
pdlib/src/chinese_whispers.cc
T
Remi Collet 40a2bd60e4 cleanup TSRMLS_C macro
- only used on PHP 5 (not supported by this ext.)
- not needed on PHP 7
- removed from PHP 8
2020-06-22 15:01:30 +02:00

105 lines
2.6 KiB
C++

#include "../php_pdlib.h"
#include "chinese_whispers.h"
#include <zend_exceptions.h>
#include <dlib/clustering.h>
#include <iostream>
using namespace dlib;
using namespace std;
PHP_FUNCTION(dlib_chinese_whispers)
{
zval *edges_arg;
HashTable *edges_arg_hash;
std::vector<sample_pair> edges;
std::vector<unsigned long> labels;
if(zend_parse_parameters(ZEND_NUM_ARGS(), "a", &edges_arg) == FAILURE){
zend_throw_exception_ex(
zend_ce_exception,
0,
"Unable to parse edges in dlib_chinese_whispers");
return;
}
edges_arg_hash = Z_ARRVAL_P(edges_arg);
try {
HashPosition pos;
zval *edge;
HashTable *edge_hash;
// Iterate for all given edges, check if they are valid and put them to edges
//
for (
zend_hash_internal_pointer_reset_ex(edges_arg_hash, &pos);
(edge = zend_hash_get_current_data_ex(edges_arg_hash, &pos)) != nullptr;
zend_hash_move_forward_ex(edges_arg_hash, &pos)) {
// Check that each given edge is actually array
//
if (Z_TYPE_P(edge) != IS_ARRAY) {
zend_throw_exception_ex(
zend_ce_exception,
0,
"Each edge provided in array needs to be numeric array of 2 elements");
return;
}
edge_hash = Z_ARRVAL_P(edge);
// Check that there are two elements in this edge
//
if (zend_hash_num_elements(edge_hash) != 2) {
zend_throw_exception_ex(
zend_ce_exception,
0,
"Edges need to contain exactly two elements");
return;
}
// Check that this is regular array with integer keys
//
if (!zend_hash_index_exists(edge_hash, 0) ||
!zend_hash_index_exists(edge_hash, 1)) {
zend_throw_exception_ex(
zend_ce_exception,
0,
"Edge should be numeric array with integer keys");
return;
}
zval *elem_i = zend_hash_index_find(edge_hash, 0);
zval *elem_j = zend_hash_index_find(edge_hash, 1);
// Check that both elements in array are longs
if ((Z_TYPE_P(elem_i) != IS_LONG) || (Z_TYPE_P(elem_j) != IS_LONG)) {
zend_throw_exception_ex(
zend_ce_exception,
0,
"Both elements in each edge must be of long type");
return;
}
// Finally, put extracted elements to edges
edges.push_back(sample_pair(Z_LVAL_P(elem_i), Z_LVAL_P(elem_j)));
}
chinese_whispers(edges, labels);
// Preparing and generating response array containing labels
//
array_init(return_value);
for (auto label = labels.begin(); label != labels.end(); label++) {
add_next_index_long(return_value, *label);
}
} catch (exception& e)
{
zend_throw_exception_ex(zend_ce_exception, 0, "%s", e.what());
return;
}
}