From b64ffbd9b5553297d67c809264af78de17877a67 Mon Sep 17 00:00:00 2001 From: CismonX Date: Mon, 27 May 2019 16:51:57 +0800 Subject: [PATCH] Add some implementations. --- src/dense_matrix.cc | 19 ++++++- src/matrix.cc | 20 ++++--- src/resizable.cc | 126 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 155 insertions(+), 10 deletions(-) diff --git a/src/dense_matrix.cc b/src/dense_matrix.cc index e8a7790..3460627 100644 --- a/src/dense_matrix.cc +++ b/src/dense_matrix.cc @@ -22,7 +22,7 @@ namespace php_arma Z_PARAM_LONG_DEREF(j) ZEND_PARSE_PARAMETERS_END(); - auto native = to_native_object(Z_OBJ_P(getThis())); + auto native = THIS_NATIVE; zend_object *zobj; try { @@ -42,7 +42,22 @@ namespace php_arma template PHP_ARMA_METHOD(dense_matrix, at, T, T1) { - + zend_long i, j; + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_LONG_DEREF(i) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_DEREF(j) + ZEND_PARSE_PARAMETERS_END(); + + auto native = THIS_NATIVE; + + zend_object *zobj; + if (EX_NUM_ARGS() == 1) { + zobj = mapval_dense::create(&native->at(i)); + } else { + zobj = mapval_dense::create(&native->at(i, j)); + } + RETVAL_OBJ(zobj); } template diff --git a/src/matrix.cc b/src/matrix.cc index 8c23831..ece5023 100644 --- a/src/matrix.cc +++ b/src/matrix.cc @@ -7,42 +7,50 @@ #include "matrix.hh" #include "mat.hh" +#include + namespace php_arma { template PHP_ARMA_METHOD(matrix, nRows, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_LONG(native->n_rows); } template PHP_ARMA_METHOD(matrix, nCols, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_LONG(native->n_cols); } template PHP_ARMA_METHOD(matrix, isVec, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_BOOL(native->is_vec()); } template PHP_ARMA_METHOD(matrix, isCol, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_BOOL(native->is_colvec()); } template PHP_ARMA_METHOD(matrix, isRow, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_BOOL(native->is_rowvec()); } template PHP_ARMA_METHOD(matrix, isSquare, T, T1) { - + auto native = THIS_NATIVE; + RETVAL_BOOL(native->is_square()); } template diff --git a/src/resizable.cc b/src/resizable.cc index fb87033..cd20948 100644 --- a/src/resizable.cc +++ b/src/resizable.cc @@ -6,9 +6,57 @@ #include "resizable.hh" #include "mat.hh" +#include "constants.hh" + +#include + +#ifdef __GNUC__ +#include +#endif // __GNUC__ namespace php_arma { + zend_always_inline + int zval_to_fd(zval *zv) + { + auto stream = reinterpret_cast(zend_fetch_resource2_ex( + zv, "stream", php_file_le_stream(), php_file_le_pstream())); + if (stream == nullptr) { + return -1; + } + struct { + FILE *file; + int fd; + } *stream_data = reinterpret_cast(stream->abstract); + return stream_data->fd; + } + +#ifdef ARMA_USE_HDF5 + zend_always_inline + arma::hdf5_name zend_array_to_hdf5_name(zend_array *ht) + { + auto fname_z = zend_hash_str_find_deref(ht, "file_name", sizeof("file_name") - 1); + std::string fname(fname_z && Z_TYPE_P(fname_z) == IS_STRING ? Z_STRVAL_P(fname_z) : ""); + + auto dsname_z = zend_hash_str_find_deref(ht, "dataset_name", sizeof("dataset_name") - 1); + std::string dsname(dsname_z && Z_TYPE_P(dsname_z) == IS_STRING ? Z_STRVAL_P(dsname_z) : ""); + + auto opts_z = zend_hash_str_find_deref(ht, "options", sizeof("options") - 1); + arma::hdf5_opts::opts opts(opts_z && Z_TYPE_P(opts_z) == IS_LONG ? Z_LVAL_P(opts_z) : hdf5_opts::none); + + return { fname, dsname, opts }; + } +#endif + +#ifndef __GNUC__ + zend_always_inline + void filebuf_unsupported() + { + zend_throw_exception(zend_ce_type_error, "Resource is not yet supported. Use file name instead, " + "or re-compile php-armadillo with a compiler supporting GNU extensions.", 0); + } +#endif // !__GNUC__ + template PHP_ARMA_METHOD(resizable, copySize, T, T1) { @@ -36,13 +84,87 @@ namespace php_arma template PHP_ARMA_METHOD(resizable, save, T, T1) { - + zval *dest; + zend_long file_type = file_type::arma_binary; + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ZVAL_DEREF(dest) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_DEREF(file_type) + ZEND_PARSE_PARAMETERS_END(); + + auto native = THIS_NATIVE; + auto ftype = file_type::native(file_type); + + zend_bool retval; + if (Z_TYPE_P(dest) == IS_STRING) { + RETURN_BOOL(native->save(Z_STRVAL_P(dest), ftype, false)); + } + if (Z_TYPE_P(dest) == IS_RESOURCE) { +#ifdef __GNUC__ + __gnu_cxx::stdio_filebuf filebuf(zval_to_fd(dest), std::ios::out); + std::ostream os(&filebuf); + RETURN_BOOL(native->save(os, ftype, false)); +#else + filebuf_unsupported(); + RETURN_FALSE; +#endif // __GNUC__ + } +#ifdef ARMA_USE_HDF5 + if (Z_TYPE_P(dest) == IS_ARRAY) { + if (ftype != arma::file_type::hdf5_binary) { + ex_bad_type("string or resource", zval_get_type_name(dest)); + RETURN_FALSE; + } + RETURN_BOOL(native->save(zend_array_to_hdf5_name(Z_ARR_P(dest)), ftype, false)); + } + ex_bad_type("string, resource or array", zval_get_type_name(dest)); +#else + ex_bad_type("string or resource", zval_get_type_name(dest)); +#endif // ARMA_USE_HDF5 + RETURN_FALSE; } template PHP_ARMA_METHOD(resizable, load, T, T1) { - + zval *from; + zend_long file_type = file_type::auto_detect; + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ZVAL_DEREF(from) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_DEREF(file_type) + ZEND_PARSE_PARAMETERS_END(); + + auto native = THIS_NATIVE; + auto ftype = file_type::native(file_type); + + zend_bool retval; + if (Z_TYPE_P(from) == IS_STRING) { + RETURN_BOOL(native->load(Z_STRVAL_P(from), ftype, false)); + } + if (Z_TYPE_P(from) == IS_RESOURCE) { +#ifdef __GNUC__ + __gnu_cxx::stdio_filebuf filebuf(zval_to_fd(from), std::ios::in); + std::istream is(&filebuf); + RETURN_BOOL(native->load(is, ftype, false)); +#else + filebuf_unsupported(); + RETURN_FALSE; +#endif // __GNUC__ + } +#ifdef ARMA_USE_HDF5 + if (Z_TYPE_P(from) == IS_ARRAY) { + if (ftype != arma::file_type::hdf5_binary) { + ex_bad_type("string or resource", zval_get_type_name(from)); + RETURN_FALSE; + } + RETURN_BOOL(native->load(zend_array_to_hdf5_name(Z_ARR_P(from)), ftype, false)); + } + ex_bad_type("string, resource or array", zval_get_type_name(from)); +#else + ex_bad_type("string or resource", zval_get_type_name(from)); +#endif // ARMA_USE_HDF5 + RETURN_FALSE; } template