Add some implementations.

This commit is contained in:
CismonX 2019-05-27 16:51:57 +08:00
parent 6eb263b763
commit b64ffbd9b5
3 changed files with 155 additions and 10 deletions

View File

@ -22,7 +22,7 @@ namespace php_arma
Z_PARAM_LONG_DEREF(j)
ZEND_PARSE_PARAMETERS_END();
auto native = to_native_object<native_t>(Z_OBJ_P(getThis()));
auto native = THIS_NATIVE;
zend_object *zobj;
try {
@ -42,7 +42,22 @@ namespace php_arma
template <typename T, typename T1>
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<T>::create(&native->at(i));
} else {
zobj = mapval_dense<T>::create(&native->at(i, j));
}
RETVAL_OBJ(zobj);
}
template <typename T, typename T1>

View File

@ -7,42 +7,50 @@
#include "matrix.hh"
#include "mat.hh"
#include <armadillo>
namespace php_arma
{
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, nRows, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_LONG(native->n_rows);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, nCols, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_LONG(native->n_cols);
}
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, isVec, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_vec());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, isCol, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_colvec());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, isRow, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_rowvec());
}
template <typename T, typename T1>
PHP_ARMA_METHOD(matrix, isSquare, T, T1)
{
auto native = THIS_NATIVE;
RETVAL_BOOL(native->is_square());
}
template <typename T, typename T1>

View File

@ -6,9 +6,57 @@
#include "resizable.hh"
#include "mat.hh"
#include "constants.hh"
#include <armadillo>
#ifdef __GNUC__
#include <ext/stdio_filebuf.h>
#endif // __GNUC__
namespace php_arma
{
zend_always_inline
int zval_to_fd(zval *zv)
{
auto stream = reinterpret_cast<php_stream*>(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<decltype(stream_data)>(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 <typename T, typename T1>
PHP_ARMA_METHOD(resizable, copySize, T, T1)
{
@ -36,13 +84,87 @@ namespace php_arma
template <typename T, typename T1>
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<char> 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 <typename T, typename T1>
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<char> 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 <typename T, typename T1>