From 8ec32aaa8fb03f4cb155223ea601e63086c97223 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 20 Mar 2024 03:07:51 +0900 Subject: [PATCH] GH-35941: [Dev][MATLAB] Add clang-format configuration to pre-commit (#40588) ### Rationale for this change If we use formatter, we don't need to check style manually. ### What changes are included in this PR? * Add clang-format configuration to pre-commit * This uses the same style as C++/Python/R uses We can format by `pre-commit run -a`. ### Are these changes tested? Yes. ### Are there any user-facing changes? No. * GitHub Issue: #35941 Authored-by: Sutou Kouhei Signed-off-by: Kevin Gurney --- .pre-commit-config.yaml | 7 + matlab/src/cpp/arrow/matlab/api/visibility.h | 2 +- .../src/cpp/arrow/matlab/array/proxy/array.cc | 266 +++++------ .../src/cpp/arrow/matlab/array/proxy/array.h | 27 +- .../arrow/matlab/array/proxy/boolean_array.cc | 61 +-- .../arrow/matlab/array/proxy/boolean_array.h | 19 +- .../arrow/matlab/array/proxy/chunked_array.cc | 279 ++++++------ .../arrow/matlab/array/proxy/chunked_array.h | 28 +- .../arrow/matlab/array/proxy/list_array.cc | 215 ++++----- .../cpp/arrow/matlab/array/proxy/list_array.h | 23 +- .../arrow/matlab/array/proxy/numeric_array.h | 105 +++-- .../arrow/matlab/array/proxy/string_array.cc | 105 +++-- .../arrow/matlab/array/proxy/string_array.h | 19 +- .../arrow/matlab/array/proxy/struct_array.cc | 334 +++++++------- .../arrow/matlab/array/proxy/struct_array.h | 23 +- .../arrow/matlab/array/proxy/time32_array.cc | 11 +- .../arrow/matlab/array/proxy/time32_array.h | 11 +- .../arrow/matlab/array/proxy/time64_array.cc | 11 +- .../arrow/matlab/array/proxy/time64_array.h | 11 +- .../cpp/arrow/matlab/array/proxy/time_array.h | 75 ++- .../matlab/array/proxy/timestamp_array.cc | 76 ++-- .../matlab/array/proxy/timestamp_array.h | 11 +- .../src/cpp/arrow/matlab/array/proxy/wrap.cc | 114 +++-- .../src/cpp/arrow/matlab/array/proxy/wrap.h | 3 +- .../cpp/arrow/matlab/array/validation_mode.h | 6 +- matlab/src/cpp/arrow/matlab/bit/pack.cc | 78 ++-- matlab/src/cpp/arrow/matlab/bit/pack.h | 17 +- matlab/src/cpp/arrow/matlab/bit/unpack.cc | 57 +-- matlab/src/cpp/arrow/matlab/bit/unpack.h | 9 +- .../cpp/arrow/matlab/buffer/matlab_buffer.h | 44 +- .../cpp/arrow/matlab/buffer/proxy/buffer.cc | 141 +++--- .../cpp/arrow/matlab/buffer/proxy/buffer.h | 25 +- matlab/src/cpp/arrow/matlab/error/error.h | 213 +++++---- matlab/src/cpp/arrow/matlab/index/validate.cc | 90 ++-- matlab/src/cpp/arrow/matlab/index/validate.h | 10 +- .../arrow/matlab/io/csv/proxy/table_reader.cc | 101 +++-- .../arrow/matlab/io/csv/proxy/table_reader.h | 25 +- .../arrow/matlab/io/csv/proxy/table_writer.cc | 92 ++-- .../arrow/matlab/io/csv/proxy/table_writer.h | 25 +- .../arrow/matlab/io/feather/proxy/reader.cc | 130 +++--- .../arrow/matlab/io/feather/proxy/reader.h | 23 +- .../arrow/matlab/io/feather/proxy/writer.cc | 117 ++--- .../arrow/matlab/io/feather/proxy/writer.h | 33 +- matlab/src/cpp/arrow/matlab/mex/gateway.cc | 11 +- matlab/src/cpp/arrow/matlab/proxy/factory.cc | 140 +++--- matlab/src/cpp/arrow/matlab/proxy/factory.h | 9 +- .../arrow/matlab/tabular/get_row_as_string.h | 96 ++-- .../matlab/tabular/proxy/record_batch.cc | 429 +++++++++--------- .../arrow/matlab/tabular/proxy/record_batch.h | 49 +- .../cpp/arrow/matlab/tabular/proxy/schema.cc | 230 +++++----- .../cpp/arrow/matlab/tabular/proxy/schema.h | 29 +- .../cpp/arrow/matlab/tabular/proxy/table.cc | 419 +++++++++-------- .../cpp/arrow/matlab/tabular/proxy/table.h | 37 +- .../arrow/matlab/type/proxy/date32_type.cc | 16 +- .../cpp/arrow/matlab/type/proxy/date32_type.h | 18 +- .../arrow/matlab/type/proxy/date64_type.cc | 16 +- .../cpp/arrow/matlab/type/proxy/date64_type.h | 18 +- .../cpp/arrow/matlab/type/proxy/date_type.cc | 27 +- .../cpp/arrow/matlab/type/proxy/date_type.h | 13 +- .../src/cpp/arrow/matlab/type/proxy/field.cc | 109 ++--- .../src/cpp/arrow/matlab/type/proxy/field.h | 21 +- .../matlab/type/proxy/fixed_width_type.cc | 22 +- .../matlab/type/proxy/fixed_width_type.h | 13 +- .../cpp/arrow/matlab/type/proxy/list_type.cc | 70 +-- .../cpp/arrow/matlab/type/proxy/list_type.h | 18 +- .../arrow/matlab/type/proxy/primitive_ctype.h | 37 +- .../arrow/matlab/type/proxy/string_type.cc | 12 +- .../cpp/arrow/matlab/type/proxy/string_type.h | 13 +- .../arrow/matlab/type/proxy/struct_type.cc | 38 +- .../cpp/arrow/matlab/type/proxy/struct_type.h | 16 +- .../arrow/matlab/type/proxy/time32_type.cc | 10 +- .../cpp/arrow/matlab/type/proxy/time32_type.h | 14 +- .../arrow/matlab/type/proxy/time64_type.cc | 10 +- .../cpp/arrow/matlab/type/proxy/time64_type.h | 14 +- .../cpp/arrow/matlab/type/proxy/time_type.cc | 79 ++-- .../cpp/arrow/matlab/type/proxy/time_type.h | 17 +- .../arrow/matlab/type/proxy/timestamp_type.cc | 94 ++-- .../arrow/matlab/type/proxy/timestamp_type.h | 20 +- .../src/cpp/arrow/matlab/type/proxy/traits.h | 174 +++---- .../src/cpp/arrow/matlab/type/proxy/type.cc | 144 +++--- matlab/src/cpp/arrow/matlab/type/proxy/type.h | 23 +- .../src/cpp/arrow/matlab/type/proxy/wrap.cc | 119 +++-- matlab/src/cpp/arrow/matlab/type/proxy/wrap.h | 3 +- matlab/src/cpp/arrow/matlab/type/time_unit.cc | 68 +-- matlab/src/cpp/arrow/matlab/type/time_unit.h | 10 +- 85 files changed, 3000 insertions(+), 2797 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16a1bfb7b8900..9e5440e884218 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,6 +59,13 @@ repos: name: C/GLib Format files: >- ^c_glib/ + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v14.0.6 + hooks: + - id: clang-format + name: MATLAB (C++) Format + files: >- + ^matlab/src/cpp/ - repo: https://github.com/cheshirekow/cmake-format-precommit rev: v0.6.13 hooks: diff --git a/matlab/src/cpp/arrow/matlab/api/visibility.h b/matlab/src/cpp/arrow/matlab/api/visibility.h index 51efac972ee92..1570de06c4e17 100644 --- a/matlab/src/cpp/arrow/matlab/api/visibility.h +++ b/matlab/src/cpp/arrow/matlab/api/visibility.h @@ -23,6 +23,6 @@ #else #define ARROW_MATLAB_EXPORT __declspec(dllimport) #endif -#else // Not Windows +#else // Not Windows #define ARROW_MATLAB_EXPORT __attribute__((visibility("default"))) #endif diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc index cdeb4e03fa666..b8f85b08632a3 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc @@ -32,150 +32,150 @@ namespace arrow::matlab::array::proxy { - Array::Array(std::shared_ptr array) : array{std::move(array)} { - - // Register Proxy methods. - REGISTER_METHOD(Array, toString); - REGISTER_METHOD(Array, getNumElements); - REGISTER_METHOD(Array, getValid); - REGISTER_METHOD(Array, getType); - REGISTER_METHOD(Array, isEqual); - REGISTER_METHOD(Array, slice); - } - - std::shared_ptr Array::unwrap() { - return array; - } - - void Array::toString(libmexclass::proxy::method::Context& context) { - ::matlab::data::ArrayFactory factory; - - auto opts = arrow::PrettyPrintOptions::Defaults(); - opts.window = 3; - opts.indent = 4; - opts.indent_size = 4; - - const auto type_id = array->type()->id(); - if (arrow::is_primitive(type_id) || arrow::is_string(type_id)) { - /* - * Display primitive and string types horizontally without - * opening and closing delimiters. Use " | " as the delimiter - * between elements. Below is an example Int32Array display: - * - * 1 | 2 | 3 | ... | 6 | 7 | 8 - */ - opts.skip_new_lines = true; - opts.array_delimiters.open = ""; - opts.array_delimiters.close = ""; - opts.array_delimiters.element = " | "; - } - - std::stringstream ss; - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(arrow::PrettyPrint(*array, opts, &ss), context, error::ARRAY_PRETTY_PRINT_FAILED); - - const auto str_utf8 = opts.skip_new_lines ? " " + ss.str() : ss.str(); - - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto str_utf16, arrow::util::UTF8StringToUTF16(str_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - auto str_mda = factory.createScalar(str_utf16); - context.outputs[0] = str_mda; - } - - void Array::getNumElements(libmexclass::proxy::method::Context& context) { - ::matlab::data::ArrayFactory factory; - auto length_mda = factory.createScalar(array->length()); - context.outputs[0] = length_mda; - } - - void Array::getValid(libmexclass::proxy::method::Context& context) { - auto array_length = static_cast(array->length()); - - // If the Arrow array has no null values, then return a MATLAB - // logical array that is all "true" for the validity bitmap. - if (array->null_count() == 0) { - ::matlab::data::ArrayFactory factory; - auto validity_buffer = factory.createBuffer(array_length); - auto validity_buffer_ptr = validity_buffer.get(); - std::fill(validity_buffer_ptr, validity_buffer_ptr + array_length, true); - auto valid_elements_mda = factory.createArrayFromBuffer({array_length, 1}, std::move(validity_buffer)); - context.outputs[0] = valid_elements_mda; - return; - } - - auto validity_bitmap = array->null_bitmap(); - auto valid_elements_mda = bit::unpack(validity_bitmap, array_length, array->offset()); - context.outputs[0] = valid_elements_mda; - } - - void Array::getType(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; +Array::Array(std::shared_ptr array) : array{std::move(array)} { + // Register Proxy methods. + REGISTER_METHOD(Array, toString); + REGISTER_METHOD(Array, getNumElements); + REGISTER_METHOD(Array, getValid); + REGISTER_METHOD(Array, getType); + REGISTER_METHOD(Array, isEqual); + REGISTER_METHOD(Array, slice); +} - mda::ArrayFactory factory; +std::shared_ptr Array::unwrap() { return array; } + +void Array::toString(libmexclass::proxy::method::Context& context) { + ::matlab::data::ArrayFactory factory; + + auto opts = arrow::PrettyPrintOptions::Defaults(); + opts.window = 3; + opts.indent = 4; + opts.indent_size = 4; + + const auto type_id = array->type()->id(); + if (arrow::is_primitive(type_id) || arrow::is_string(type_id)) { + /* + * Display primitive and string types horizontally without + * opening and closing delimiters. Use " | " as the delimiter + * between elements. Below is an example Int32Array display: + * + * 1 | 2 | 3 | ... | 6 | 7 | 8 + */ + opts.skip_new_lines = true; + opts.array_delimiters.open = ""; + opts.array_delimiters.close = ""; + opts.array_delimiters.element = " | "; + } + + std::stringstream ss; + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(arrow::PrettyPrint(*array, opts, &ss), context, + error::ARRAY_PRETTY_PRINT_FAILED); + + const auto str_utf8 = opts.skip_new_lines ? " " + ss.str() : ss.str(); + + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto str_utf16, + arrow::util::UTF8StringToUTF16(str_utf8), context, + error::UNICODE_CONVERSION_ERROR_ID); + auto str_mda = factory.createScalar(str_utf16); + context.outputs[0] = str_mda; +} - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto type_proxy, - type::proxy::wrap(array->type()), - context, - error::ARRAY_FAILED_TO_CREATE_TYPE_PROXY); +void Array::getNumElements(libmexclass::proxy::method::Context& context) { + ::matlab::data::ArrayFactory factory; + auto length_mda = factory.createScalar(array->length()); + context.outputs[0] = length_mda; +} - const auto type_id = static_cast(type_proxy->unwrap()->id()); - const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(type_proxy); +void Array::getValid(libmexclass::proxy::method::Context& context) { + auto array_length = static_cast(array->length()); + + // If the Arrow array has no null values, then return a MATLAB + // logical array that is all "true" for the validity bitmap. + if (array->null_count() == 0) { + ::matlab::data::ArrayFactory factory; + auto validity_buffer = factory.createBuffer(array_length); + auto validity_buffer_ptr = validity_buffer.get(); + std::fill(validity_buffer_ptr, validity_buffer_ptr + array_length, true); + auto valid_elements_mda = factory.createArrayFromBuffer( + {array_length, 1}, std::move(validity_buffer)); + context.outputs[0] = valid_elements_mda; + return; + } + + auto validity_bitmap = array->null_bitmap(); + auto valid_elements_mda = bit::unpack(validity_bitmap, array_length, array->offset()); + context.outputs[0] = valid_elements_mda; +} - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(proxy_id); - output[0]["TypeID"] = factory.createScalar(type_id); - context.outputs[0] = output; - } +void Array::getType(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; - void Array::isEqual(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - const mda::TypedArray array_proxy_ids = context.inputs[0]; - - bool is_equal = true; - const auto equals_options = arrow::EqualOptions::Defaults(); - for (const auto& array_proxy_id : array_proxy_ids) { - // Retrieve the Array proxy from the ProxyManager - auto proxy = libmexclass::proxy::ProxyManager::getProxy(array_proxy_id); - auto array_proxy = std::static_pointer_cast(proxy); - auto array_to_compare = array_proxy->unwrap(); - - if (!array->Equals(array_to_compare, equals_options)) { - is_equal = false; - break; - } - } - mda::ArrayFactory factory; - context.outputs[0] = factory.createScalar(is_equal); - } + mda::ArrayFactory factory; - void Array::slice(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto type_proxy, type::proxy::wrap(array->type()), + context, error::ARRAY_FAILED_TO_CREATE_TYPE_PROXY); - mda::StructArray opts = context.inputs[0]; - const mda::TypedArray offset_mda = opts[0]["Offset"]; - const mda::TypedArray length_mda = opts[0]["Length"]; + const auto type_id = static_cast(type_proxy->unwrap()->id()); + const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(type_proxy); - const auto matlab_offset = int64_t(offset_mda[0]); - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(arrow::matlab::index::validateSliceOffset(matlab_offset), - context, error::ARRAY_SLICE_NON_POSITIVE_OFFSET); + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(proxy_id); + output[0]["TypeID"] = factory.createScalar(type_id); + context.outputs[0] = output; +} - // Note: MATLAB uses 1-based indexing, so subtract 1. - const int64_t offset = matlab_offset - 1; - const int64_t length = int64_t(length_mda[0]); - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(arrow::matlab::index::validateSliceLength(length), - context, error::ARRAY_SLICE_NEGATIVE_LENGTH); +void Array::isEqual(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; - auto sliced_array = array->Slice(offset, length); - const auto type_id = static_cast(sliced_array->type_id()); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto sliced_array_proxy, - array::proxy::wrap(sliced_array), - context, error::ARRAY_SLICE_FAILED_TO_CREATE_ARRAY_PROXY); + const mda::TypedArray array_proxy_ids = context.inputs[0]; - const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(sliced_array_proxy); + bool is_equal = true; + const auto equals_options = arrow::EqualOptions::Defaults(); + for (const auto& array_proxy_id : array_proxy_ids) { + // Retrieve the Array proxy from the ProxyManager + auto proxy = libmexclass::proxy::ProxyManager::getProxy(array_proxy_id); + auto array_proxy = std::static_pointer_cast(proxy); + auto array_to_compare = array_proxy->unwrap(); - mda::ArrayFactory factory; - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(proxy_id); - output[0]["TypeID"] = factory.createScalar(type_id); - context.outputs[0] = output; + if (!array->Equals(array_to_compare, equals_options)) { + is_equal = false; + break; } + } + mda::ArrayFactory factory; + context.outputs[0] = factory.createScalar(is_equal); +} + +void Array::slice(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + mda::StructArray opts = context.inputs[0]; + const mda::TypedArray offset_mda = opts[0]["Offset"]; + const mda::TypedArray length_mda = opts[0]["Length"]; + + const auto matlab_offset = int64_t(offset_mda[0]); + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + arrow::matlab::index::validateSliceOffset(matlab_offset), context, + error::ARRAY_SLICE_NON_POSITIVE_OFFSET); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + const int64_t offset = matlab_offset - 1; + const int64_t length = int64_t(length_mda[0]); + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(arrow::matlab::index::validateSliceLength(length), + context, error::ARRAY_SLICE_NEGATIVE_LENGTH); + + auto sliced_array = array->Slice(offset, length); + const auto type_id = static_cast(sliced_array->type_id()); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto sliced_array_proxy, + array::proxy::wrap(sliced_array), context, + error::ARRAY_SLICE_FAILED_TO_CREATE_ARRAY_PROXY); + + const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(sliced_array_proxy); + + mda::ArrayFactory factory; + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(proxy_id); + output[0]["TypeID"] = factory.createScalar(type_id); + context.outputs[0] = output; } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/array/proxy/array.h index 1e3164ed01a72..61ba06a503bc4 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.h @@ -25,28 +25,27 @@ namespace arrow::matlab::array::proxy { class Array : public libmexclass::proxy::Proxy { - public: - Array(std::shared_ptr array); - - virtual ~Array() {} + public: + Array(std::shared_ptr array); - std::shared_ptr unwrap(); + virtual ~Array() {} - protected: + std::shared_ptr unwrap(); - void toString(libmexclass::proxy::method::Context& context); + protected: + void toString(libmexclass::proxy::method::Context& context); - void getNumElements(libmexclass::proxy::method::Context& context); + void getNumElements(libmexclass::proxy::method::Context& context); - void getValid(libmexclass::proxy::method::Context& context); + void getValid(libmexclass::proxy::method::Context& context); - void getType(libmexclass::proxy::method::Context& context); + void getType(libmexclass::proxy::method::Context& context); - void isEqual(libmexclass::proxy::method::Context& context); + void isEqual(libmexclass::proxy::method::Context& context); - void slice(libmexclass::proxy::method::Context& context); + void slice(libmexclass::proxy::method::Context& context); - std::shared_ptr array; + std::shared_ptr array; }; -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc index da3560ce522f3..053c8101dd53b 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc @@ -18,42 +18,51 @@ #include "arrow/matlab/array/proxy/boolean_array.h" #include "arrow/matlab/type/proxy/primitive_ctype.h" -#include "arrow/matlab/error/error.h" #include "arrow/matlab/bit/pack.h" #include "arrow/matlab/bit/unpack.h" +#include "arrow/matlab/error/error.h" namespace arrow::matlab::array::proxy { - BooleanArray::BooleanArray(std::shared_ptr array) - : arrow::matlab::array::proxy::Array{std::move(array)} { - REGISTER_METHOD(BooleanArray, toMATLAB); - } +BooleanArray::BooleanArray(std::shared_ptr array) + : arrow::matlab::array::proxy::Array{std::move(array)} { + REGISTER_METHOD(BooleanArray, toMATLAB); +} - libmexclass::proxy::MakeResult BooleanArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - ::matlab::data::StructArray opts = constructor_arguments[0]; +libmexclass::proxy::MakeResult BooleanArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + ::matlab::data::StructArray opts = constructor_arguments[0]; - // Get the mxArray from constructor arguments - const ::matlab::data::TypedArray logical_mda = opts[0]["MatlabArray"]; - const ::matlab::data::TypedArray validity_bitmap_mda = opts[0]["Valid"]; + // Get the mxArray from constructor arguments + const ::matlab::data::TypedArray logical_mda = opts[0]["MatlabArray"]; + const ::matlab::data::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - // Pack the logical data values. - MATLAB_ASSIGN_OR_ERROR(auto data_buffer, bit::pack(logical_mda), error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + // Pack the logical data values. + MATLAB_ASSIGN_OR_ERROR(auto data_buffer, bit::pack(logical_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(const auto validity_bitmap_buffer, bit::packValid(validity_bitmap_mda), error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(const auto validity_bitmap_buffer, + bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - const auto data_type = arrow::boolean(); - const auto array_length = logical_mda.getNumberOfElements(); + const auto data_type = arrow::boolean(); + const auto array_length = logical_mda.getNumberOfElements(); - auto array_data = arrow::ArrayData::Make(data_type, array_length, {validity_bitmap_buffer, data_buffer}); - auto arrow_array = std::static_pointer_cast(arrow::MakeArray(array_data)); - return std::make_shared(std::move(arrow_array)); - } + auto array_data = arrow::ArrayData::Make(data_type, array_length, + {validity_bitmap_buffer, data_buffer}); + auto arrow_array = + std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared( + std::move(arrow_array)); +} - void BooleanArray::toMATLAB(libmexclass::proxy::method::Context& context) { - auto array_length = array->length(); - auto packed_logical_data_buffer = std::static_pointer_cast(array)->values(); - auto logical_array_mda = bit::unpack(packed_logical_data_buffer, array_length, array->offset()); - context.outputs[0] = logical_array_mda; - } +void BooleanArray::toMATLAB(libmexclass::proxy::method::Context& context) { + auto array_length = array->length(); + auto packed_logical_data_buffer = + std::static_pointer_cast(array)->values(); + auto logical_array_mda = + bit::unpack(packed_logical_data_buffer, array_length, array->offset()); + context.outputs[0] = logical_array_mda; } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h index edc00b178e42a..2638a2c190ae6 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h @@ -19,19 +19,20 @@ #include "arrow/matlab/array/proxy/array.h" -#include "libmexclass/proxy/Proxy.h" #include "arrow/type_fwd.h" +#include "libmexclass/proxy/Proxy.h" namespace arrow::matlab::array::proxy { - class BooleanArray : public arrow::matlab::array::proxy::Array { - public: - BooleanArray(std::shared_ptr array); +class BooleanArray : public arrow::matlab::array::proxy::Array { + public: + BooleanArray(std::shared_ptr array); - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void toMATLAB(libmexclass::proxy::method::Context& context); - }; + protected: + void toMATLAB(libmexclass::proxy::method::Context& context); +}; -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.cc index dea824fd04c5b..a23d4744dd3a3 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.cc @@ -17,171 +17,168 @@ #include "arrow/util/utf8.h" -#include "arrow/matlab/array/proxy/chunked_array.h" #include "arrow/matlab/array/proxy/array.h" +#include "arrow/matlab/array/proxy/chunked_array.h" +#include "arrow/matlab/array/proxy/wrap.h" #include "arrow/matlab/error/error.h" #include "arrow/matlab/type/proxy/wrap.h" -#include "arrow/matlab/array/proxy/wrap.h" #include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::array::proxy { - namespace { - libmexclass::error::Error makeEmptyChunkedArrayError() { - const std::string error_msg = "Numeric indexing using the chunk method is not supported for chunked arrays with zero chunks."; - return libmexclass::error::Error{error::CHUNKED_ARRAY_NUMERIC_INDEX_WITH_EMPTY_CHUNKED_ARRAY, error_msg}; - } - - libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, const int32_t num_chunks) { - std::stringstream error_message_stream; - error_message_stream << "Invalid chunk index: "; - error_message_stream << matlab_index; - error_message_stream << ". Chunk index must be between 1 and the number of chunks ("; - error_message_stream << num_chunks; - error_message_stream << ")."; - return libmexclass::error::Error{error::CHUNKED_ARRAY_INVALID_NUMERIC_CHUNK_INDEX, error_message_stream.str()}; - } - } - - ChunkedArray::ChunkedArray(std::shared_ptr chunked_array) : chunked_array{std::move(chunked_array)} { - - // Register Proxy methods. - REGISTER_METHOD(ChunkedArray, getNumElements); - REGISTER_METHOD(ChunkedArray, getNumChunks); - REGISTER_METHOD(ChunkedArray, getChunk); - REGISTER_METHOD(ChunkedArray, getType); - REGISTER_METHOD(ChunkedArray, isEqual); - } - - - libmexclass::proxy::MakeResult ChunkedArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; +namespace { +libmexclass::error::Error makeEmptyChunkedArrayError() { + const std::string error_msg = + "Numeric indexing using the chunk method is not supported for chunked arrays with " + "zero chunks."; + return libmexclass::error::Error{ + error::CHUNKED_ARRAY_NUMERIC_INDEX_WITH_EMPTY_CHUNKED_ARRAY, error_msg}; +} - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray array_proxy_ids = opts[0]["ArrayProxyIDs"]; - const mda::TypedArray type_proxy_id = opts[0]["TypeProxyID"]; +libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, + const int32_t num_chunks) { + std::stringstream error_message_stream; + error_message_stream << "Invalid chunk index: "; + error_message_stream << matlab_index; + error_message_stream << ". Chunk index must be between 1 and the number of chunks ("; + error_message_stream << num_chunks; + error_message_stream << ")."; + return libmexclass::error::Error{error::CHUNKED_ARRAY_INVALID_NUMERIC_CHUNK_INDEX, + error_message_stream.str()}; +} +} // namespace + +ChunkedArray::ChunkedArray(std::shared_ptr chunked_array) + : chunked_array{std::move(chunked_array)} { + // Register Proxy methods. + REGISTER_METHOD(ChunkedArray, getNumElements); + REGISTER_METHOD(ChunkedArray, getNumChunks); + REGISTER_METHOD(ChunkedArray, getChunk); + REGISTER_METHOD(ChunkedArray, getType); + REGISTER_METHOD(ChunkedArray, isEqual); +} - std::vector> arrays; - // Retrieve all of the Array Proxy instances from the libmexclass ProxyManager. - for (const auto& array_proxy_id : array_proxy_ids) { - auto proxy = libmexclass::proxy::ProxyManager::getProxy(array_proxy_id); - auto array_proxy = std::static_pointer_cast(proxy); - auto array = array_proxy->unwrap(); - arrays.push_back(array); - } +libmexclass::proxy::MakeResult ChunkedArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; - auto proxy = libmexclass::proxy::ProxyManager::getProxy(type_proxy_id[0]); - auto type_proxy = std::static_pointer_cast(proxy); - auto type = type_proxy->unwrap(); + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray array_proxy_ids = opts[0]["ArrayProxyIDs"]; + const mda::TypedArray type_proxy_id = opts[0]["TypeProxyID"]; - MATLAB_ASSIGN_OR_ERROR(auto chunked_array, - arrow::ChunkedArray::Make(arrays, type), - error::CHUNKED_ARRAY_MAKE_FAILED); + std::vector> arrays; + // Retrieve all of the Array Proxy instances from the libmexclass ProxyManager. + for (const auto& array_proxy_id : array_proxy_ids) { + auto proxy = libmexclass::proxy::ProxyManager::getProxy(array_proxy_id); + auto array_proxy = std::static_pointer_cast(proxy); + auto array = array_proxy->unwrap(); + arrays.push_back(array); + } - return std::make_unique(std::move(chunked_array)); - } + auto proxy = libmexclass::proxy::ProxyManager::getProxy(type_proxy_id[0]); + auto type_proxy = std::static_pointer_cast(proxy); + auto type = type_proxy->unwrap(); - std::shared_ptr ChunkedArray::unwrap() { - return chunked_array; - } + MATLAB_ASSIGN_OR_ERROR(auto chunked_array, arrow::ChunkedArray::Make(arrays, type), + error::CHUNKED_ARRAY_MAKE_FAILED); - void ChunkedArray::getNumElements(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - auto num_elements_mda = factory.createScalar(chunked_array->length()); - context.outputs[0] = num_elements_mda; - } + return std::make_unique(std::move(chunked_array)); +} - void ChunkedArray::getNumChunks(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - auto length_mda = factory.createScalar(chunked_array->num_chunks()); - context.outputs[0] = length_mda; - } +std::shared_ptr ChunkedArray::unwrap() { return chunked_array; } - void ChunkedArray::getChunk(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - // arrow::Schema::field does not do any bounds checking. - const int32_t index = matlab_index - 1; - const auto num_chunks = chunked_array->num_chunks(); - - if (num_chunks == 0) { - context.error = makeEmptyChunkedArrayError(); - return; - } - - if (matlab_index < 1 || matlab_index > num_chunks) { - context.error = makeInvalidNumericIndexError(matlab_index, num_chunks); - return; - } - - const auto array = chunked_array->chunk(index); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, - arrow::matlab::array::proxy::wrap(array), - context, - error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - - - const auto array_proxy_id = libmexclass::proxy::ProxyManager::manageProxy(array_proxy); - const auto type_id = static_cast(array->type_id()); - - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(array_proxy_id); - output[0]["TypeID"] = factory.createScalar(type_id); - context.outputs[0] = output; - } +void ChunkedArray::getNumElements(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + auto num_elements_mda = factory.createScalar(chunked_array->length()); + context.outputs[0] = num_elements_mda; +} +void ChunkedArray::getNumChunks(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + auto length_mda = factory.createScalar(chunked_array->num_chunks()); + context.outputs[0] = length_mda; +} - void ChunkedArray::getType(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; +void ChunkedArray::getChunk(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + // arrow::Schema::field does not do any bounds checking. + const int32_t index = matlab_index - 1; + const auto num_chunks = chunked_array->num_chunks(); + + if (num_chunks == 0) { + context.error = makeEmptyChunkedArrayError(); + return; + } + + if (matlab_index < 1 || matlab_index > num_chunks) { + context.error = makeInvalidNumericIndexError(matlab_index, num_chunks); + return; + } + + const auto array = chunked_array->chunk(index); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, + arrow::matlab::array::proxy::wrap(array), context, + error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + + const auto array_proxy_id = libmexclass::proxy::ProxyManager::manageProxy(array_proxy); + const auto type_id = static_cast(array->type_id()); + + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(array_proxy_id); + output[0]["TypeID"] = factory.createScalar(type_id); + context.outputs[0] = output; +} - mda::ArrayFactory factory; +void ChunkedArray::getType(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto type_proxy, - type::proxy::wrap(chunked_array->type()), - context, - error::ARRAY_FAILED_TO_CREATE_TYPE_PROXY); + mda::ArrayFactory factory; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto type_proxy, + type::proxy::wrap(chunked_array->type()), context, + error::ARRAY_FAILED_TO_CREATE_TYPE_PROXY); - const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(type_proxy); - const auto type_id = static_cast(type_proxy->unwrap()->id()); + const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(type_proxy); + const auto type_id = static_cast(type_proxy->unwrap()->id()); - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(proxy_id); - output[0]["TypeID"] = factory.createScalar(type_id); - context.outputs[0] = output; - } + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(proxy_id); + output[0]["TypeID"] = factory.createScalar(type_id); + context.outputs[0] = output; +} - void ChunkedArray::isEqual(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - const mda::TypedArray chunked_array_proxy_ids = context.inputs[0]; - - bool is_equal = true; - for (const auto& chunked_array_proxy_id : chunked_array_proxy_ids) { - // Retrieve the ChunkedArray proxy from the ProxyManager - auto proxy = libmexclass::proxy::ProxyManager::getProxy(chunked_array_proxy_id); - auto chunked_array_proxy = std::static_pointer_cast(proxy); - auto chunked_array_to_compare = chunked_array_proxy->unwrap(); - - // Use the ChunkedArray::Equals(const ChunkedArray& other) overload instead - // of ChunkedArray::Equals(const std::shared_ptr other&) to - // ensure we don't assume chunked arrays with the same memory address are - // equal. This ensures we treat NaNs as not equal by default. - if (!chunked_array->Equals(*chunked_array_to_compare)) { - is_equal = false; - break; - } - } - mda::ArrayFactory factory; - context.outputs[0] = factory.createScalar(is_equal); +void ChunkedArray::isEqual(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + const mda::TypedArray chunked_array_proxy_ids = context.inputs[0]; + + bool is_equal = true; + for (const auto& chunked_array_proxy_id : chunked_array_proxy_ids) { + // Retrieve the ChunkedArray proxy from the ProxyManager + auto proxy = libmexclass::proxy::ProxyManager::getProxy(chunked_array_proxy_id); + auto chunked_array_proxy = std::static_pointer_cast(proxy); + auto chunked_array_to_compare = chunked_array_proxy->unwrap(); + + // Use the ChunkedArray::Equals(const ChunkedArray& other) overload instead + // of ChunkedArray::Equals(const std::shared_ptr other&) to + // ensure we don't assume chunked arrays with the same memory address are + // equal. This ensures we treat NaNs as not equal by default. + if (!chunked_array->Equals(*chunked_array_to_compare)) { + is_equal = false; + break; } + } + mda::ArrayFactory factory; + context.outputs[0] = factory.createScalar(is_equal); } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.h index 74cc5d6859de4..1ba0feb572375 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/chunked_array.h @@ -24,28 +24,28 @@ namespace arrow::matlab::array::proxy { class ChunkedArray : public libmexclass::proxy::Proxy { - public: - ChunkedArray(std::shared_ptr chunked_array); - - ~ChunkedArray() {} + public: + ChunkedArray(std::shared_ptr chunked_array); - std::shared_ptr unwrap(); + ~ChunkedArray() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + std::shared_ptr unwrap(); - protected: + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - void getNumElements(libmexclass::proxy::method::Context& context); + protected: + void getNumElements(libmexclass::proxy::method::Context& context); - void getNumChunks(libmexclass::proxy::method::Context& context); + void getNumChunks(libmexclass::proxy::method::Context& context); - void getChunk(libmexclass::proxy::method::Context& context); + void getChunk(libmexclass::proxy::method::Context& context); - void getType(libmexclass::proxy::method::Context& context); + void getType(libmexclass::proxy::method::Context& context); - void isEqual(libmexclass::proxy::method::Context& context); + void isEqual(libmexclass::proxy::method::Context& context); - std::shared_ptr chunked_array; + std::shared_ptr chunked_array; }; -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/list_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/list_array.cc index 941e658c25127..9b8a587e56f27 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/list_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/list_array.cc @@ -15,125 +15,130 @@ // specific language governing permissions and limitations // under the License. -#include "arrow/matlab/array/validation_mode.h" #include "arrow/matlab/array/proxy/list_array.h" #include "arrow/matlab/array/proxy/numeric_array.h" #include "arrow/matlab/array/proxy/wrap.h" +#include "arrow/matlab/array/validation_mode.h" #include "arrow/matlab/error/error.h" #include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::array::proxy { - ListArray::ListArray(std::shared_ptr list_array) : proxy::Array{std::move(list_array)} { - REGISTER_METHOD(ListArray, getValues); - REGISTER_METHOD(ListArray, getOffsets); - REGISTER_METHOD(ListArray, validate); - } - - libmexclass::proxy::MakeResult ListArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using libmexclass::proxy::ProxyManager; - using Int32ArrayProxy = arrow::matlab::array::proxy::NumericArray; - using ListArrayProxy = arrow::matlab::array::proxy::ListArray; - using ArrayProxy = arrow::matlab::array::proxy::Array; - - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray offsets_proxy_id_mda = opts[0]["OffsetsProxyID"]; - const mda::TypedArray values_proxy_id_mda = opts[0]["ValuesProxyID"]; - const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - - const auto offsets_proxy_id = offsets_proxy_id_mda[0]; - const auto values_proxy_id = values_proxy_id_mda[0]; - - const auto offsets_proxy = std::static_pointer_cast(ProxyManager::getProxy(offsets_proxy_id)); - const auto values_proxy = std::static_pointer_cast(ProxyManager::getProxy(values_proxy_id)); +ListArray::ListArray(std::shared_ptr list_array) + : proxy::Array{std::move(list_array)} { + REGISTER_METHOD(ListArray, getValues); + REGISTER_METHOD(ListArray, getOffsets); + REGISTER_METHOD(ListArray, validate); +} - const auto offsets = offsets_proxy->unwrap(); - const auto values = values_proxy->unwrap(); +libmexclass::proxy::MakeResult ListArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using libmexclass::proxy::ProxyManager; + using Int32ArrayProxy = arrow::matlab::array::proxy::NumericArray; + using ListArrayProxy = arrow::matlab::array::proxy::ListArray; + using ArrayProxy = arrow::matlab::array::proxy::Array; + + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray offsets_proxy_id_mda = opts[0]["OffsetsProxyID"]; + const mda::TypedArray values_proxy_id_mda = opts[0]["ValuesProxyID"]; + const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; + + const auto offsets_proxy_id = offsets_proxy_id_mda[0]; + const auto values_proxy_id = values_proxy_id_mda[0]; + + const auto offsets_proxy = + std::static_pointer_cast(ProxyManager::getProxy(offsets_proxy_id)); + const auto values_proxy = + std::static_pointer_cast(ProxyManager::getProxy(values_proxy_id)); + + const auto offsets = offsets_proxy->unwrap(); + const auto values = values_proxy->unwrap(); + + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(auto validity_bitmap_buffer, bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + + // Create a ListArray from values and offsets. + MATLAB_ASSIGN_OR_ERROR( + auto array, + arrow::ListArray::FromArrays(*offsets, *values, arrow::default_memory_pool(), + validity_bitmap_buffer), + error::LIST_ARRAY_FROM_ARRAYS_FAILED); + + // Return a ListArray Proxy. + auto list_array = std::static_pointer_cast(array); + return std::make_shared(std::move(list_array)); +} - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(auto validity_bitmap_buffer, - bit::packValid(validity_bitmap_mda), - error::BITPACK_VALIDITY_BITMAP_ERROR_ID); +void ListArray::getValues(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using libmexclass::proxy::ProxyManager; + + auto list_array = std::static_pointer_cast(array); + auto value_array = list_array->values(); + + // Wrap the array within a proxy object if possible. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto value_array_proxy, proxy::wrap(value_array), + context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + const auto value_array_proxy_id = ProxyManager::manageProxy(value_array_proxy); + const auto type_id = value_array->type_id(); + + // Return a struct with two fields: ProxyID and TypeID. The MATLAB + // layer will use these values to construct the appropriate MATLAB + // arrow.array.Array subclass. + mda::ArrayFactory factory; + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(value_array_proxy_id); + output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); + context.outputs[0] = output; +} - // Create a ListArray from values and offsets. - MATLAB_ASSIGN_OR_ERROR(auto array, - arrow::ListArray::FromArrays(*offsets, *values, arrow::default_memory_pool(), validity_bitmap_buffer), - error::LIST_ARRAY_FROM_ARRAYS_FAILED); +void ListArray::getOffsets(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using libmexclass::proxy::ProxyManager; + using Int32ArrayProxy = arrow::matlab::array::proxy::NumericArray; + auto list_array = std::static_pointer_cast(array); + auto offsets_array = list_array->offsets(); + auto offsets_int32_array = std::static_pointer_cast(offsets_array); + auto offsets_int32_array_proxy = std::make_shared(offsets_int32_array); + const auto offsets_int32_array_proxy_id = + ProxyManager::manageProxy(offsets_int32_array_proxy); + mda::ArrayFactory factory; + context.outputs[0] = factory.createScalar(offsets_int32_array_proxy_id); +} - // Return a ListArray Proxy. - auto list_array = std::static_pointer_cast(array); - return std::make_shared(std::move(list_array)); +void ListArray::validate(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::StructArray args = context.inputs[0]; + const mda::TypedArray validation_mode_mda = args[0]["ValidationMode"]; + const auto validation_mode_integer = uint8_t(validation_mode_mda[0]); + // Convert integer representation to ValidationMode enum. + const auto validation_mode = static_cast(validation_mode_integer); + switch (validation_mode) { + case ValidationMode::None: { + // Do nothing. + break; } - - void ListArray::getValues(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using libmexclass::proxy::ProxyManager; - - auto list_array = std::static_pointer_cast(array); - auto value_array = list_array->values(); - - // Wrap the array within a proxy object if possible. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto value_array_proxy, - proxy::wrap(value_array), - context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - const auto value_array_proxy_id = ProxyManager::manageProxy(value_array_proxy); - const auto type_id = value_array->type_id(); - - // Return a struct with two fields: ProxyID and TypeID. The MATLAB - // layer will use these values to construct the appropriate MATLAB - // arrow.array.Array subclass. - mda::ArrayFactory factory; - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(value_array_proxy_id); - output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); - context.outputs[0] = output; + case ValidationMode::Minimal: { + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(array->Validate(), context, + error::ARRAY_VALIDATE_MINIMAL_FAILED); + break; } - - void ListArray::getOffsets(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using libmexclass::proxy::ProxyManager; - using Int32ArrayProxy = arrow::matlab::array::proxy::NumericArray; - auto list_array = std::static_pointer_cast(array); - auto offsets_array = list_array->offsets(); - auto offsets_int32_array = std::static_pointer_cast(offsets_array); - auto offsets_int32_array_proxy = std::make_shared(offsets_int32_array); - const auto offsets_int32_array_proxy_id = ProxyManager::manageProxy(offsets_int32_array_proxy); - mda::ArrayFactory factory; - context.outputs[0] = factory.createScalar(offsets_int32_array_proxy_id); + case ValidationMode::Full: { + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(array->ValidateFull(), context, + error::ARRAY_VALIDATE_FULL_FAILED); + break; } - - void ListArray::validate(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::StructArray args = context.inputs[0]; - const mda::TypedArray validation_mode_mda = args[0]["ValidationMode"]; - const auto validation_mode_integer = uint8_t(validation_mode_mda[0]); - // Convert integer representation to ValidationMode enum. - const auto validation_mode = static_cast(validation_mode_integer); - switch (validation_mode) { - case ValidationMode::None: { - // Do nothing. - break; - } - case ValidationMode::Minimal: { - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(array->Validate(), - context, - error::ARRAY_VALIDATE_MINIMAL_FAILED); - break; - } - case ValidationMode::Full: { - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(array->ValidateFull(), - context, - error::ARRAY_VALIDATE_FULL_FAILED); - break; - } - default: { - // Throw an error if an unsupported enumeration value is provided. - const auto msg = "Unsupported ValidationMode enumeration value: " + std::to_string(validation_mode_integer); - context.error = libmexclass::error::Error{error::ARRAY_VALIDATE_UNSUPPORTED_ENUM, msg}; - return; - } - } + default: { + // Throw an error if an unsupported enumeration value is provided. + const auto msg = "Unsupported ValidationMode enumeration value: " + + std::to_string(validation_mode_integer); + context.error = + libmexclass::error::Error{error::ARRAY_VALIDATE_UNSUPPORTED_ENUM, msg}; + return; } - + } } + +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/list_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/list_array.h index 1f34b11406594..09f5fdb0cface 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/list_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/list_array.h @@ -22,18 +22,17 @@ namespace arrow::matlab::array::proxy { class ListArray : public arrow::matlab::array::proxy::Array { + public: + ListArray(std::shared_ptr list_array); + ~ListArray() {} - public: - ListArray(std::shared_ptr list_array); - ~ListArray() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + protected: + void getValues(libmexclass::proxy::method::Context& context); + void getOffsets(libmexclass::proxy::method::Context& context); + void validate(libmexclass::proxy::method::Context& context); +}; - protected: - void getValues(libmexclass::proxy::method::Context& context); - void getOffsets(libmexclass::proxy::method::Context& context); - void validate(libmexclass::proxy::method::Context& context); - - }; - -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 4b4ddb6588678..9ad7731bacf54 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -26,63 +26,68 @@ #include "arrow/matlab/array/proxy/array.h" #include "arrow/matlab/type/proxy/traits.h" -#include "arrow/matlab/error/error.h" #include "arrow/matlab/bit/pack.h" #include "arrow/matlab/bit/unpack.h" #include "arrow/matlab/buffer/matlab_buffer.h" +#include "arrow/matlab/error/error.h" #include "libmexclass/proxy/Proxy.h" namespace arrow::matlab::array::proxy { -template +template class NumericArray : public arrow::matlab::array::proxy::Array { - public: - - NumericArray(const std::shared_ptr> numeric_array) - : arrow::matlab::array::proxy::Array{std::move(numeric_array)} { - REGISTER_METHOD(NumericArray, toMATLAB); - } - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; - using CType = typename arrow::TypeTraits::CType; - using NumericArray = arrow::NumericArray; - using NumericArrayProxy = typename proxy::NumericArray; - - ::matlab::data::StructArray opts = constructor_arguments[0]; - - // Get the mxArray from constructor arguments - const ::matlab::data::TypedArray numeric_mda = opts[0]["MatlabArray"]; - const ::matlab::data::TypedArray valid_mda = opts[0]["Valid"]; - - auto data_buffer = std::make_shared(numeric_mda); - - const auto data_type = arrow::TypeTraits::type_singleton(); - const auto length = static_cast(numeric_mda.getNumberOfElements()); // cast size_t to int64_t - - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, bit::packValid(valid_mda), error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - auto array_data = arrow::ArrayData::Make(data_type, length, {packed_validity_bitmap, data_buffer}); - auto numeric_array = std::static_pointer_cast(arrow::MakeArray(array_data)); - return std::make_shared(std::move(numeric_array)); - } - - protected: - void toMATLAB(libmexclass::proxy::method::Context& context) { - using CType = typename arrow::TypeTraits::CType; - using NumericArray = arrow::NumericArray; - - const auto num_elements = static_cast(array->length()); - const auto numeric_array = std::static_pointer_cast(array); - const CType* const data_begin = numeric_array->raw_values(); - const CType* const data_end = data_begin + num_elements; - - ::matlab::data::ArrayFactory factory; - - // Constructs a TypedArray from the raw values. Makes a copy. - ::matlab::data::TypedArray result = factory.createArray({num_elements, 1}, data_begin, data_end); - context.outputs[0] = result; - } + public: + NumericArray(const std::shared_ptr> numeric_array) + : arrow::matlab::array::proxy::Array{std::move(numeric_array)} { + REGISTER_METHOD(NumericArray, toMATLAB); + } + + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + using CType = typename arrow::TypeTraits::CType; + using NumericArray = arrow::NumericArray; + using NumericArrayProxy = typename proxy::NumericArray; + + ::matlab::data::StructArray opts = constructor_arguments[0]; + + // Get the mxArray from constructor arguments + const ::matlab::data::TypedArray numeric_mda = opts[0]["MatlabArray"]; + const ::matlab::data::TypedArray valid_mda = opts[0]["Valid"]; + + auto data_buffer = std::make_shared(numeric_mda); + + const auto data_type = arrow::TypeTraits::type_singleton(); + const auto length = static_cast( + numeric_mda.getNumberOfElements()); // cast size_t to int64_t + + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, bit::packValid(valid_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + auto array_data = + arrow::ArrayData::Make(data_type, length, {packed_validity_bitmap, data_buffer}); + auto numeric_array = + std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(numeric_array)); + } + + protected: + void toMATLAB(libmexclass::proxy::method::Context& context) { + using CType = typename arrow::TypeTraits::CType; + using NumericArray = arrow::NumericArray; + + const auto num_elements = static_cast(array->length()); + const auto numeric_array = std::static_pointer_cast(array); + const CType* const data_begin = numeric_array->raw_values(); + const CType* const data_end = data_begin + num_elements; + + ::matlab::data::ArrayFactory factory; + + // Constructs a TypedArray from the raw values. Makes a copy. + ::matlab::data::TypedArray result = + factory.createArray({num_elements, 1}, data_begin, data_end); + context.outputs[0] = result; + } }; -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc index 7160e88a3c8a0..e03d6e767c1ea 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc @@ -20,67 +20,74 @@ #include "arrow/array/builder_binary.h" -#include "arrow/matlab/error/error.h" #include "arrow/matlab/bit/pack.h" #include "arrow/matlab/bit/unpack.h" +#include "arrow/matlab/error/error.h" #include "arrow/util/utf8.h" namespace arrow::matlab::array::proxy { - StringArray::StringArray(const std::shared_ptr string_array) - : arrow::matlab::array::proxy::Array(std::move(string_array)) { - REGISTER_METHOD(StringArray, toMATLAB); - } +StringArray::StringArray(const std::shared_ptr string_array) + : arrow::matlab::array::proxy::Array(std::move(string_array)) { + REGISTER_METHOD(StringArray, toMATLAB); +} - libmexclass::proxy::MakeResult StringArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; +libmexclass::proxy::MakeResult StringArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; - mda::StructArray opts = constructor_arguments[0]; - const mda::StringArray array_mda = opts[0]["MatlabArray"]; - const mda::TypedArray unpacked_validity_bitmap_mda = opts[0]["Valid"]; + mda::StructArray opts = constructor_arguments[0]; + const mda::StringArray array_mda = opts[0]["MatlabArray"]; + const mda::TypedArray unpacked_validity_bitmap_mda = opts[0]["Valid"]; - // Convert UTF-16 encoded MATLAB string values to UTF-8 encoded Arrow string values. - const auto array_length = array_mda.getNumberOfElements(); - std::vector strings; - strings.reserve(array_length); - for (const auto& str : array_mda) { - if (!str) { - // Substitute MATLAB string(missing) values with the empty string value ("") - strings.emplace_back(""); - } else { - MATLAB_ASSIGN_OR_ERROR(auto str_utf8, arrow::util::UTF16StringToUTF8(*str), error::UNICODE_CONVERSION_ERROR_ID); - strings.push_back(std::move(str_utf8)); - } - } + // Convert UTF-16 encoded MATLAB string values to UTF-8 encoded Arrow string values. + const auto array_length = array_mda.getNumberOfElements(); + std::vector strings; + strings.reserve(array_length); + for (const auto& str : array_mda) { + if (!str) { + // Substitute MATLAB string(missing) values with the empty string value ("") + strings.emplace_back(""); + } else { + MATLAB_ASSIGN_OR_ERROR(auto str_utf8, arrow::util::UTF16StringToUTF8(*str), + error::UNICODE_CONVERSION_ERROR_ID); + strings.push_back(std::move(str_utf8)); + } + } - auto unpacked_validity_bitmap_ptr = bit::extract_ptr(unpacked_validity_bitmap_mda); + auto unpacked_validity_bitmap_ptr = bit::extract_ptr(unpacked_validity_bitmap_mda); - // Build up an Arrow StringArray from a vector of UTF-8 encoded strings. - arrow::StringBuilder builder; - MATLAB_ERROR_IF_NOT_OK(builder.AppendValues(strings, unpacked_validity_bitmap_ptr), error::STRING_BUILDER_APPEND_FAILED); - MATLAB_ASSIGN_OR_ERROR(auto array, builder.Finish(), error::STRING_BUILDER_FINISH_FAILED); - auto typed_array = std::static_pointer_cast(array); - return std::make_shared(std::move(typed_array)); - } + // Build up an Arrow StringArray from a vector of UTF-8 encoded strings. + arrow::StringBuilder builder; + MATLAB_ERROR_IF_NOT_OK(builder.AppendValues(strings, unpacked_validity_bitmap_ptr), + error::STRING_BUILDER_APPEND_FAILED); + MATLAB_ASSIGN_OR_ERROR(auto array, builder.Finish(), + error::STRING_BUILDER_FINISH_FAILED); + auto typed_array = std::static_pointer_cast(array); + return std::make_shared( + std::move(typed_array)); +} - void StringArray::toMATLAB(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; +void StringArray::toMATLAB(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; - // Convert UTF-8 encoded Arrow string values to UTF-16 encoded MATLAB string values. - auto array_length = static_cast(array->length()); - std::vector strings; - strings.reserve(array_length); - for (size_t i = 0; i < array_length; ++i) { - auto string_array = std::static_pointer_cast(array); - auto str_utf8 = string_array->GetView(i); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto str_utf16, arrow::util::UTF8StringToUTF16(str_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - const mda::MATLABString matlab_string = mda::MATLABString(std::move(str_utf16)); - strings.push_back(matlab_string); - } + // Convert UTF-8 encoded Arrow string values to UTF-16 encoded MATLAB string values. + auto array_length = static_cast(array->length()); + std::vector strings; + strings.reserve(array_length); + for (size_t i = 0; i < array_length; ++i) { + auto string_array = std::static_pointer_cast(array); + auto str_utf8 = string_array->GetView(i); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto str_utf16, + arrow::util::UTF8StringToUTF16(str_utf8), context, + error::UNICODE_CONVERSION_ERROR_ID); + const mda::MATLABString matlab_string = mda::MATLABString(std::move(str_utf16)); + strings.push_back(matlab_string); + } - // Create a MATLAB String array from a vector of UTF-16 encoded strings. - mda::ArrayFactory factory; - auto array_mda = factory.createArray({array_length, 1}, strings.begin(), strings.end()); - context.outputs[0] = array_mda; - } + // Create a MATLAB String array from a vector of UTF-16 encoded strings. + mda::ArrayFactory factory; + auto array_mda = factory.createArray({array_length, 1}, strings.begin(), strings.end()); + context.outputs[0] = array_mda; } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h index 4cc01f0a02f8c..69c6f3b337a8b 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h @@ -25,14 +25,15 @@ namespace arrow::matlab::array::proxy { - class StringArray : public arrow::matlab::array::proxy::Array { - public: - StringArray(const std::shared_ptr string_array); - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); +class StringArray : public arrow::matlab::array::proxy::Array { + public: + StringArray(const std::shared_ptr string_array); - protected: - void toMATLAB(libmexclass::proxy::method::Context& context); - }; + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); -} + protected: + void toMATLAB(libmexclass::proxy::method::Context& context); +}; + +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.cc index c6d9e47a9b0c4..e70c70950e474 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.cc @@ -27,173 +27,169 @@ namespace arrow::matlab::array::proxy { - StructArray::StructArray(std::shared_ptr struct_array) - : proxy::Array{std::move(struct_array)} { - REGISTER_METHOD(StructArray, getNumFields); - REGISTER_METHOD(StructArray, getFieldByIndex); - REGISTER_METHOD(StructArray, getFieldByName); - REGISTER_METHOD(StructArray, getFieldNames); - } - - libmexclass::proxy::MakeResult StructArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using libmexclass::proxy::ProxyManager; - - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; - const mda::StringArray field_names_mda = opts[0]["FieldNames"]; - const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - - std::vector> arrow_arrays; - arrow_arrays.reserve(arrow_array_proxy_ids.getNumberOfElements()); - - // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. - for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { - auto proxy = ProxyManager::getProxy(arrow_array_proxy_id); - auto arrow_array_proxy = std::static_pointer_cast(proxy); - auto arrow_array = arrow_array_proxy->unwrap(); - arrow_arrays.push_back(arrow_array); - } - - // Convert the utf-16 encoded field names into utf-8 encoded strings - std::vector field_names; - field_names.reserve(field_names_mda.getNumberOfElements()); - for (const auto& field_name : field_names_mda) { - const auto field_name_utf16 = std::u16string(field_name); - MATLAB_ASSIGN_OR_ERROR(const auto field_name_utf8, - arrow::util::UTF16StringToUTF8(field_name_utf16), - error::UNICODE_CONVERSION_ERROR_ID); - field_names.push_back(field_name_utf8); - } - - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(auto validity_bitmap_buffer, - bit::packValid(validity_bitmap_mda), - error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - - // Create the StructArray - MATLAB_ASSIGN_OR_ERROR(auto array, - arrow::StructArray::Make(arrow_arrays, field_names, validity_bitmap_buffer), - error::STRUCT_ARRAY_MAKE_FAILED); - - // Construct the StructArray Proxy - auto struct_array = std::static_pointer_cast(array); - return std::make_shared(std::move(struct_array)); - } - - void StructArray::getNumFields(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - mda::ArrayFactory factory; - const auto num_fields = array->type()->num_fields(); - context.outputs[0] = factory.createScalar(num_fields); - } - - void StructArray::getFieldByIndex(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - auto struct_array = std::static_pointer_cast(array); - - const auto num_fields = struct_array->type()->num_fields(); - - // Validate there is at least 1 field - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateNonEmptyContainer(num_fields), - context, error::INDEX_EMPTY_CONTAINER); - - // Validate the matlab index provided is within the range [1, num_fields] - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateInRange(matlab_index, num_fields), - context, error::INDEX_OUT_OF_RANGE); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - const int32_t index = matlab_index - 1; - - auto field_array = struct_array->field(index); - - // Wrap the array within a proxy object if possible. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto field_array_proxy, - proxy::wrap(field_array), - context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - const auto field_array_proxy_id = ProxyManager::manageProxy(field_array_proxy); - const auto type_id = field_array->type_id(); - - // Return a struct with two fields: ProxyID and TypeID. The MATLAB - // layer will use these values to construct the appropriate MATLAB - // arrow.array.Array subclass. - mda::ArrayFactory factory; - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(field_array_proxy_id); - output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); - context.outputs[0] = output; - } - - void StructArray::getFieldByName(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using libmexclass::proxy::ProxyManager; - - mda::StructArray args = context.inputs[0]; - - const mda::StringArray name_mda = args[0]["Name"]; - const auto name_utf16 = std::u16string(name_mda[0]); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, - arrow::util::UTF16StringToUTF8(name_utf16), - context, error::UNICODE_CONVERSION_ERROR_ID); - - - auto struct_array = std::static_pointer_cast(array); - auto field_array = struct_array->GetFieldByName(name); - if (!field_array) { - // Return an error if we could not query the field by name. - const auto msg = "Could not find field named " + name + "."; - context.error = libmexclass::error::Error{ - error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME, msg}; - return; - } - - // Wrap the array within a proxy object if possible. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto field_array_proxy, - proxy::wrap(field_array), - context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - const auto field_array_proxy_id = ProxyManager::manageProxy(field_array_proxy); - const auto type_id = field_array->type_id(); - - // Return a struct with two fields: ProxyID and TypeID. The MATLAB - // layer will use these values to construct the appropriate MATLAB - // arrow.array.Array subclass. - mda::ArrayFactory factory; - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(field_array_proxy_id); - output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); - context.outputs[0] = output; - } - - void StructArray::getFieldNames(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - const auto& fields = array->type()->fields(); - const auto num_fields = fields.size(); - std::vector names; - names.reserve(num_fields); - - for (size_t i = 0; i < num_fields; ++i) { - auto str_utf8 = fields[i]->name(); - - // MATLAB strings are UTF-16 encoded. Must convert UTF-8 - // encoded field names before returning to MATLAB. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto str_utf16, - arrow::util::UTF8StringToUTF16(str_utf8), - context, error::UNICODE_CONVERSION_ERROR_ID); - const mda::MATLABString matlab_string = mda::MATLABString(std::move(str_utf16)); - names.push_back(matlab_string); - } - - mda::ArrayFactory factory; - context.outputs[0] = factory.createArray({1, num_fields}, names.begin(), names.end()); - } +StructArray::StructArray(std::shared_ptr struct_array) + : proxy::Array{std::move(struct_array)} { + REGISTER_METHOD(StructArray, getNumFields); + REGISTER_METHOD(StructArray, getFieldByIndex); + REGISTER_METHOD(StructArray, getFieldByName); + REGISTER_METHOD(StructArray, getFieldNames); } + +libmexclass::proxy::MakeResult StructArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using libmexclass::proxy::ProxyManager; + + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; + const mda::StringArray field_names_mda = opts[0]["FieldNames"]; + const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; + + std::vector> arrow_arrays; + arrow_arrays.reserve(arrow_array_proxy_ids.getNumberOfElements()); + + // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. + for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { + auto proxy = ProxyManager::getProxy(arrow_array_proxy_id); + auto arrow_array_proxy = std::static_pointer_cast(proxy); + auto arrow_array = arrow_array_proxy->unwrap(); + arrow_arrays.push_back(arrow_array); + } + + // Convert the utf-16 encoded field names into utf-8 encoded strings + std::vector field_names; + field_names.reserve(field_names_mda.getNumberOfElements()); + for (const auto& field_name : field_names_mda) { + const auto field_name_utf16 = std::u16string(field_name); + MATLAB_ASSIGN_OR_ERROR(const auto field_name_utf8, + arrow::util::UTF16StringToUTF8(field_name_utf16), + error::UNICODE_CONVERSION_ERROR_ID); + field_names.push_back(field_name_utf8); + } + + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(auto validity_bitmap_buffer, bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + + // Create the StructArray + MATLAB_ASSIGN_OR_ERROR( + auto array, + arrow::StructArray::Make(arrow_arrays, field_names, validity_bitmap_buffer), + error::STRUCT_ARRAY_MAKE_FAILED); + + // Construct the StructArray Proxy + auto struct_array = std::static_pointer_cast(array); + return std::make_shared(std::move(struct_array)); +} + +void StructArray::getNumFields(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + mda::ArrayFactory factory; + const auto num_fields = array->type()->num_fields(); + context.outputs[0] = factory.createScalar(num_fields); +} + +void StructArray::getFieldByIndex(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + auto struct_array = std::static_pointer_cast(array); + + const auto num_fields = struct_array->type()->num_fields(); + + // Validate there is at least 1 field + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(index::validateNonEmptyContainer(num_fields), + context, error::INDEX_EMPTY_CONTAINER); + + // Validate the matlab index provided is within the range [1, num_fields] + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(index::validateInRange(matlab_index, num_fields), + context, error::INDEX_OUT_OF_RANGE); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + const int32_t index = matlab_index - 1; + + auto field_array = struct_array->field(index); + + // Wrap the array within a proxy object if possible. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto field_array_proxy, proxy::wrap(field_array), + context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + const auto field_array_proxy_id = ProxyManager::manageProxy(field_array_proxy); + const auto type_id = field_array->type_id(); + + // Return a struct with two fields: ProxyID and TypeID. The MATLAB + // layer will use these values to construct the appropriate MATLAB + // arrow.array.Array subclass. + mda::ArrayFactory factory; + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(field_array_proxy_id); + output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); + context.outputs[0] = output; +} + +void StructArray::getFieldByName(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using libmexclass::proxy::ProxyManager; + + mda::StructArray args = context.inputs[0]; + + const mda::StringArray name_mda = args[0]["Name"]; + const auto name_utf16 = std::u16string(name_mda[0]); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, + arrow::util::UTF16StringToUTF8(name_utf16), context, + error::UNICODE_CONVERSION_ERROR_ID); + + auto struct_array = std::static_pointer_cast(array); + auto field_array = struct_array->GetFieldByName(name); + if (!field_array) { + // Return an error if we could not query the field by name. + const auto msg = "Could not find field named " + name + "."; + context.error = + libmexclass::error::Error{error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME, msg}; + return; + } + + // Wrap the array within a proxy object if possible. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto field_array_proxy, proxy::wrap(field_array), + context, error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + const auto field_array_proxy_id = ProxyManager::manageProxy(field_array_proxy); + const auto type_id = field_array->type_id(); + + // Return a struct with two fields: ProxyID and TypeID. The MATLAB + // layer will use these values to construct the appropriate MATLAB + // arrow.array.Array subclass. + mda::ArrayFactory factory; + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(field_array_proxy_id); + output[0]["TypeID"] = factory.createScalar(static_cast(type_id)); + context.outputs[0] = output; +} + +void StructArray::getFieldNames(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + const auto& fields = array->type()->fields(); + const auto num_fields = fields.size(); + std::vector names; + names.reserve(num_fields); + + for (size_t i = 0; i < num_fields; ++i) { + auto str_utf8 = fields[i]->name(); + + // MATLAB strings are UTF-16 encoded. Must convert UTF-8 + // encoded field names before returning to MATLAB. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto str_utf16, + arrow::util::UTF8StringToUTF16(str_utf8), context, + error::UNICODE_CONVERSION_ERROR_ID); + const mda::MATLABString matlab_string = mda::MATLABString(std::move(str_utf16)); + names.push_back(matlab_string); + } + + mda::ArrayFactory factory; + context.outputs[0] = factory.createArray({1, num_fields}, names.begin(), names.end()); +} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.h index cfb548c4e50df..e73fe3fd75f58 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/struct_array.h @@ -22,23 +22,22 @@ namespace arrow::matlab::array::proxy { class StructArray : public arrow::matlab::array::proxy::Array { - public: - StructArray(std::shared_ptr struct_array); - - ~StructArray() {} + public: + StructArray(std::shared_ptr struct_array); - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + ~StructArray() {} - protected: + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - void getNumFields(libmexclass::proxy::method::Context& context); + protected: + void getNumFields(libmexclass::proxy::method::Context& context); - void getFieldByIndex(libmexclass::proxy::method::Context& context); + void getFieldByIndex(libmexclass::proxy::method::Context& context); - void getFieldByName(libmexclass::proxy::method::Context& context); - - void getFieldNames(libmexclass::proxy::method::Context& context); + void getFieldByName(libmexclass::proxy::method::Context& context); + void getFieldNames(libmexclass::proxy::method::Context& context); }; -} +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc index 2be1af6d2c264..e1c2a7545bd66 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc @@ -20,9 +20,10 @@ namespace arrow::matlab::array::proxy { - // Specialization of NumericArray::Make for arrow::Time32Type - template <> - libmexclass::proxy::MakeResult Time32Array::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - return make_time_array(constructor_arguments); - } +// Specialization of NumericArray::Make for arrow::Time32Type +template <> +libmexclass::proxy::MakeResult Time32Array::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + return make_time_array(constructor_arguments); } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h index 6770adeaed67d..a843b7137985d 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h @@ -23,9 +23,10 @@ namespace arrow::matlab::array::proxy { - using Time32Array = NumericArray; +using Time32Array = NumericArray; - // Specialization of NumericArray::Make for arrow::Time32Type - template<> - ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult Time32Array::make(const libmexclass::proxy::FunctionArguments& constructor_arguments); -} +// Specialization of NumericArray::Make for arrow::Time32Type +template <> +ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult Time32Array::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.cc index 4ef2e990dc7ec..8bbd5bcd27740 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.cc @@ -20,9 +20,10 @@ namespace arrow::matlab::array::proxy { - // Specialization of NumericArray::Make for arrow::Time64Type - template <> - libmexclass::proxy::MakeResult Time64Array::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - return make_time_array(constructor_arguments); - } +// Specialization of NumericArray::Make for arrow::Time64Type +template <> +libmexclass::proxy::MakeResult Time64Array::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + return make_time_array(constructor_arguments); } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.h index aab586defe75e..91da30b75a506 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/time64_array.h @@ -23,9 +23,10 @@ namespace arrow::matlab::array::proxy { - using Time64Array = NumericArray; +using Time64Array = NumericArray; - // Specialization of NumericArray::Make for arrow::Time64Type - template<> - ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult Time64Array::make(const libmexclass::proxy::FunctionArguments& constructor_arguments); -} +// Specialization of NumericArray::Make for arrow::Time64Type +template <> +ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult Time64Array::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/time_array.h index 696f021921e23..c916e019bcadc 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/time_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/time_array.h @@ -18,55 +18,54 @@ #include "arrow/matlab/array/proxy/numeric_array.h" #include "arrow/matlab/type/time_unit.h" -#include "arrow/util/utf8.h" #include "arrow/type_traits.h" +#include "arrow/util/utf8.h" namespace arrow::matlab::array::proxy { - template - using is_time = arrow::is_time_type; - - template - using enable_if_time = std::enable_if_t::value, bool>; +template +using is_time = arrow::is_time_type; - template = true> - libmexclass::proxy::MakeResult make_time_array(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using namespace arrow::matlab::type; - using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; - using TimeArray = arrow::NumericArray; - using TimeArrayProxy = proxy::NumericArray; - using CType = typename arrow::TypeTraits::CType; +template +using enable_if_time = std::enable_if_t::value, bool>; - mda::StructArray opts = constructor_arguments[0]; +template = true> +libmexclass::proxy::MakeResult make_time_array( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using namespace arrow::matlab::type; + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + using TimeArray = arrow::NumericArray; + using TimeArrayProxy = proxy::NumericArray; + using CType = typename arrow::TypeTraits::CType; - const mda::TypedArray time_mda = opts[0]["MatlabArray"]; - const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - const mda::TypedArray time_unit_mda = opts[0]["TimeUnit"]; + mda::StructArray opts = constructor_arguments[0]; - // extract the time unit - const std::u16string& time_unit_utf16 = time_unit_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto time_unit, - timeUnitFromString(time_unit_utf16), - error::UNKNOWN_TIME_UNIT_ERROR_ID); + const mda::TypedArray time_mda = opts[0]["MatlabArray"]; + const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; + const mda::TypedArray time_unit_mda = opts[0]["TimeUnit"]; - MATLAB_ERROR_IF_NOT_OK(validateTimeUnit(time_unit), - error::INVALID_TIME_UNIT); + // extract the time unit + const std::u16string& time_unit_utf16 = time_unit_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto time_unit, timeUnitFromString(time_unit_utf16), + error::UNKNOWN_TIME_UNIT_ERROR_ID); - // create the ArrowType - const auto data_type = std::make_shared(time_unit); + MATLAB_ERROR_IF_NOT_OK(validateTimeUnit(time_unit), + error::INVALID_TIME_UNIT); - auto array_length = static_cast(time_mda.getNumberOfElements()); - auto data_buffer = std::make_shared(time_mda); + // create the ArrowType + const auto data_type = std::make_shared(time_unit); - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, - bit::packValid(validity_bitmap_mda), - error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + auto array_length = static_cast(time_mda.getNumberOfElements()); + auto data_buffer = std::make_shared(time_mda); - auto array_data = arrow::ArrayData::Make(data_type, array_length, {packed_validity_bitmap, data_buffer}); - auto time_array = std::static_pointer_cast(arrow::MakeArray(array_data)); - return std::make_shared(std::move(time_array)); + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - } -} \ No newline at end of file + auto array_data = arrow::ArrayData::Make(data_type, array_length, + {packed_validity_bitmap, data_buffer}); + auto time_array = std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(time_array)); +} +} // namespace arrow::matlab::array::proxy \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc index 24abb4161a865..0b6391cc337e9 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc @@ -22,48 +22,52 @@ namespace arrow::matlab::array::proxy { - // Specialization of NumericArray::Make for arrow::TimestampType. - template <> - libmexclass::proxy::MakeResult TimestampArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; - using TimestampArray = arrow::TimestampArray; - using TimestampArrayProxy = arrow::matlab::array::proxy::NumericArray; +// Specialization of NumericArray::Make for arrow::TimestampType. +template <> +libmexclass::proxy::MakeResult TimestampArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + using TimestampArray = arrow::TimestampArray; + using TimestampArrayProxy = + arrow::matlab::array::proxy::NumericArray; - mda::StructArray opts = constructor_arguments[0]; + mda::StructArray opts = constructor_arguments[0]; - // Get the mxArray from constructor arguments - const mda::TypedArray timestamp_mda = opts[0]["MatlabArray"]; - const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - - const mda::TypedArray timezone_mda = opts[0]["TimeZone"]; - const mda::TypedArray units_mda = opts[0]["TimeUnit"]; + // Get the mxArray from constructor arguments + const mda::TypedArray timestamp_mda = opts[0]["MatlabArray"]; + const mda::TypedArray validity_bitmap_mda = opts[0]["Valid"]; - // extract the time zone string - const std::u16string& u16_timezone = timezone_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto timezone, - arrow::util::UTF16StringToUTF8(u16_timezone), - error::UNICODE_CONVERSION_ERROR_ID); + const mda::TypedArray timezone_mda = opts[0]["TimeZone"]; + const mda::TypedArray units_mda = opts[0]["TimeUnit"]; - // extract the time unit - const std::u16string& u16_timeunit = units_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto time_unit, - arrow::matlab::type::timeUnitFromString(u16_timeunit), - error::UNKNOWN_TIME_UNIT_ERROR_ID) + // extract the time zone string + const std::u16string& u16_timezone = timezone_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto timezone, + arrow::util::UTF16StringToUTF8(u16_timezone), + error::UNICODE_CONVERSION_ERROR_ID); - // create the timestamp_type - auto data_type = arrow::timestamp(time_unit, timezone); - auto array_length = static_cast(timestamp_mda.getNumberOfElements()); // cast size_t to int64_t + // extract the time unit + const std::u16string& u16_timeunit = units_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto time_unit, + arrow::matlab::type::timeUnitFromString(u16_timeunit), + error::UNKNOWN_TIME_UNIT_ERROR_ID) - auto data_buffer = std::make_shared(timestamp_mda); + // create the timestamp_type + auto data_type = arrow::timestamp(time_unit, timezone); + auto array_length = static_cast( + timestamp_mda.getNumberOfElements()); // cast size_t to int64_t - // Pack the validity bitmap values. - MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, - bit::packValid(validity_bitmap_mda), - error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + auto data_buffer = std::make_shared(timestamp_mda); - auto array_data = arrow::ArrayData::Make(data_type, array_length, {packed_validity_bitmap, data_buffer}); - auto timestamp_array = std::static_pointer_cast(arrow::MakeArray(array_data)); - return std::make_shared(std::move(timestamp_array)); - } + // Pack the validity bitmap values. + MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); + + auto array_data = arrow::ArrayData::Make(data_type, array_length, + {packed_validity_bitmap, data_buffer}); + auto timestamp_array = + std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(timestamp_array)); } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h index 0667917f3689a..4ecf53e1be948 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h @@ -23,9 +23,10 @@ namespace arrow::matlab::array::proxy { - using TimestampArray = NumericArray; +using TimestampArray = NumericArray; - // Specialization of NumericArray::Make for arrow::TimestampType - template<> - ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult TimestampArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments); -} +// Specialization of NumericArray::Make for arrow::TimestampType +template <> +ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult TimestampArray::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/wrap.cc b/matlab/src/cpp/arrow/matlab/array/proxy/wrap.cc index 8e300c959717a..3e38306906588 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/wrap.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/wrap.cc @@ -15,60 +15,80 @@ // specific language governing permissions and limitations // under the License. - #include "arrow/matlab/array/proxy/wrap.h" #include "arrow/matlab/array/proxy/array.h" #include "arrow/matlab/array/proxy/boolean_array.h" +#include "arrow/matlab/array/proxy/list_array.h" #include "arrow/matlab/array/proxy/numeric_array.h" #include "arrow/matlab/array/proxy/string_array.h" -#include "arrow/matlab/array/proxy/list_array.h" #include "arrow/matlab/array/proxy/struct_array.h" namespace arrow::matlab::array::proxy { - arrow::Result> wrap(const std::shared_ptr& array) { - using ID = arrow::Type::type; - switch (array->type_id()) { - case ID::BOOL: - return std::make_shared(std::static_pointer_cast(array)); - case ID::UINT8: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::UINT16: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::UINT32: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::UINT64: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::INT8: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::INT16: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::INT32: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::INT64: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::FLOAT: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::DOUBLE: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::TIMESTAMP: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::TIME32: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::TIME64: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::DATE32: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::DATE64: - return std::make_shared>(std::static_pointer_cast(array)); - case ID::STRING: - return std::make_shared(std::static_pointer_cast(array)); - case ID::LIST: - return std::make_shared(std::static_pointer_cast(array)); - case ID::STRUCT: - return std::make_shared(std::static_pointer_cast(array)); - default: - return arrow::Status::NotImplemented("Unsupported DataType: " + array->type()->ToString()); - } - } +arrow::Result> wrap( + const std::shared_ptr& array) { + using ID = arrow::Type::type; + switch (array->type_id()) { + case ID::BOOL: + return std::make_shared( + std::static_pointer_cast(array)); + case ID::UINT8: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::UINT16: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::UINT32: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::UINT64: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::INT8: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::INT16: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::INT32: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::INT64: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::FLOAT: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::DOUBLE: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::TIMESTAMP: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::TIME32: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::TIME64: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::DATE32: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::DATE64: + return std::make_shared>( + std::static_pointer_cast(array)); + case ID::STRING: + return std::make_shared( + std::static_pointer_cast(array)); + case ID::LIST: + return std::make_shared( + std::static_pointer_cast(array)); + case ID::STRUCT: + return std::make_shared( + std::static_pointer_cast(array)); + default: + return arrow::Status::NotImplemented("Unsupported DataType: " + + array->type()->ToString()); + } } +} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/wrap.h b/matlab/src/cpp/arrow/matlab/array/proxy/wrap.h index 5ccb498f7689a..4555990c003d5 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/wrap.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/wrap.h @@ -24,6 +24,7 @@ namespace arrow::matlab::array::proxy { - arrow::Result> wrap(const std::shared_ptr& array); +arrow::Result> wrap( + const std::shared_ptr& array); } diff --git a/matlab/src/cpp/arrow/matlab/array/validation_mode.h b/matlab/src/cpp/arrow/matlab/array/validation_mode.h index 92e10f47aa4e7..fdde07350e6c0 100644 --- a/matlab/src/cpp/arrow/matlab/array/validation_mode.h +++ b/matlab/src/cpp/arrow/matlab/array/validation_mode.h @@ -21,10 +21,6 @@ namespace arrow::matlab::array { - enum class ValidationMode : uint8_t { - None = 0, - Minimal = 1, - Full = 2 - }; +enum class ValidationMode : uint8_t { None = 0, Minimal = 1, Full = 2 }; } diff --git a/matlab/src/cpp/arrow/matlab/bit/pack.cc b/matlab/src/cpp/arrow/matlab/bit/pack.cc index d47f2955f1081..17c1f7ae8e6cd 100644 --- a/matlab/src/cpp/arrow/matlab/bit/pack.cc +++ b/matlab/src/cpp/arrow/matlab/bit/pack.cc @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -#include // std::ceil +#include // std::ceil #include #include @@ -24,49 +24,53 @@ namespace arrow::matlab::bit { - // Calculate the number of bytes required in the bit-packed validity buffer. - int64_t packedLength(int64_t num_elements) { - // Since MATLAB logical values are encoded using a full byte (8 bits), - // we can divide the number of elements in the logical array by 8 to get - // the bit packed length. - return static_cast(std::ceil(num_elements / 8.0)); - } - - arrow::Result> packValid(const ::matlab::data::TypedArray matlab_logical_array) { - const auto unpacked_buffer_length = matlab_logical_array.getNumberOfElements(); - if (unpacked_buffer_length > 0) { - return arrow::matlab::bit::pack(matlab_logical_array); - } else { - return nullptr; - } - } +// Calculate the number of bytes required in the bit-packed validity buffer. +int64_t packedLength(int64_t num_elements) { + // Since MATLAB logical values are encoded using a full byte (8 bits), + // we can divide the number of elements in the logical array by 8 to get + // the bit packed length. + return static_cast(std::ceil(num_elements / 8.0)); +} - // Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer. - arrow::Result> pack(const ::matlab::data::TypedArray matlab_logical_array) { - // Validate that the input arrow::Buffer has sufficient size to store a full bit-packed - // representation of the input MATLAB logical array. - const auto unpacked_buffer_length = matlab_logical_array.getNumberOfElements(); +arrow::Result> packValid( + const ::matlab::data::TypedArray matlab_logical_array) { + const auto unpacked_buffer_length = matlab_logical_array.getNumberOfElements(); + if (unpacked_buffer_length > 0) { + return arrow::matlab::bit::pack(matlab_logical_array); + } else { + return nullptr; + } +} - // Compute the bit packed length from the unpacked length. - const auto packed_buffer_length = packedLength(unpacked_buffer_length); +// Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer. +arrow::Result> pack( + const ::matlab::data::TypedArray matlab_logical_array) { + // Validate that the input arrow::Buffer has sufficient size to store a full bit-packed + // representation of the input MATLAB logical array. + const auto unpacked_buffer_length = matlab_logical_array.getNumberOfElements(); - ARROW_ASSIGN_OR_RAISE(auto packed_validity_bitmap_buffer, arrow::AllocateResizableBuffer(packed_buffer_length)); + // Compute the bit packed length from the unpacked length. + const auto packed_buffer_length = packedLength(unpacked_buffer_length); - // Get pointers to the internal uint8_t arrays behind arrow::Buffer and mxArray - // Get raw bool array pointer from MATLAB logical array. - // Get an iterator to the raw bool data behind the MATLAB logical array. - auto unpacked_bool_data_iterator = matlab_logical_array.cbegin(); + ARROW_ASSIGN_OR_RAISE(auto packed_validity_bitmap_buffer, + arrow::AllocateResizableBuffer(packed_buffer_length)); - // Iterate over the mxLogical array and write bit-packed bools to the arrow::Buffer. - // Call into a loop-unrolled Arrow utility for better performance when bit-packing. - auto generator = [&]() -> bool { return *(unpacked_bool_data_iterator++); }; - const int64_t start_offset = 0; + // Get pointers to the internal uint8_t arrays behind arrow::Buffer and mxArray + // Get raw bool array pointer from MATLAB logical array. + // Get an iterator to the raw bool data behind the MATLAB logical array. + auto unpacked_bool_data_iterator = matlab_logical_array.cbegin(); - auto mutable_data = packed_validity_bitmap_buffer->mutable_data(); + // Iterate over the mxLogical array and write bit-packed bools to the arrow::Buffer. + // Call into a loop-unrolled Arrow utility for better performance when bit-packing. + auto generator = [&]() -> bool { return *(unpacked_bool_data_iterator++); }; + const int64_t start_offset = 0; - arrow::internal::GenerateBitsUnrolled(mutable_data, start_offset, unpacked_buffer_length, generator); + auto mutable_data = packed_validity_bitmap_buffer->mutable_data(); - return packed_validity_bitmap_buffer; - } + arrow::internal::GenerateBitsUnrolled(mutable_data, start_offset, + unpacked_buffer_length, generator); + return packed_validity_bitmap_buffer; } + +} // namespace arrow::matlab::bit diff --git a/matlab/src/cpp/arrow/matlab/bit/pack.h b/matlab/src/cpp/arrow/matlab/bit/pack.h index 2c63f3551953e..a80d70d9c1a99 100644 --- a/matlab/src/cpp/arrow/matlab/bit/pack.h +++ b/matlab/src/cpp/arrow/matlab/bit/pack.h @@ -23,12 +23,15 @@ #include "MatlabDataArray.hpp" namespace arrow::matlab::bit { - // Calculate the number of bytes required in the bit-packed validity buffer. - int64_t packedLength(int64_t num_elements); +// Calculate the number of bytes required in the bit-packed validity buffer. +int64_t packedLength(int64_t num_elements); - // Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer representing the validity bitmap. - arrow::Result> packValid(const ::matlab::data::TypedArray matlab_logical_array); +// Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer representing the +// validity bitmap. +arrow::Result> packValid( + const ::matlab::data::TypedArray matlab_logical_array); - // Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer. - arrow::Result> pack(const ::matlab::data::TypedArray matlab_logical_array); -} +// Pack an unpacked MATLAB logical array into a bit-packed arrow::Buffer. +arrow::Result> pack( + const ::matlab::data::TypedArray matlab_logical_array); +} // namespace arrow::matlab::bit diff --git a/matlab/src/cpp/arrow/matlab/bit/unpack.cc b/matlab/src/cpp/arrow/matlab/bit/unpack.cc index 6cc88d48ede43..a7919a3ce5787 100644 --- a/matlab/src/cpp/arrow/matlab/bit/unpack.cc +++ b/matlab/src/cpp/arrow/matlab/bit/unpack.cc @@ -20,30 +20,35 @@ #include "arrow/util/bitmap_visit.h" namespace arrow::matlab::bit { - ::matlab::data::TypedArray unpack(const std::shared_ptr& packed_buffer, int64_t length, int64_t start_offset) { - const auto packed_buffer_ptr = packed_buffer->data(); - - ::matlab::data::ArrayFactory factory; - - const auto array_length = static_cast(length); - - auto unpacked_buffer = factory.createBuffer(array_length); - auto unpacked_buffer_ptr = unpacked_buffer.get(); - auto visitFcn = [&](const bool is_valid) { *unpacked_buffer_ptr++ = is_valid; }; - - arrow::internal::VisitBitsUnrolled(packed_buffer_ptr, start_offset, length, visitFcn); - - ::matlab::data::TypedArray unpacked_matlab_logical_Array = factory.createArrayFromBuffer({array_length, 1}, std::move(unpacked_buffer)); - - return unpacked_matlab_logical_Array; - } - - const uint8_t* extract_ptr(const ::matlab::data::TypedArray& unpacked_validity_bitmap) { - if (unpacked_validity_bitmap.getNumberOfElements() > 0) { - const auto unpacked_validity_bitmap_iterator(unpacked_validity_bitmap.cbegin()); - return reinterpret_cast(unpacked_validity_bitmap_iterator.operator->()); - } else { - return nullptr; - } - } +::matlab::data::TypedArray unpack( + const std::shared_ptr& packed_buffer, int64_t length, + int64_t start_offset) { + const auto packed_buffer_ptr = packed_buffer->data(); + + ::matlab::data::ArrayFactory factory; + + const auto array_length = static_cast(length); + + auto unpacked_buffer = factory.createBuffer(array_length); + auto unpacked_buffer_ptr = unpacked_buffer.get(); + auto visitFcn = [&](const bool is_valid) { *unpacked_buffer_ptr++ = is_valid; }; + + arrow::internal::VisitBitsUnrolled(packed_buffer_ptr, start_offset, length, visitFcn); + + ::matlab::data::TypedArray unpacked_matlab_logical_Array = + factory.createArrayFromBuffer({array_length, 1}, std::move(unpacked_buffer)); + + return unpacked_matlab_logical_Array; +} + +const uint8_t* extract_ptr( + const ::matlab::data::TypedArray& unpacked_validity_bitmap) { + if (unpacked_validity_bitmap.getNumberOfElements() > 0) { + const auto unpacked_validity_bitmap_iterator(unpacked_validity_bitmap.cbegin()); + return reinterpret_cast( + unpacked_validity_bitmap_iterator.operator->()); + } else { + return nullptr; + } } +} // namespace arrow::matlab::bit diff --git a/matlab/src/cpp/arrow/matlab/bit/unpack.h b/matlab/src/cpp/arrow/matlab/bit/unpack.h index 6cd633e76fa56..3841a902effef 100644 --- a/matlab/src/cpp/arrow/matlab/bit/unpack.h +++ b/matlab/src/cpp/arrow/matlab/bit/unpack.h @@ -22,6 +22,9 @@ #include "MatlabDataArray.hpp" namespace arrow::matlab::bit { - ::matlab::data::TypedArray unpack(const std::shared_ptr& packed_buffer, int64_t length, int64_t start_offset); - const uint8_t* extract_ptr(const ::matlab::data::TypedArray& unpacked_validity_bitmap); -} +::matlab::data::TypedArray unpack( + const std::shared_ptr& packed_buffer, int64_t length, + int64_t start_offset); +const uint8_t* extract_ptr( + const ::matlab::data::TypedArray& unpacked_validity_bitmap); +} // namespace arrow::matlab::bit diff --git a/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h b/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h index 80b237544ded8..900d976acc1ed 100644 --- a/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h +++ b/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h @@ -23,26 +23,24 @@ namespace arrow::matlab::buffer { - namespace mda = ::matlab::data; - - class MatlabBuffer : public arrow::Buffer { - public: - - template - MatlabBuffer(const mda::TypedArray typed_array) - : arrow::Buffer{nullptr, 0} - , array{typed_array} { - - // Get raw pointer of mxArray - auto it(typed_array.cbegin()); - auto dt = it.operator->(); - - data_ = reinterpret_cast(dt); - size_ = sizeof(CType) * static_cast(typed_array.getNumberOfElements()); - capacity_ = size_; - is_mutable_ = false; - } - private: - const mda::Array array; - }; -} \ No newline at end of file +namespace mda = ::matlab::data; + +class MatlabBuffer : public arrow::Buffer { + public: + template + MatlabBuffer(const mda::TypedArray typed_array) + : arrow::Buffer{nullptr, 0}, array{typed_array} { + // Get raw pointer of mxArray + auto it(typed_array.cbegin()); + auto dt = it.operator->(); + + data_ = reinterpret_cast(dt); + size_ = sizeof(CType) * static_cast(typed_array.getNumberOfElements()); + capacity_ = size_; + is_mutable_ = false; + } + + private: + const mda::Array array; +}; +} // namespace arrow::matlab::buffer \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc index 633b82d9fa127..e9b314050dd90 100644 --- a/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc +++ b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc @@ -15,7 +15,6 @@ // specific language governing permissions and limitations // under the License. - #include "arrow/matlab/buffer/proxy/buffer.h" #include "arrow/matlab/buffer/matlab_buffer.h" #include "arrow/matlab/error/error.h" @@ -23,74 +22,74 @@ namespace arrow::matlab::buffer::proxy { - Buffer::Buffer(std::shared_ptr buffer) : buffer{std::move(buffer)} { - REGISTER_METHOD(Buffer, getNumBytes); - REGISTER_METHOD(Buffer, isEqual); - REGISTER_METHOD(Buffer, toMATLAB); - } - - libmexclass::proxy::MakeResult Buffer::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using BufferProxy = proxy::Buffer; - using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; - - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray values_mda = opts[0]["Values"]; - auto buffer = std::make_shared(values_mda); - return std::make_shared(std::move(buffer)); - } - - std::shared_ptr Buffer::unwrap() { - return buffer; - } - - void Buffer::getNumBytes(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - auto num_bytes_mda = factory.createScalar(buffer->size()); - context.outputs[0] = num_bytes_mda; - } - - void Buffer::isEqual(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - bool is_equal = true; - const mda::TypedArray buffer_proxy_ids = context.inputs[0]; - for (const auto& buffer_proxy_id : buffer_proxy_ids) { - // Retrieve the Buffer proxy from the ProxyManager - auto proxy = libmexclass::proxy::ProxyManager::getProxy(buffer_proxy_id); - auto buffer_proxy = std::static_pointer_cast(proxy); - auto buffer_to_compare = buffer_proxy->unwrap(); - - if (!buffer->Equals(*buffer_to_compare)) { - is_equal = false; - break; - } - } - mda::ArrayFactory factory; - context.outputs[0] = factory.createScalar(is_equal); +Buffer::Buffer(std::shared_ptr buffer) : buffer{std::move(buffer)} { + REGISTER_METHOD(Buffer, getNumBytes); + REGISTER_METHOD(Buffer, isEqual); + REGISTER_METHOD(Buffer, toMATLAB); +} + +libmexclass::proxy::MakeResult Buffer::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using BufferProxy = proxy::Buffer; + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray values_mda = opts[0]["Values"]; + auto buffer = std::make_shared(values_mda); + return std::make_shared(std::move(buffer)); +} + +std::shared_ptr Buffer::unwrap() { return buffer; } + +void Buffer::getNumBytes(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + auto num_bytes_mda = factory.createScalar(buffer->size()); + context.outputs[0] = num_bytes_mda; +} + +void Buffer::isEqual(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + bool is_equal = true; + const mda::TypedArray buffer_proxy_ids = context.inputs[0]; + for (const auto& buffer_proxy_id : buffer_proxy_ids) { + // Retrieve the Buffer proxy from the ProxyManager + auto proxy = libmexclass::proxy::ProxyManager::getProxy(buffer_proxy_id); + auto buffer_proxy = std::static_pointer_cast(proxy); + auto buffer_to_compare = buffer_proxy->unwrap(); + + if (!buffer->Equals(*buffer_to_compare)) { + is_equal = false; + break; } - - void Buffer::toMATLAB(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - // If buffer->is_cpu() returns false, invoking buffer->data() may cause a crash. - // Avoid this potential crash by first invoking ViewOrCopy(buffer, memory_manager_device). - // This function tries to create a no-copy view of the buffer on the given memory - // manager device. If not possible, then ViewOrCopy copies the buffer's contents. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( - auto cpu_buffer, - arrow::Buffer::ViewOrCopy(buffer, arrow::default_cpu_memory_manager()), - context, error::BUFFER_VIEW_OR_COPY_FAILED - ); - - const auto* data_begin = cpu_buffer->data(); - const auto num_bytes = cpu_buffer->size(); - // data_begin is a uint8_t*, so num_bytes is equal to the number of elements - const auto* data_end = data_begin + num_bytes; - - mda::ArrayFactory factory; - context.outputs[0] = factory.createArray({static_cast(num_bytes), 1}, data_begin, data_end); - } - -} \ No newline at end of file + } + mda::ArrayFactory factory; + context.outputs[0] = factory.createScalar(is_equal); +} + +void Buffer::toMATLAB(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + // If buffer->is_cpu() returns false, invoking buffer->data() may cause a crash. + // Avoid this potential crash by first invoking ViewOrCopy(buffer, + // memory_manager_device). This function tries to create a no-copy view of the buffer on + // the given memory manager device. If not possible, then ViewOrCopy copies the buffer's + // contents. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto cpu_buffer, + arrow::Buffer::ViewOrCopy(buffer, arrow::default_cpu_memory_manager()), context, + error::BUFFER_VIEW_OR_COPY_FAILED); + + const auto* data_begin = cpu_buffer->data(); + const auto num_bytes = cpu_buffer->size(); + // data_begin is a uint8_t*, so num_bytes is equal to the number of elements + const auto* data_end = data_begin + num_bytes; + + mda::ArrayFactory factory; + context.outputs[0] = factory.createArray({static_cast(num_bytes), 1}, + data_begin, data_end); +} + +} // namespace arrow::matlab::buffer::proxy \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h index bb6dc5e4c5d2c..bbeb6c88ffc8e 100644 --- a/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h +++ b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h @@ -24,23 +24,24 @@ namespace arrow::matlab::buffer::proxy { class Buffer : public libmexclass::proxy::Proxy { - public: - Buffer(std::shared_ptr buffer); - - ~Buffer() {} + public: + Buffer(std::shared_ptr buffer); - std::shared_ptr unwrap(); + ~Buffer() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + std::shared_ptr unwrap(); - protected: - void getNumBytes(libmexclass::proxy::method::Context& context); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - void toMATLAB(libmexclass::proxy::method::Context& context); + protected: + void getNumBytes(libmexclass::proxy::method::Context& context); - void isEqual(libmexclass::proxy::method::Context& context); + void toMATLAB(libmexclass::proxy::method::Context& context); - std::shared_ptr buffer; + void isEqual(libmexclass::proxy::method::Context& context); + + std::shared_ptr buffer; }; -} +} // namespace arrow::matlab::buffer::proxy diff --git a/matlab/src/cpp/arrow/matlab/error/error.h b/matlab/src/cpp/arrow/matlab/error/error.h index c9eaf1d9640d4..db8b715141ee8 100644 --- a/matlab/src/cpp/arrow/matlab/error/error.h +++ b/matlab/src/cpp/arrow/matlab/error/error.h @@ -35,19 +35,20 @@ // --- Arguments --- // // expr - expression that returns an arrow::Status (e.g. builder.Append(...)) -// id - MATLAB error ID string (const char* - "arrow:matlab:proxy:make:FailedConstruction") +// id - MATLAB error ID string (const char* - +// "arrow:matlab:proxy:make:FailedConstruction") // // --- Example --- // // MATLAB_ERROR_IF_NOT_OK(builder.Append(...), error::BUILDER_FAILED_TO_APPEND); // -#define MATLAB_ERROR_IF_NOT_OK(expr, id) \ - do { \ - arrow::Status _status = (expr); \ - if (!_status.ok()) { \ - return libmexclass::error::Error{(id), _status.message()}; \ - } \ - } while (0) +#define MATLAB_ERROR_IF_NOT_OK(expr, id) \ + do { \ + arrow::Status _status = (expr); \ + if (!_status.ok()) { \ + return libmexclass::error::Error{(id), _status.message()}; \ + } \ + } while (0) // // MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(expr, context, id) @@ -58,35 +59,37 @@ // by the specified expression is not "OK" (i.e. error). // // **NOTE**: This macro should be used inside of a non-static member function of a -// Proxy class which has a libmexclass::proxy::method::Context as an input argument. -// Use MATLAB_ERROR_IF_NOT_OK inside of a Proxy static make() member function. +// Proxy class which has a libmexclass::proxy::method::Context as an input +// argument. Use MATLAB_ERROR_IF_NOT_OK inside of a Proxy static make() member +// function. // // --- Arguments --- // // expr - expression that returns an arrow::Status (e.g. builder.Append(...)) // context - libmexclass::proxy::method::Context context input to a Proxy method -// id - MATLAB error ID string (const char* - "arrow:matlab:proxy:make:FailedConstruction") +// id - MATLAB error ID string (const char* - +// "arrow:matlab:proxy:make:FailedConstruction") // // --- Example --- // -// MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(builder.Append(...), context, error::BUILDER_FAILED_TO_APPEND); -// -#define MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(expr, context, id) \ - do { \ - arrow::Status _status = (expr); \ - if (!_status.ok()) { \ - context.error = libmexclass::error::Error{id, _status.message()}; \ - return; \ - } \ - } while (0) +// MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(builder.Append(...), context, +// error::BUILDER_FAILED_TO_APPEND); +// +#define MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(expr, context, id) \ + do { \ + arrow::Status _status = (expr); \ + if (!_status.ok()) { \ + context.error = libmexclass::error::Error{id, _status.message()}; \ + return; \ + } \ + } while (0) -#define MATLAB_ASSIGN_OR_ERROR_NAME(x, y) \ - ARROW_CONCAT(x, y) +#define MATLAB_ASSIGN_OR_ERROR_NAME(x, y) ARROW_CONCAT(x, y) #define MATLAB_ASSIGN_OR_ERROR_IMPL(result_name, lhs, rexpr, id) \ - auto&& result_name = (rexpr); \ - MATLAB_ERROR_IF_NOT_OK(result_name.status(), id); \ - lhs = std::move(result_name).ValueUnsafe(); + auto&& result_name = (rexpr); \ + MATLAB_ERROR_IF_NOT_OK(result_name.status(), id); \ + lhs = std::move(result_name).ValueUnsafe(); // // MATLAB_ASSIGN_OR_ERROR(lhs, rexpr, id) @@ -110,21 +113,21 @@ // // lhs - variable name to assign to (e.g. auto array) // rexpr - expression that returns an arrow::Result (e.g. builder.Finish()) -// id - MATLAB error ID string (const char* - "arrow:matlab:proxy:make:FailedConstruction") +// id - MATLAB error ID string (const char* - +// "arrow:matlab:proxy:make:FailedConstruction") // // --- Example --- // // MATLAB_ASSIGN_OR_ERROR(auto array, builder.Finish(), error::FAILED_TO_BUILD_ARRAY); // -#define MATLAB_ASSIGN_OR_ERROR(lhs, rexpr, id) \ - MATLAB_ASSIGN_OR_ERROR_IMPL(MATLAB_ASSIGN_OR_ERROR_NAME(_matlab_error_or_value, __COUNTER__), \ - lhs, rexpr, id); - +#define MATLAB_ASSIGN_OR_ERROR(lhs, rexpr, id) \ + MATLAB_ASSIGN_OR_ERROR_IMPL( \ + MATLAB_ASSIGN_OR_ERROR_NAME(_matlab_error_or_value, __COUNTER__), lhs, rexpr, id); #define MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT_IMPL(result_name, lhs, rexpr, context, id) \ - auto&& result_name = (rexpr); \ - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(result_name.status(), context, id); \ - lhs = std::move(result_name).ValueUnsafe(); + auto&& result_name = (rexpr); \ + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(result_name.status(), context, id); \ + lhs = std::move(result_name).ValueUnsafe(); // // MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(lhs, rexpr, context, id) @@ -141,73 +144,101 @@ // then the specified error ID is returned to MATLAB. // // **NOTE**: This macro should be used inside of a non-static member function of a -// Proxy class which has a libmexclass::proxy::method::Context as an input argument. -// Use MATLAB_ASSIGN_OR_ERROR inside of a Proxy static make() member function. +// Proxy class which has a libmexclass::proxy::method::Context as an input +// argument. Use MATLAB_ASSIGN_OR_ERROR inside of a Proxy static make() member +// function. // // --- Arguments --- // // lhs - variable name to assign to (e.g. auto array) // rexpr - expression that returns an arrow::Result (e.g. builder.Finish()) // context - libmexclass::proxy::method::Context context input to a Proxy method -// id - MATLAB error ID string (const char* - "arrow:matlab:proxy:make:FailedConstruction") +// id - MATLAB error ID string (const char* - +// "arrow:matlab:proxy:make:FailedConstruction") // // --- Example --- // -// MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array, builder.Finish(), error::FAILED_TO_BUILD_ARRAY); +// MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array, builder.Finish(), +// error::FAILED_TO_BUILD_ARRAY); // -#define MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(lhs, rexpr, context, id) \ - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT_IMPL(MATLAB_ASSIGN_OR_ERROR_NAME(_matlab_error_or_value, __COUNTER__), \ - lhs, rexpr, context, id); +#define MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(lhs, rexpr, context, id) \ + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT_IMPL( \ + MATLAB_ASSIGN_OR_ERROR_NAME(_matlab_error_or_value, __COUNTER__), lhs, rexpr, \ + context, id); namespace arrow::matlab::error { - // TODO: Make Error ID Enum class to avoid defining static constexpr - static const char* APPEND_VALUES_ERROR_ID = "arrow:matlab:proxy:make:FailedToAppendValues"; - static const char* BUILD_ARRAY_ERROR_ID = "arrow:matlab:proxy:make:FailedToAppendValues"; - static const char* BITPACK_VALIDITY_BITMAP_ERROR_ID = "arrow:matlab:proxy:make:FailedToBitPackValidityBitmap"; - static const char* UNKNOWN_PROXY_ERROR_ID = "arrow:matlab:proxy:UnknownProxy"; - static const char* SCHEMA_BUILDER_FINISH_ERROR_ID = "arrow:matlab:tabular:proxy:SchemaBuilderAddFields"; - static const char* SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID = "arrow:matlab:tabular:proxy:SchemaBuilderFinish"; - static const char* UNICODE_CONVERSION_ERROR_ID = "arrow:matlab:unicode:UnicodeConversion"; - static const char* STRING_BUILDER_APPEND_FAILED = "arrow:matlab:array:string:StringBuilderAppendFailed"; - static const char* STRING_BUILDER_FINISH_FAILED = "arrow:matlab:array:string:StringBuilderFinishFailed"; - static const char* UNKNOWN_TIME_UNIT_ERROR_ID = "arrow:matlab:UnknownTimeUnit"; - static const char* INVALID_TIME_UNIT = "arrow:type:InvalidTimeUnit"; - static const char* FIELD_FAILED_TO_CREATE_TYPE_PROXY = "arrow:field:FailedToCreateTypeProxy"; - static const char* ARRAY_FAILED_TO_CREATE_TYPE_PROXY = "arrow:array:FailedToCreateTypeProxy"; - static const char* LIST_TYPE_FAILED_TO_CREATE_VALUE_TYPE_PROXY = "arrow:type:list:FailedToCreateValueTypeProxy"; - static const char* ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME = "arrow:tabular:schema:AmbiguousFieldName"; - static const char* UNKNOWN_PROXY_FOR_ARRAY_TYPE = "arrow:array:UnknownProxyForArrayType"; - static const char* RECORD_BATCH_NUMERIC_INDEX_WITH_EMPTY_RECORD_BATCH = "arrow:tabular:recordbatch:NumericIndexWithEmptyRecordBatch"; - static const char* RECORD_BATCH_INVALID_NUMERIC_COLUMN_INDEX = "arrow:tabular:recordbatch:InvalidNumericColumnIndex"; - static const char* TABLE_NUMERIC_INDEX_WITH_EMPTY_TABLE = "arrow:tabular:table:NumericIndexWithEmptyTable"; - static const char* TABLE_INVALID_NUMERIC_COLUMN_INDEX = "arrow:tabular:table:InvalidNumericColumnIndex"; - static const char* FAILED_TO_OPEN_FILE_FOR_WRITE = "arrow:io:FailedToOpenFileForWrite"; - static const char* FAILED_TO_OPEN_FILE_FOR_READ = "arrow:io:FailedToOpenFileForRead"; - static const char* CSV_FAILED_TO_WRITE_TABLE = "arrow:io:csv:FailedToWriteTable"; - static const char* CSV_FAILED_TO_CREATE_TABLE_READER = "arrow:io:csv:FailedToCreateTableReader"; - static const char* CSV_FAILED_TO_READ_TABLE = "arrow:io:csv:FailedToReadTable"; - static const char* FEATHER_FAILED_TO_WRITE_TABLE = "arrow:io:feather:FailedToWriteTable"; - static const char* TABLE_FROM_RECORD_BATCH = "arrow:table:FromRecordBatch"; - static const char* FEATHER_FAILED_TO_CREATE_READER = "arrow:io:feather:FailedToCreateReader"; - static const char* FEATHER_VERSION_2 = "arrow:io:feather:FeatherVersion2"; - static const char* FEATHER_VERSION_UNKNOWN = "arrow:io:feather:FeatherVersionUnknown"; - static const char* FEATHER_FAILED_TO_READ_TABLE = "arrow:io:feather:FailedToReadTable"; - static const char* FEATHER_FAILED_TO_READ_RECORD_BATCH = "arrow:io:feather:FailedToReadRecordBatch"; - static const char* CHUNKED_ARRAY_MAKE_FAILED = "arrow:chunkedarray:MakeFailed"; - static const char* CHUNKED_ARRAY_NUMERIC_INDEX_WITH_EMPTY_CHUNKED_ARRAY = "arrow:chunkedarray:NumericIndexWithEmptyChunkedArray"; - static const char* CHUNKED_ARRAY_INVALID_NUMERIC_CHUNK_INDEX = "arrow:chunkedarray:InvalidNumericChunkIndex"; - static const char* STRUCT_ARRAY_MAKE_FAILED = "arrow:array:StructArrayMakeFailed"; - static const char* LIST_ARRAY_FROM_ARRAYS_FAILED = "arrow:array:ListArrayFromArraysFailed"; - static const char* INDEX_EMPTY_CONTAINER = "arrow:index:EmptyContainer"; - static const char* INDEX_OUT_OF_RANGE = "arrow:index:OutOfRange"; - static const char* BUFFER_VIEW_OR_COPY_FAILED = "arrow:buffer:ViewOrCopyFailed"; - static const char* ARRAY_PRETTY_PRINT_FAILED = "arrow:array:PrettyPrintFailed"; - static const char* TABULAR_GET_ROW_AS_STRING_FAILED = "arrow:tabular:GetRowAsStringFailed"; - static const char* ARRAY_VALIDATE_MINIMAL_FAILED = "arrow:array:ValidateMinimalFailed"; - static const char* ARRAY_VALIDATE_FULL_FAILED = "arrow:array:ValidateFullFailed"; - static const char* ARRAY_VALIDATE_UNSUPPORTED_ENUM = "arrow:array:ValidateUnsupportedEnum"; - static const char* ARRAY_SLICE_NON_POSITIVE_OFFSET = "arrow:array:slice:NonPositiveOffset"; - static const char* ARRAY_SLICE_NEGATIVE_LENGTH = "arrow:array:slice:NegativeLength"; - static const char* ARRAY_SLICE_FAILED_TO_CREATE_ARRAY_PROXY = "arrow:array:slice:FailedToCreateArrayProxy"; +// TODO: Make Error ID Enum class to avoid defining static constexpr +static const char* APPEND_VALUES_ERROR_ID = + "arrow:matlab:proxy:make:FailedToAppendValues"; +static const char* BUILD_ARRAY_ERROR_ID = "arrow:matlab:proxy:make:FailedToAppendValues"; +static const char* BITPACK_VALIDITY_BITMAP_ERROR_ID = + "arrow:matlab:proxy:make:FailedToBitPackValidityBitmap"; +static const char* UNKNOWN_PROXY_ERROR_ID = "arrow:matlab:proxy:UnknownProxy"; +static const char* SCHEMA_BUILDER_FINISH_ERROR_ID = + "arrow:matlab:tabular:proxy:SchemaBuilderAddFields"; +static const char* SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID = + "arrow:matlab:tabular:proxy:SchemaBuilderFinish"; +static const char* UNICODE_CONVERSION_ERROR_ID = "arrow:matlab:unicode:UnicodeConversion"; +static const char* STRING_BUILDER_APPEND_FAILED = + "arrow:matlab:array:string:StringBuilderAppendFailed"; +static const char* STRING_BUILDER_FINISH_FAILED = + "arrow:matlab:array:string:StringBuilderFinishFailed"; +static const char* UNKNOWN_TIME_UNIT_ERROR_ID = "arrow:matlab:UnknownTimeUnit"; +static const char* INVALID_TIME_UNIT = "arrow:type:InvalidTimeUnit"; +static const char* FIELD_FAILED_TO_CREATE_TYPE_PROXY = + "arrow:field:FailedToCreateTypeProxy"; +static const char* ARRAY_FAILED_TO_CREATE_TYPE_PROXY = + "arrow:array:FailedToCreateTypeProxy"; +static const char* LIST_TYPE_FAILED_TO_CREATE_VALUE_TYPE_PROXY = + "arrow:type:list:FailedToCreateValueTypeProxy"; +static const char* ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME = + "arrow:tabular:schema:AmbiguousFieldName"; +static const char* UNKNOWN_PROXY_FOR_ARRAY_TYPE = "arrow:array:UnknownProxyForArrayType"; +static const char* RECORD_BATCH_NUMERIC_INDEX_WITH_EMPTY_RECORD_BATCH = + "arrow:tabular:recordbatch:NumericIndexWithEmptyRecordBatch"; +static const char* RECORD_BATCH_INVALID_NUMERIC_COLUMN_INDEX = + "arrow:tabular:recordbatch:InvalidNumericColumnIndex"; +static const char* TABLE_NUMERIC_INDEX_WITH_EMPTY_TABLE = + "arrow:tabular:table:NumericIndexWithEmptyTable"; +static const char* TABLE_INVALID_NUMERIC_COLUMN_INDEX = + "arrow:tabular:table:InvalidNumericColumnIndex"; +static const char* FAILED_TO_OPEN_FILE_FOR_WRITE = "arrow:io:FailedToOpenFileForWrite"; +static const char* FAILED_TO_OPEN_FILE_FOR_READ = "arrow:io:FailedToOpenFileForRead"; +static const char* CSV_FAILED_TO_WRITE_TABLE = "arrow:io:csv:FailedToWriteTable"; +static const char* CSV_FAILED_TO_CREATE_TABLE_READER = + "arrow:io:csv:FailedToCreateTableReader"; +static const char* CSV_FAILED_TO_READ_TABLE = "arrow:io:csv:FailedToReadTable"; +static const char* FEATHER_FAILED_TO_WRITE_TABLE = "arrow:io:feather:FailedToWriteTable"; +static const char* TABLE_FROM_RECORD_BATCH = "arrow:table:FromRecordBatch"; +static const char* FEATHER_FAILED_TO_CREATE_READER = + "arrow:io:feather:FailedToCreateReader"; +static const char* FEATHER_VERSION_2 = "arrow:io:feather:FeatherVersion2"; +static const char* FEATHER_VERSION_UNKNOWN = "arrow:io:feather:FeatherVersionUnknown"; +static const char* FEATHER_FAILED_TO_READ_TABLE = "arrow:io:feather:FailedToReadTable"; +static const char* FEATHER_FAILED_TO_READ_RECORD_BATCH = + "arrow:io:feather:FailedToReadRecordBatch"; +static const char* CHUNKED_ARRAY_MAKE_FAILED = "arrow:chunkedarray:MakeFailed"; +static const char* CHUNKED_ARRAY_NUMERIC_INDEX_WITH_EMPTY_CHUNKED_ARRAY = + "arrow:chunkedarray:NumericIndexWithEmptyChunkedArray"; +static const char* CHUNKED_ARRAY_INVALID_NUMERIC_CHUNK_INDEX = + "arrow:chunkedarray:InvalidNumericChunkIndex"; +static const char* STRUCT_ARRAY_MAKE_FAILED = "arrow:array:StructArrayMakeFailed"; +static const char* LIST_ARRAY_FROM_ARRAYS_FAILED = + "arrow:array:ListArrayFromArraysFailed"; +static const char* INDEX_EMPTY_CONTAINER = "arrow:index:EmptyContainer"; +static const char* INDEX_OUT_OF_RANGE = "arrow:index:OutOfRange"; +static const char* BUFFER_VIEW_OR_COPY_FAILED = "arrow:buffer:ViewOrCopyFailed"; +static const char* ARRAY_PRETTY_PRINT_FAILED = "arrow:array:PrettyPrintFailed"; +static const char* TABULAR_GET_ROW_AS_STRING_FAILED = + "arrow:tabular:GetRowAsStringFailed"; +static const char* ARRAY_VALIDATE_MINIMAL_FAILED = "arrow:array:ValidateMinimalFailed"; +static const char* ARRAY_VALIDATE_FULL_FAILED = "arrow:array:ValidateFullFailed"; +static const char* ARRAY_VALIDATE_UNSUPPORTED_ENUM = + "arrow:array:ValidateUnsupportedEnum"; +static const char* ARRAY_SLICE_NON_POSITIVE_OFFSET = + "arrow:array:slice:NonPositiveOffset"; +static const char* ARRAY_SLICE_NEGATIVE_LENGTH = "arrow:array:slice:NegativeLength"; +static const char* ARRAY_SLICE_FAILED_TO_CREATE_ARRAY_PROXY = + "arrow:array:slice:FailedToCreateArrayProxy"; -} +} // namespace arrow::matlab::error diff --git a/matlab/src/cpp/arrow/matlab/index/validate.cc b/matlab/src/cpp/arrow/matlab/index/validate.cc index 84e8e424e171f..49ccdbc78fc1a 100644 --- a/matlab/src/cpp/arrow/matlab/index/validate.cc +++ b/matlab/src/cpp/arrow/matlab/index/validate.cc @@ -21,52 +21,54 @@ namespace arrow::matlab::index { - namespace { - std::string makeEmptyContainerErrorMessage() { - return "Numeric indexing using the field method is not supported for objects with zero fields."; - } +namespace { +std::string makeEmptyContainerErrorMessage() { + return "Numeric indexing using the field method is not supported for objects with zero " + "fields."; +} - std::string makeIndexOutOfRangeErrorMessage(const int32_t matlab_index, const int32_t num_fields) { - std::stringstream error_message_stream; - error_message_stream << "Invalid field index: "; - // matlab uses 1-based indexing - error_message_stream << matlab_index; - error_message_stream << ". Field index must be between 1 and the number of fields ("; - error_message_stream << num_fields; - error_message_stream << ")."; - return error_message_stream.str(); - } - } // anonymous namespace +std::string makeIndexOutOfRangeErrorMessage(const int32_t matlab_index, + const int32_t num_fields) { + std::stringstream error_message_stream; + error_message_stream << "Invalid field index: "; + // matlab uses 1-based indexing + error_message_stream << matlab_index; + error_message_stream << ". Field index must be between 1 and the number of fields ("; + error_message_stream << num_fields; + error_message_stream << ")."; + return error_message_stream.str(); +} +} // anonymous namespace - arrow::Status validateNonEmptyContainer(const int32_t num_fields) { - if (num_fields == 0) { - const auto msg = makeEmptyContainerErrorMessage(); - return arrow::Status::Invalid(std::move(msg)); - } - return arrow::Status::OK(); - } +arrow::Status validateNonEmptyContainer(const int32_t num_fields) { + if (num_fields == 0) { + const auto msg = makeEmptyContainerErrorMessage(); + return arrow::Status::Invalid(std::move(msg)); + } + return arrow::Status::OK(); +} - arrow::Status validateInRange(const int32_t matlab_index, const int32_t num_fields) { - if (matlab_index < 1 || matlab_index > num_fields) { - const auto msg = makeIndexOutOfRangeErrorMessage(matlab_index, num_fields); - return arrow::Status::Invalid(std::move(msg)); - } - return arrow::Status::OK(); - } +arrow::Status validateInRange(const int32_t matlab_index, const int32_t num_fields) { + if (matlab_index < 1 || matlab_index > num_fields) { + const auto msg = makeIndexOutOfRangeErrorMessage(matlab_index, num_fields); + return arrow::Status::Invalid(std::move(msg)); + } + return arrow::Status::OK(); +} - arrow::Status validateSliceOffset(const int64_t matlab_offset) { - if (matlab_offset < 1) { - const std::string msg = "Slice offset must be positive"; - return arrow::Status::Invalid(std::move(msg)); - } - return arrow::Status::OK(); - } +arrow::Status validateSliceOffset(const int64_t matlab_offset) { + if (matlab_offset < 1) { + const std::string msg = "Slice offset must be positive"; + return arrow::Status::Invalid(std::move(msg)); + } + return arrow::Status::OK(); +} - arrow::Status validateSliceLength(const int64_t length) { - if (length < 0) { - const std::string msg = "Slice length must be nonnegative"; - return arrow::Status::Invalid(std::move(msg)); - } - return arrow::Status::OK(); - } -} \ No newline at end of file +arrow::Status validateSliceLength(const int64_t length) { + if (length < 0) { + const std::string msg = "Slice length must be nonnegative"; + return arrow::Status::Invalid(std::move(msg)); + } + return arrow::Status::OK(); +} +} // namespace arrow::matlab::index \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/index/validate.h b/matlab/src/cpp/arrow/matlab/index/validate.h index 2fa88ef8f1b5a..0a1ebf972676d 100644 --- a/matlab/src/cpp/arrow/matlab/index/validate.h +++ b/matlab/src/cpp/arrow/matlab/index/validate.h @@ -21,9 +21,9 @@ namespace arrow::matlab::index { - arrow::Status validateNonEmptyContainer(const int32_t num_fields); - arrow::Status validateInRange(const int32_t matlab_index, const int32_t num_fields); - arrow::Status validateSliceOffset(const int64_t matlab_offset); - arrow::Status validateSliceLength(const int64_t length); +arrow::Status validateNonEmptyContainer(const int32_t num_fields); +arrow::Status validateInRange(const int32_t matlab_index, const int32_t num_fields); +arrow::Status validateSliceOffset(const int64_t matlab_offset); +arrow::Status validateSliceLength(const int64_t length); -} \ No newline at end of file +} // namespace arrow::matlab::index \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.cc b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.cc index ab9935ce145a8..f2b4aa7c98760 100644 --- a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.cc +++ b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.cc @@ -24,70 +24,79 @@ #include "arrow/result.h" +#include "arrow/csv/reader.h" #include "arrow/io/file.h" #include "arrow/io/interfaces.h" -#include "arrow/csv/reader.h" #include "arrow/table.h" namespace arrow::matlab::io::csv::proxy { - TableReader::TableReader(const std::string& filename) : filename{filename} { - REGISTER_METHOD(TableReader, read); - REGISTER_METHOD(TableReader, getFilename); - } - - libmexclass::proxy::MakeResult TableReader::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using TableReaderProxy = arrow::matlab::io::csv::proxy::TableReader; +TableReader::TableReader(const std::string& filename) : filename{filename} { + REGISTER_METHOD(TableReader, read); + REGISTER_METHOD(TableReader, getFilename); +} - mda::StructArray args = constructor_arguments[0]; - const mda::StringArray filename_utf16_mda = args[0]["Filename"]; - const auto filename_utf16 = std::u16string(filename_utf16_mda[0]); - MATLAB_ASSIGN_OR_ERROR(const auto filename, arrow::util::UTF16StringToUTF8(filename_utf16), error::UNICODE_CONVERSION_ERROR_ID); +libmexclass::proxy::MakeResult TableReader::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using TableReaderProxy = arrow::matlab::io::csv::proxy::TableReader; - return std::make_shared(filename); - } + mda::StructArray args = constructor_arguments[0]; + const mda::StringArray filename_utf16_mda = args[0]["Filename"]; + const auto filename_utf16 = std::u16string(filename_utf16_mda[0]); + MATLAB_ASSIGN_OR_ERROR(const auto filename, + arrow::util::UTF16StringToUTF8(filename_utf16), + error::UNICODE_CONVERSION_ERROR_ID); - void TableReader::read(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - namespace csv = ::arrow::csv; - using TableProxy = arrow::matlab::tabular::proxy::Table; + return std::make_shared(filename); +} - mda::ArrayFactory factory; +void TableReader::read(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + namespace csv = ::arrow::csv; + using TableProxy = arrow::matlab::tabular::proxy::Table; - // Create a file input stream. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto source, arrow::io::ReadableFile::Open(filename, arrow::default_memory_pool()), context, error::FAILED_TO_OPEN_FILE_FOR_READ); + mda::ArrayFactory factory; - const ::arrow::io::IOContext io_context; - const auto read_options = csv::ReadOptions::Defaults(); - const auto parse_options = csv::ParseOptions::Defaults(); - const auto convert_options = csv::ConvertOptions::Defaults(); + // Create a file input stream. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto source, arrow::io::ReadableFile::Open(filename, arrow::default_memory_pool()), + context, error::FAILED_TO_OPEN_FILE_FOR_READ); - // Create a TableReader from the file input stream. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto table_reader, - csv::TableReader::Make(io_context, source, read_options, parse_options, convert_options), - context, - error::CSV_FAILED_TO_CREATE_TABLE_READER); + const ::arrow::io::IOContext io_context; + const auto read_options = csv::ReadOptions::Defaults(); + const auto parse_options = csv::ParseOptions::Defaults(); + const auto convert_options = csv::ConvertOptions::Defaults(); - // Read a Table from the file. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto table, table_reader->Read(), context, error::CSV_FAILED_TO_READ_TABLE); + // Create a TableReader from the file input stream. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto table_reader, + csv::TableReader::Make(io_context, source, read_options, parse_options, + convert_options), + context, error::CSV_FAILED_TO_CREATE_TABLE_READER); - auto table_proxy = std::make_shared(table); - const auto table_proxy_id = ProxyManager::manageProxy(table_proxy); + // Read a Table from the file. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto table, table_reader->Read(), context, + error::CSV_FAILED_TO_READ_TABLE); - const auto table_proxy_id_mda = factory.createScalar(table_proxy_id); + auto table_proxy = std::make_shared(table); + const auto table_proxy_id = ProxyManager::manageProxy(table_proxy); - context.outputs[0] = table_proxy_id_mda; - } + const auto table_proxy_id_mda = factory.createScalar(table_proxy_id); - void TableReader::getFilename(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; + context.outputs[0] = table_proxy_id_mda; +} - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto filename_utf16, arrow::util::UTF8StringToUTF16(filename), context, error::UNICODE_CONVERSION_ERROR_ID); - auto filename_utf16_mda = factory.createScalar(filename_utf16); - context.outputs[0] = filename_utf16_mda; - } +void TableReader::getFilename(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto filename_utf16, + arrow::util::UTF8StringToUTF16(filename), context, + error::UNICODE_CONVERSION_ERROR_ID); + auto filename_utf16_mda = factory.createScalar(filename_utf16); + context.outputs[0] = filename_utf16_mda; } + +} // namespace arrow::matlab::io::csv::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.h b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.h index d5dfce50e4096..73af2e79ce167 100644 --- a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.h +++ b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_reader.h @@ -21,18 +21,19 @@ namespace arrow::matlab::io::csv::proxy { - class TableReader : public libmexclass::proxy::Proxy { - public: - TableReader(const std::string& filename); - ~TableReader() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); +class TableReader : public libmexclass::proxy::Proxy { + public: + TableReader(const std::string& filename); + ~TableReader() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void read(libmexclass::proxy::method::Context& context); - void getFilename(libmexclass::proxy::method::Context& context); + protected: + void read(libmexclass::proxy::method::Context& context); + void getFilename(libmexclass::proxy::method::Context& context); - private: - const std::string filename; - }; + private: + const std::string filename; +}; -} +} // namespace arrow::matlab::io::csv::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.cc b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.cc index b24bd81b06681..6129d42f66d60 100644 --- a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.cc +++ b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.cc @@ -16,71 +16,69 @@ // under the License. #include "arrow/matlab/io/csv/proxy/table_writer.h" -#include "arrow/matlab/tabular/proxy/table.h" #include "arrow/matlab/error/error.h" +#include "arrow/matlab/tabular/proxy/table.h" #include "arrow/result.h" #include "arrow/table.h" #include "arrow/util/utf8.h" -#include "arrow/io/file.h" -#include "arrow/csv/writer.h" #include "arrow/csv/options.h" +#include "arrow/csv/writer.h" +#include "arrow/io/file.h" #include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::io::csv::proxy { - TableWriter::TableWriter(const std::string& filename) : filename{filename} { - REGISTER_METHOD(TableWriter, getFilename); - REGISTER_METHOD(TableWriter, write); - } +TableWriter::TableWriter(const std::string& filename) : filename{filename} { + REGISTER_METHOD(TableWriter, getFilename); + REGISTER_METHOD(TableWriter, write); +} - libmexclass::proxy::MakeResult TableWriter::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - mda::StructArray opts = constructor_arguments[0]; - const mda::StringArray filename_mda = opts[0]["Filename"]; - using TableWriterProxy = ::arrow::matlab::io::csv::proxy::TableWriter; +libmexclass::proxy::MakeResult TableWriter::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + mda::StructArray opts = constructor_arguments[0]; + const mda::StringArray filename_mda = opts[0]["Filename"]; + using TableWriterProxy = ::arrow::matlab::io::csv::proxy::TableWriter; - const auto filename_utf16 = std::u16string(filename_mda[0]); - MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8, - arrow::util::UTF16StringToUTF8(filename_utf16), - error::UNICODE_CONVERSION_ERROR_ID); + const auto filename_utf16 = std::u16string(filename_mda[0]); + MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8, + arrow::util::UTF16StringToUTF8(filename_utf16), + error::UNICODE_CONVERSION_ERROR_ID); - return std::make_shared(filename_utf8); - } + return std::make_shared(filename_utf8); +} - void TableWriter::getFilename(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_filename, - arrow::util::UTF8StringToUTF16(filename), - context, - error::UNICODE_CONVERSION_ERROR_ID); - mda::ArrayFactory factory; - auto str_mda = factory.createScalar(utf16_filename); - context.outputs[0] = str_mda; - } +void TableWriter::getFilename(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_filename, + arrow::util::UTF8StringToUTF16(filename), context, + error::UNICODE_CONVERSION_ERROR_ID); + mda::ArrayFactory factory; + auto str_mda = factory.createScalar(utf16_filename); + context.outputs[0] = str_mda; +} - void TableWriter::write(libmexclass::proxy::method::Context& context) { - namespace csv = ::arrow::csv; - namespace mda = ::matlab::data; - using TableProxy = ::arrow::matlab::tabular::proxy::Table; +void TableWriter::write(libmexclass::proxy::method::Context& context) { + namespace csv = ::arrow::csv; + namespace mda = ::matlab::data; + using TableProxy = ::arrow::matlab::tabular::proxy::Table; - mda::StructArray opts = context.inputs[0]; - const mda::TypedArray table_proxy_id_mda = opts[0]["TableProxyID"]; - const uint64_t table_proxy_id = table_proxy_id_mda[0]; + mda::StructArray opts = context.inputs[0]; + const mda::TypedArray table_proxy_id_mda = opts[0]["TableProxyID"]; + const uint64_t table_proxy_id = table_proxy_id_mda[0]; - auto proxy = libmexclass::proxy::ProxyManager::getProxy(table_proxy_id); - auto table_proxy = std::static_pointer_cast(proxy); - auto table = table_proxy->unwrap(); + auto proxy = libmexclass::proxy::ProxyManager::getProxy(table_proxy_id); + auto table_proxy = std::static_pointer_cast(proxy); + auto table = table_proxy->unwrap(); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto output_stream, - arrow::io::FileOutputStream::Open(filename), - context, - error::FAILED_TO_OPEN_FILE_FOR_WRITE); - const auto options = csv::WriteOptions::Defaults(); - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(csv::WriteCSV(*table, options, output_stream.get()), - context, - error::CSV_FAILED_TO_WRITE_TABLE); - } + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto output_stream, + arrow::io::FileOutputStream::Open(filename), + context, error::FAILED_TO_OPEN_FILE_FOR_WRITE); + const auto options = csv::WriteOptions::Defaults(); + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(csv::WriteCSV(*table, options, output_stream.get()), + context, error::CSV_FAILED_TO_WRITE_TABLE); } +} // namespace arrow::matlab::io::csv::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.h b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.h index b9916bd9bdc22..caf1999db2653 100644 --- a/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.h +++ b/matlab/src/cpp/arrow/matlab/io/csv/proxy/table_writer.h @@ -21,18 +21,19 @@ namespace arrow::matlab::io::csv::proxy { - class TableWriter : public libmexclass::proxy::Proxy { - public: - TableWriter(const std::string& filename); - ~TableWriter() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); +class TableWriter : public libmexclass::proxy::Proxy { + public: + TableWriter(const std::string& filename); + ~TableWriter() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void getFilename(libmexclass::proxy::method::Context& context); - void write(libmexclass::proxy::method::Context& context); + protected: + void getFilename(libmexclass::proxy::method::Context& context); + void write(libmexclass::proxy::method::Context& context); - private: - const std::string filename; - }; + private: + const std::string filename; +}; -} +} // namespace arrow::matlab::io::csv::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.cc b/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.cc index db33b410f7b92..7afe47bd7c295 100644 --- a/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.cc +++ b/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.cc @@ -30,67 +30,83 @@ namespace arrow::matlab::io::feather::proxy { - Reader::Reader(const std::string& filename) : filename{filename} { - REGISTER_METHOD(Reader, read); - REGISTER_METHOD(Reader, getFilename); - } - - libmexclass::proxy::MakeResult Reader::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using ReaderProxy = arrow::matlab::io::feather::proxy::Reader; - - mda::StructArray args = constructor_arguments[0]; - const mda::StringArray filename_utf16_mda = args[0]["Filename"]; - const auto filename_utf16 = std::u16string(filename_utf16_mda[0]); - MATLAB_ASSIGN_OR_ERROR(const auto filename, arrow::util::UTF16StringToUTF8(filename_utf16), error::UNICODE_CONVERSION_ERROR_ID); - - return std::make_shared(filename); - } - - void Reader::read(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch; - - mda::ArrayFactory factory; - - // Create a file input stream. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto source, arrow::io::ReadableFile::Open(filename, arrow::default_memory_pool()), context, error::FAILED_TO_OPEN_FILE_FOR_READ); - - // Create a Reader from the file input stream. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto reader, arrow::ipc::feather::Reader::Open(source), context, error::FEATHER_FAILED_TO_CREATE_READER); - - // Error if not Feather V1. - const auto version = reader->version(); - if (version == ipc::feather::kFeatherV2Version) { - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(Status::NotImplemented("Support for Feather V2 has not been implemented."), context, error::FEATHER_VERSION_2); - } else if (version != ipc::feather::kFeatherV1Version) { - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(Status::Invalid("Unknown Feather format version."), context, error::FEATHER_VERSION_UNKNOWN); - } - - // Read a Table from the file. - std::shared_ptr table = nullptr; - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(reader->Read(&table), context, error::FEATHER_FAILED_TO_READ_TABLE); - - // Combine all the chunks of the Table into a single RecordBatch. - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto record_batch, table->CombineChunksToBatch(arrow::default_memory_pool()), context, error::FEATHER_FAILED_TO_READ_RECORD_BATCH); +Reader::Reader(const std::string& filename) : filename{filename} { + REGISTER_METHOD(Reader, read); + REGISTER_METHOD(Reader, getFilename); +} - // Create a Proxy from the first RecordBatch. - auto record_batch_proxy = std::make_shared(record_batch); - const auto record_batch_proxy_id = ProxyManager::manageProxy(record_batch_proxy); +libmexclass::proxy::MakeResult Reader::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using ReaderProxy = arrow::matlab::io::feather::proxy::Reader; - const auto record_batch_proxy_id_mda = factory.createScalar(record_batch_proxy_id); + mda::StructArray args = constructor_arguments[0]; + const mda::StringArray filename_utf16_mda = args[0]["Filename"]; + const auto filename_utf16 = std::u16string(filename_utf16_mda[0]); + MATLAB_ASSIGN_OR_ERROR(const auto filename, + arrow::util::UTF16StringToUTF8(filename_utf16), + error::UNICODE_CONVERSION_ERROR_ID); - context.outputs[0] = record_batch_proxy_id_mda; - } + return std::make_shared(filename); +} - void Reader::getFilename(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void Reader::read(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch; + + mda::ArrayFactory factory; + + // Create a file input stream. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto source, arrow::io::ReadableFile::Open(filename, arrow::default_memory_pool()), + context, error::FAILED_TO_OPEN_FILE_FOR_READ); + + // Create a Reader from the file input stream. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto reader, + arrow::ipc::feather::Reader::Open(source), context, + error::FEATHER_FAILED_TO_CREATE_READER); + + // Error if not Feather V1. + const auto version = reader->version(); + if (version == ipc::feather::kFeatherV2Version) { + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + Status::NotImplemented("Support for Feather V2 has not been implemented."), + context, error::FEATHER_VERSION_2); + } else if (version != ipc::feather::kFeatherV1Version) { + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + Status::Invalid("Unknown Feather format version."), context, + error::FEATHER_VERSION_UNKNOWN); + } + + // Read a Table from the file. + std::shared_ptr table = nullptr; + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(reader->Read(&table), context, + error::FEATHER_FAILED_TO_READ_TABLE); + + // Combine all the chunks of the Table into a single RecordBatch. + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + const auto record_batch, table->CombineChunksToBatch(arrow::default_memory_pool()), + context, error::FEATHER_FAILED_TO_READ_RECORD_BATCH); + + // Create a Proxy from the first RecordBatch. + auto record_batch_proxy = std::make_shared(record_batch); + const auto record_batch_proxy_id = ProxyManager::manageProxy(record_batch_proxy); + + const auto record_batch_proxy_id_mda = factory.createScalar(record_batch_proxy_id); + + context.outputs[0] = record_batch_proxy_id_mda; +} - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto filename_utf16, arrow::util::UTF8StringToUTF16(filename), context, error::UNICODE_CONVERSION_ERROR_ID); - auto filename_utf16_mda = factory.createScalar(filename_utf16); - context.outputs[0] = filename_utf16_mda; - } +void Reader::getFilename(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto filename_utf16, + arrow::util::UTF8StringToUTF16(filename), context, + error::UNICODE_CONVERSION_ERROR_ID); + auto filename_utf16_mda = factory.createScalar(filename_utf16); + context.outputs[0] = filename_utf16_mda; } + +} // namespace arrow::matlab::io::feather::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.h b/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.h index fb6c06de8638d..38432dcf44c3f 100644 --- a/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.h +++ b/matlab/src/cpp/arrow/matlab/io/feather/proxy/reader.h @@ -21,19 +21,20 @@ namespace arrow::matlab::io::feather::proxy { - class Reader : public libmexclass::proxy::Proxy { - public: - Reader(const std::string& filename); +class Reader : public libmexclass::proxy::Proxy { + public: + Reader(const std::string& filename); - virtual ~Reader() {} + virtual ~Reader() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void read(libmexclass::proxy::method::Context& context); - void getFilename(libmexclass::proxy::method::Context& context); + protected: + void read(libmexclass::proxy::method::Context& context); + void getFilename(libmexclass::proxy::method::Context& context); - const std::string filename; - }; + const std::string filename; +}; -} +} // namespace arrow::matlab::io::feather::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.cc b/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.cc index c71c9ae7a514e..e5c3fb398ebed 100644 --- a/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.cc +++ b/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.cc @@ -16,8 +16,8 @@ // under the License. #include "arrow/matlab/io/feather/proxy/writer.h" -#include "arrow/matlab/tabular/proxy/record_batch.h" #include "arrow/matlab/error/error.h" +#include "arrow/matlab/tabular/proxy/record_batch.h" #include "arrow/result.h" #include "arrow/table.h" @@ -30,61 +30,62 @@ namespace arrow::matlab::io::feather::proxy { - Writer::Writer(const std::string& filename) : filename{filename} { - REGISTER_METHOD(Writer, getFilename); - REGISTER_METHOD(Writer, write); - } - - libmexclass::proxy::MakeResult Writer::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - mda::StructArray opts = constructor_arguments[0]; - const mda::StringArray filename_mda = opts[0]["Filename"]; - - const auto filename_utf16 = std::u16string(filename_mda[0]); - MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8, - arrow::util::UTF16StringToUTF8(filename_utf16), - error::UNICODE_CONVERSION_ERROR_ID); - - return std::make_shared(filename_utf8); - } - - void Writer::getFilename(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_filename, - arrow::util::UTF8StringToUTF16(filename), - context, - error::UNICODE_CONVERSION_ERROR_ID); - mda::ArrayFactory factory; - auto str_mda = factory.createScalar(utf16_filename); - context.outputs[0] = str_mda; - } - - void Writer::write(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::StructArray opts = context.inputs[0]; - const mda::TypedArray record_batch_proxy_id_mda = opts[0]["RecordBatchProxyID"]; - const uint64_t record_batch_proxy_id = record_batch_proxy_id_mda[0]; - - auto proxy = libmexclass::proxy::ProxyManager::getProxy(record_batch_proxy_id); - auto record_batch_proxy = std::static_pointer_cast(proxy); - auto record_batch = record_batch_proxy->unwrap(); - - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto table, - arrow::Table::FromRecordBatches({record_batch}), - context, - error::TABLE_FROM_RECORD_BATCH); - - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(std::shared_ptr output_stream, - arrow::io::FileOutputStream::Open(filename), - context, - error::FAILED_TO_OPEN_FILE_FOR_WRITE); - - // Specify the feather file format version as V1 - arrow::ipc::feather::WriteProperties write_props; - write_props.version = arrow::ipc::feather::kFeatherV1Version; - - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(ipc::feather::WriteTable(*table, output_stream.get(), write_props), - context, - error::FEATHER_FAILED_TO_WRITE_TABLE); - } +Writer::Writer(const std::string& filename) : filename{filename} { + REGISTER_METHOD(Writer, getFilename); + REGISTER_METHOD(Writer, write); +} + +libmexclass::proxy::MakeResult Writer::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + mda::StructArray opts = constructor_arguments[0]; + const mda::StringArray filename_mda = opts[0]["Filename"]; + + const auto filename_utf16 = std::u16string(filename_mda[0]); + MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8, + arrow::util::UTF16StringToUTF8(filename_utf16), + error::UNICODE_CONVERSION_ERROR_ID); + + return std::make_shared(filename_utf8); +} + +void Writer::getFilename(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_filename, + arrow::util::UTF8StringToUTF16(filename), context, + error::UNICODE_CONVERSION_ERROR_ID); + mda::ArrayFactory factory; + auto str_mda = factory.createScalar(utf16_filename); + context.outputs[0] = str_mda; +} + +void Writer::write(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::StructArray opts = context.inputs[0]; + const mda::TypedArray record_batch_proxy_id_mda = + opts[0]["RecordBatchProxyID"]; + const uint64_t record_batch_proxy_id = record_batch_proxy_id_mda[0]; + + auto proxy = libmexclass::proxy::ProxyManager::getProxy(record_batch_proxy_id); + auto record_batch_proxy = + std::static_pointer_cast(proxy); + auto record_batch = record_batch_proxy->unwrap(); + + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto table, + arrow::Table::FromRecordBatches({record_batch}), + context, error::TABLE_FROM_RECORD_BATCH); + + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + std::shared_ptr output_stream, + arrow::io::FileOutputStream::Open(filename), context, + error::FAILED_TO_OPEN_FILE_FOR_WRITE); + + // Specify the feather file format version as V1 + arrow::ipc::feather::WriteProperties write_props; + write_props.version = arrow::ipc::feather::kFeatherV1Version; + + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + ipc::feather::WriteTable(*table, output_stream.get(), write_props), context, + error::FEATHER_FAILED_TO_WRITE_TABLE); } +} // namespace arrow::matlab::io::feather::proxy diff --git a/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.h b/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.h index 21dc70f432a55..bd6d69cd91902 100644 --- a/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.h +++ b/matlab/src/cpp/arrow/matlab/io/feather/proxy/writer.h @@ -23,19 +23,20 @@ namespace arrow::matlab::io::feather::proxy { - class Writer : public libmexclass::proxy::Proxy { - public: - Writer(const std::string& filename); - - ~Writer() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - protected: - void getFilename(libmexclass::proxy::method::Context& context); - void write(libmexclass::proxy::method::Context& context); - - private: - const std::string filename; - }; -} +class Writer : public libmexclass::proxy::Proxy { + public: + Writer(const std::string& filename); + + ~Writer() {} + + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); + + protected: + void getFilename(libmexclass::proxy::method::Context& context); + void write(libmexclass::proxy::method::Context& context); + + private: + const std::string filename; +}; +} // namespace arrow::matlab::io::feather::proxy diff --git a/matlab/src/cpp/arrow/matlab/mex/gateway.cc b/matlab/src/cpp/arrow/matlab/mex/gateway.cc index 78ce6e274e918..fedeb7d5973d7 100644 --- a/matlab/src/cpp/arrow/matlab/mex/gateway.cc +++ b/matlab/src/cpp/arrow/matlab/mex/gateway.cc @@ -18,13 +18,14 @@ #include "mex.hpp" #include "mexAdapter.hpp" -#include "libmexclass/mex/gateway.h" +#include "libmexclass/mex/gateway.h" #include "arrow/matlab/proxy/factory.h" class MexFunction : public matlab::mex::Function { - public: - void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) { - libmexclass::mex::gateway(inputs, outputs, getEngine()); - } + public: + void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) { + libmexclass::mex::gateway(inputs, outputs, + getEngine()); + } }; diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc b/matlab/src/cpp/arrow/matlab/proxy/factory.cc index c3b05bec32fda..23492f75deacc 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc @@ -16,89 +16,93 @@ // under the License. #include "arrow/matlab/array/proxy/boolean_array.h" +#include "arrow/matlab/array/proxy/chunked_array.h" +#include "arrow/matlab/array/proxy/list_array.h" #include "arrow/matlab/array/proxy/numeric_array.h" #include "arrow/matlab/array/proxy/string_array.h" -#include "arrow/matlab/array/proxy/timestamp_array.h" +#include "arrow/matlab/array/proxy/struct_array.h" #include "arrow/matlab/array/proxy/time32_array.h" #include "arrow/matlab/array/proxy/time64_array.h" -#include "arrow/matlab/array/proxy/struct_array.h" -#include "arrow/matlab/array/proxy/list_array.h" -#include "arrow/matlab/array/proxy/chunked_array.h" +#include "arrow/matlab/array/proxy/timestamp_array.h" +#include "arrow/matlab/buffer/proxy/buffer.h" +#include "arrow/matlab/error/error.h" +#include "arrow/matlab/io/csv/proxy/table_reader.h" +#include "arrow/matlab/io/csv/proxy/table_writer.h" +#include "arrow/matlab/io/feather/proxy/reader.h" +#include "arrow/matlab/io/feather/proxy/writer.h" #include "arrow/matlab/tabular/proxy/record_batch.h" -#include "arrow/matlab/tabular/proxy/table.h" #include "arrow/matlab/tabular/proxy/schema.h" -#include "arrow/matlab/error/error.h" -#include "arrow/matlab/type/proxy/primitive_ctype.h" -#include "arrow/matlab/type/proxy/string_type.h" -#include "arrow/matlab/type/proxy/timestamp_type.h" +#include "arrow/matlab/tabular/proxy/table.h" #include "arrow/matlab/type/proxy/date32_type.h" #include "arrow/matlab/type/proxy/date64_type.h" +#include "arrow/matlab/type/proxy/field.h" +#include "arrow/matlab/type/proxy/list_type.h" +#include "arrow/matlab/type/proxy/primitive_ctype.h" +#include "arrow/matlab/type/proxy/string_type.h" +#include "arrow/matlab/type/proxy/struct_type.h" #include "arrow/matlab/type/proxy/time32_type.h" #include "arrow/matlab/type/proxy/time64_type.h" -#include "arrow/matlab/type/proxy/struct_type.h" -#include "arrow/matlab/type/proxy/list_type.h" -#include "arrow/matlab/type/proxy/field.h" -#include "arrow/matlab/io/feather/proxy/writer.h" -#include "arrow/matlab/io/feather/proxy/reader.h" -#include "arrow/matlab/io/csv/proxy/table_writer.h" -#include "arrow/matlab/io/csv/proxy/table_reader.h" -#include "arrow/matlab/buffer/proxy/buffer.h" +#include "arrow/matlab/type/proxy/timestamp_type.h" #include "factory.h" namespace arrow::matlab::proxy { -libmexclass::proxy::MakeResult Factory::make_proxy(const ClassName& class_name, const FunctionArguments& constructor_arguments) { - REGISTER_PROXY(arrow.array.proxy.Float32Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Float64Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.UInt8Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.UInt16Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.UInt32Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.UInt64Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Int8Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Int16Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Int32Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Int64Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.BooleanArray , arrow::matlab::array::proxy::BooleanArray); - REGISTER_PROXY(arrow.array.proxy.StringArray , arrow::matlab::array::proxy::StringArray); - REGISTER_PROXY(arrow.array.proxy.StructArray , arrow::matlab::array::proxy::StructArray); - REGISTER_PROXY(arrow.array.proxy.ListArray , arrow::matlab::array::proxy::ListArray); - REGISTER_PROXY(arrow.array.proxy.TimestampArray, arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Time32Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Time64Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Date32Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.Date64Array , arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.ChunkedArray , arrow::matlab::array::proxy::ChunkedArray); - REGISTER_PROXY(arrow.buffer.proxy.Buffer , arrow::matlab::buffer::proxy::Buffer); - REGISTER_PROXY(arrow.tabular.proxy.RecordBatch , arrow::matlab::tabular::proxy::RecordBatch); - REGISTER_PROXY(arrow.tabular.proxy.Table , arrow::matlab::tabular::proxy::Table); - REGISTER_PROXY(arrow.tabular.proxy.Schema , arrow::matlab::tabular::proxy::Schema); - REGISTER_PROXY(arrow.type.proxy.Field , arrow::matlab::type::proxy::Field); - REGISTER_PROXY(arrow.type.proxy.Float32Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.Float64Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.UInt8Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.UInt16Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.UInt32Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.UInt64Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.Int8Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.Int16Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.Int32Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.Int64Type , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.BooleanType , arrow::matlab::type::proxy::PrimitiveCType); - REGISTER_PROXY(arrow.type.proxy.StringType , arrow::matlab::type::proxy::StringType); - REGISTER_PROXY(arrow.type.proxy.TimestampType , arrow::matlab::type::proxy::TimestampType); - REGISTER_PROXY(arrow.type.proxy.Time32Type , arrow::matlab::type::proxy::Time32Type); - REGISTER_PROXY(arrow.type.proxy.Time64Type , arrow::matlab::type::proxy::Time64Type); - REGISTER_PROXY(arrow.type.proxy.Date32Type , arrow::matlab::type::proxy::Date32Type); - REGISTER_PROXY(arrow.type.proxy.Date64Type , arrow::matlab::type::proxy::Date64Type); - REGISTER_PROXY(arrow.type.proxy.StructType , arrow::matlab::type::proxy::StructType); - REGISTER_PROXY(arrow.type.proxy.ListType , arrow::matlab::type::proxy::ListType); - REGISTER_PROXY(arrow.io.feather.proxy.Writer , arrow::matlab::io::feather::proxy::Writer); - REGISTER_PROXY(arrow.io.feather.proxy.Reader , arrow::matlab::io::feather::proxy::Reader); - REGISTER_PROXY(arrow.io.csv.proxy.TableWriter , arrow::matlab::io::csv::proxy::TableWriter); - REGISTER_PROXY(arrow.io.csv.proxy.TableReader , arrow::matlab::io::csv::proxy::TableReader); +libmexclass::proxy::MakeResult Factory::make_proxy( + const ClassName& class_name, const FunctionArguments& constructor_arguments) { + // clang-format off + REGISTER_PROXY(arrow.array.proxy.Float32Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Float64Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.UInt8Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.UInt16Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.UInt32Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.UInt64Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Int8Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Int16Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Int32Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Int64Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.BooleanArray , arrow::matlab::array::proxy::BooleanArray); + REGISTER_PROXY(arrow.array.proxy.StringArray , arrow::matlab::array::proxy::StringArray); + REGISTER_PROXY(arrow.array.proxy.StructArray , arrow::matlab::array::proxy::StructArray); + REGISTER_PROXY(arrow.array.proxy.ListArray , arrow::matlab::array::proxy::ListArray); + REGISTER_PROXY(arrow.array.proxy.TimestampArray, arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Time32Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Time64Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Date32Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.Date64Array , arrow::matlab::array::proxy::NumericArray); + REGISTER_PROXY(arrow.array.proxy.ChunkedArray , arrow::matlab::array::proxy::ChunkedArray); + REGISTER_PROXY(arrow.buffer.proxy.Buffer , arrow::matlab::buffer::proxy::Buffer); + REGISTER_PROXY(arrow.tabular.proxy.RecordBatch , arrow::matlab::tabular::proxy::RecordBatch); + REGISTER_PROXY(arrow.tabular.proxy.Table , arrow::matlab::tabular::proxy::Table); + REGISTER_PROXY(arrow.tabular.proxy.Schema , arrow::matlab::tabular::proxy::Schema); + REGISTER_PROXY(arrow.type.proxy.Field , arrow::matlab::type::proxy::Field); + REGISTER_PROXY(arrow.type.proxy.Float32Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.Float64Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.UInt8Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.UInt16Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.UInt32Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.UInt64Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.Int8Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.Int16Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.Int32Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.Int64Type , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.BooleanType , arrow::matlab::type::proxy::PrimitiveCType); + REGISTER_PROXY(arrow.type.proxy.StringType , arrow::matlab::type::proxy::StringType); + REGISTER_PROXY(arrow.type.proxy.TimestampType , arrow::matlab::type::proxy::TimestampType); + REGISTER_PROXY(arrow.type.proxy.Time32Type , arrow::matlab::type::proxy::Time32Type); + REGISTER_PROXY(arrow.type.proxy.Time64Type , arrow::matlab::type::proxy::Time64Type); + REGISTER_PROXY(arrow.type.proxy.Date32Type , arrow::matlab::type::proxy::Date32Type); + REGISTER_PROXY(arrow.type.proxy.Date64Type , arrow::matlab::type::proxy::Date64Type); + REGISTER_PROXY(arrow.type.proxy.StructType , arrow::matlab::type::proxy::StructType); + REGISTER_PROXY(arrow.type.proxy.ListType , arrow::matlab::type::proxy::ListType); + REGISTER_PROXY(arrow.io.feather.proxy.Writer , arrow::matlab::io::feather::proxy::Writer); + REGISTER_PROXY(arrow.io.feather.proxy.Reader , arrow::matlab::io::feather::proxy::Reader); + REGISTER_PROXY(arrow.io.csv.proxy.TableWriter , arrow::matlab::io::csv::proxy::TableWriter); + REGISTER_PROXY(arrow.io.csv.proxy.TableReader , arrow::matlab::io::csv::proxy::TableReader); + // clang-format on - return libmexclass::error::Error{error::UNKNOWN_PROXY_ERROR_ID, "Did not find matching C++ proxy for " + class_name}; + return libmexclass::error::Error{error::UNKNOWN_PROXY_ERROR_ID, + "Did not find matching C++ proxy for " + class_name}; }; -} +} // namespace arrow::matlab::proxy diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.h b/matlab/src/cpp/arrow/matlab/proxy/factory.h index fd41a1c10aca7..3f77bd7c8c6db 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.h +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.h @@ -24,9 +24,10 @@ namespace arrow::matlab::proxy { using namespace libmexclass::proxy; class Factory : public libmexclass::proxy::Factory { - public: - Factory() { } - virtual libmexclass::proxy::MakeResult make_proxy(const ClassName& class_name, const FunctionArguments& constructor_arguments); + public: + Factory() {} + virtual libmexclass::proxy::MakeResult make_proxy( + const ClassName& class_name, const FunctionArguments& constructor_arguments); }; -} +} // namespace arrow::matlab::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/get_row_as_string.h b/matlab/src/cpp/arrow/matlab/tabular/get_row_as_string.h index aaa0d57b119a3..1a1556ad6d93f 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/get_row_as_string.h +++ b/matlab/src/cpp/arrow/matlab/tabular/get_row_as_string.h @@ -23,55 +23,57 @@ namespace arrow::matlab::tabular { - namespace { - arrow::PrettyPrintOptions make_pretty_print_options() { - auto opts = arrow::PrettyPrintOptions::Defaults(); - opts.skip_new_lines = true; - opts.array_delimiters.open = ""; - opts.array_delimiters.close = ""; - opts.chunked_array_delimiters.open = ""; - opts.chunked_array_delimiters.close = ""; - return opts; - } - } +namespace { +arrow::PrettyPrintOptions make_pretty_print_options() { + auto opts = arrow::PrettyPrintOptions::Defaults(); + opts.skip_new_lines = true; + opts.array_delimiters.open = ""; + opts.array_delimiters.close = ""; + opts.chunked_array_delimiters.open = ""; + opts.chunked_array_delimiters.close = ""; + return opts; +} +} // namespace - template - arrow::Result get_row_as_string(const std::shared_ptr& tabular_object, const int64_t matlab_row_index) { - std::stringstream ss; - const int64_t row_index = matlab_row_index - 1; - if (row_index >= tabular_object->num_rows() || row_index < 0) { - ss << "Invalid Row Index: " << matlab_row_index; - return arrow::Status::Invalid(ss.str()); - } +template +arrow::Result get_row_as_string( + const std::shared_ptr& tabular_object, const int64_t matlab_row_index) { + std::stringstream ss; + const int64_t row_index = matlab_row_index - 1; + if (row_index >= tabular_object->num_rows() || row_index < 0) { + ss << "Invalid Row Index: " << matlab_row_index; + return arrow::Status::Invalid(ss.str()); + } - const auto opts = make_pretty_print_options(); - const auto num_columns = tabular_object->num_columns(); - const auto& columns = tabular_object->columns(); + const auto opts = make_pretty_print_options(); + const auto num_columns = tabular_object->num_columns(); + const auto& columns = tabular_object->columns(); - for (int32_t i = 0; i < num_columns; ++i) { - const auto& column = columns[i]; - const auto type_id = column->type()->id(); - if (arrow::is_primitive(type_id) || arrow::is_string(type_id)) { - auto slice = column->Slice(row_index, 1); - ARROW_RETURN_NOT_OK(arrow::PrettyPrint(*slice, opts, &ss)); - } else if (type_id == arrow::Type::type::STRUCT) { - // Use as a placeholder since we don't have a good - // way to display StructArray elements horizontally on screen. - ss << ""; - } else if (type_id == arrow::Type::type::LIST) { - // Use as a placeholder since we don't have a good - // way to display ListArray elements horizontally on screen. - ss << ""; - } else { - return arrow::Status::NotImplemented("Datatype " + column->type()->ToString() + "is not currently supported for display."); - } + for (int32_t i = 0; i < num_columns; ++i) { + const auto& column = columns[i]; + const auto type_id = column->type()->id(); + if (arrow::is_primitive(type_id) || arrow::is_string(type_id)) { + auto slice = column->Slice(row_index, 1); + ARROW_RETURN_NOT_OK(arrow::PrettyPrint(*slice, opts, &ss)); + } else if (type_id == arrow::Type::type::STRUCT) { + // Use as a placeholder since we don't have a good + // way to display StructArray elements horizontally on screen. + ss << ""; + } else if (type_id == arrow::Type::type::LIST) { + // Use as a placeholder since we don't have a good + // way to display ListArray elements horizontally on screen. + ss << ""; + } else { + return arrow::Status::NotImplemented("Datatype " + column->type()->ToString() + + "is not currently supported for display."); + } - if (i + 1 < num_columns) { - // Only add the delimiter if there is at least - // one more element to print. - ss << " | "; - } - } - return ss.str(); + if (i + 1 < num_columns) { + // Only add the delimiter if there is at least + // one more element to print. + ss << " | "; } -} \ No newline at end of file + } + return ss.str(); +} +} // namespace arrow::matlab::tabular \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.cc b/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.cc index 7d24ad01d7e73..298ac4b595139 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.cc +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.cc @@ -21,219 +21,242 @@ #include "arrow/matlab/array/proxy/wrap.h" #include "arrow/matlab/error/error.h" +#include "arrow/matlab/tabular/get_row_as_string.h" #include "arrow/matlab/tabular/proxy/record_batch.h" #include "arrow/matlab/tabular/proxy/schema.h" -#include "arrow/matlab/tabular/get_row_as_string.h" #include "arrow/type.h" #include "arrow/util/utf8.h" -#include "libmexclass/proxy/ProxyManager.h" #include "libmexclass/error/Error.h" +#include "libmexclass/proxy/ProxyManager.h" #include namespace arrow::matlab::tabular::proxy { - namespace { - libmexclass::error::Error makeEmptyRecordBatchError() { - const std::string error_msg = "Numeric indexing using the column method is not supported for record batches with no columns."; - return libmexclass::error::Error{error::RECORD_BATCH_NUMERIC_INDEX_WITH_EMPTY_RECORD_BATCH, error_msg}; - } - - libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, const int32_t num_columns) { - std::stringstream error_message_stream; - error_message_stream << "Invalid column index: "; - error_message_stream << matlab_index; - error_message_stream << ". Column index must be between 1 and the number of columns ("; - error_message_stream << num_columns; - error_message_stream << ")."; - return libmexclass::error::Error{error::RECORD_BATCH_INVALID_NUMERIC_COLUMN_INDEX, error_message_stream.str()}; - } - } - - RecordBatch::RecordBatch(std::shared_ptr record_batch) : record_batch{record_batch} { - REGISTER_METHOD(RecordBatch, toString); - REGISTER_METHOD(RecordBatch, getNumRows); - REGISTER_METHOD(RecordBatch, getNumColumns); - REGISTER_METHOD(RecordBatch, getColumnNames); - REGISTER_METHOD(RecordBatch, getColumnByIndex); - REGISTER_METHOD(RecordBatch, getColumnByName); - REGISTER_METHOD(RecordBatch, getSchema); - REGISTER_METHOD(RecordBatch, getRowAsString); - } - - std::shared_ptr RecordBatch::unwrap() { - return record_batch; - } - - void RecordBatch::toString(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_string, arrow::util::UTF8StringToUTF16(record_batch->ToString()), context, error::UNICODE_CONVERSION_ERROR_ID); - mda::ArrayFactory factory; - auto str_mda = factory.createScalar(utf16_string); - context.outputs[0] = str_mda; - } - - libmexclass::proxy::MakeResult RecordBatch::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; - const mda::StringArray column_names = opts[0]["ColumnNames"]; - - std::vector> arrow_arrays; - // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. - for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { - auto proxy = libmexclass::proxy::ProxyManager::getProxy(arrow_array_proxy_id); - auto arrow_array_proxy = std::static_pointer_cast(proxy); - auto arrow_array = arrow_array_proxy->unwrap(); - arrow_arrays.push_back(arrow_array); - } - - std::vector> fields; - for (size_t i = 0; i < arrow_arrays.size(); ++i) { - const auto type = arrow_arrays[i]->type(); - const auto column_name_utf16 = std::u16string(column_names[i]); - MATLAB_ASSIGN_OR_ERROR(const auto column_name_utf8, arrow::util::UTF16StringToUTF8(column_name_utf16), error::UNICODE_CONVERSION_ERROR_ID); - fields.push_back(std::make_shared(column_name_utf8, type)); - } - - arrow::SchemaBuilder schema_builder; - MATLAB_ERROR_IF_NOT_OK(schema_builder.AddFields(fields), error::SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID); - MATLAB_ASSIGN_OR_ERROR(const auto schema, schema_builder.Finish(), error::SCHEMA_BUILDER_FINISH_ERROR_ID); - const auto num_rows = arrow_arrays.size() == 0 ? 0 : arrow_arrays[0]->length(); - const auto record_batch = arrow::RecordBatch::Make(schema, num_rows, arrow_arrays); - auto record_batch_proxy = std::make_shared(record_batch); - - return record_batch_proxy; - } - - void RecordBatch::getNumRows(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const auto num_rows = record_batch->num_rows(); - auto num_rows_mda = factory.createScalar(num_rows); - context.outputs[0] = num_rows_mda; - } - - void RecordBatch::getNumColumns(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const auto num_columns = record_batch->num_columns(); - auto num_columns_mda = factory.createScalar(num_columns); - context.outputs[0] = num_columns_mda; - } - - void RecordBatch::getColumnNames(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const int num_columns = record_batch->num_columns(); - - std::vector column_names; - for (int i = 0; i < num_columns; ++i) { - const auto column_name_utf8 = record_batch->column_name(i); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto column_name_utf16, arrow::util::UTF8StringToUTF16(column_name_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - const mda::MATLABString matlab_string = mda::MATLABString(std::move(column_name_utf16)); - column_names.push_back(matlab_string); - } - auto column_names_mda = factory.createArray({size_t{1}, static_cast(num_columns)}, column_names.begin(), column_names.end()); - context.outputs[0] = column_names_mda; - } - - void RecordBatch::getColumnByIndex(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - // arrow::Schema::field does not do any bounds checking. - const int32_t index = matlab_index - 1; - const auto num_columns = record_batch->num_columns(); - - if (num_columns == 0) { - context.error = makeEmptyRecordBatchError(); - return; - } - - if (matlab_index < 1 || matlab_index > num_columns) { - context.error = makeInvalidNumericIndexError(matlab_index, num_columns); - return; - } - - const auto array = record_batch->column(index); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, - arrow::matlab::array::proxy::wrap(array), - context, - error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - - - const auto array_proxy_id = ProxyManager::manageProxy(array_proxy); - const auto array_proxy_id_mda = factory.createScalar(array_proxy_id); - const auto array_type_id_mda = factory.createScalar(static_cast(array->type_id())); - - context.outputs[0] = array_proxy_id_mda; - context.outputs[1] = array_type_id_mda; - } - - void RecordBatch::getColumnByName(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::StringArray name_mda = args[0]["Name"]; - const auto name_utf16 = std::u16string(name_mda[0]); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, arrow::util::UTF16StringToUTF8(name_utf16), context, error::UNICODE_CONVERSION_ERROR_ID); - - const std::vector names = {name}; - const auto& schema = record_batch->schema(); - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); - - const auto array = record_batch->GetColumnByName(name); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, - arrow::matlab::array::proxy::wrap(array), - context, - error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); - - const auto array_proxy_id = ProxyManager::manageProxy(array_proxy); - const auto array_proxy_id_mda = factory.createScalar(array_proxy_id); - const auto array_type_id_mda = factory.createScalar(static_cast(array->type_id())); - - context.outputs[0] = array_proxy_id_mda; - context.outputs[1] = array_type_id_mda; - } - - void RecordBatch::getSchema(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using SchemaProxy = arrow::matlab::tabular::proxy::Schema; - mda::ArrayFactory factory; - - const auto schema = record_batch->schema(); - const auto schema_proxy = std::make_shared(std::move(schema)); - const auto schema_proxy_id = ProxyManager::manageProxy(schema_proxy); - const auto schema_proxy_id_mda = factory.createScalar(schema_proxy_id); - - context.outputs[0] = schema_proxy_id_mda; - } - - void RecordBatch::getRowAsString(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_row_index = int64_t(index_mda[0]); - - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf8, arrow::matlab::tabular::get_row_as_string(record_batch, matlab_row_index), - context, error::TABULAR_GET_ROW_AS_STRING_FAILED); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf16, arrow::util::UTF8StringToUTF16(row_str_utf8), - context, error::UNICODE_CONVERSION_ERROR_ID); - context.outputs[0] = factory.createScalar(row_str_utf16); - } +namespace { +libmexclass::error::Error makeEmptyRecordBatchError() { + const std::string error_msg = + "Numeric indexing using the column method is not supported for record batches with " + "no columns."; + return libmexclass::error::Error{ + error::RECORD_BATCH_NUMERIC_INDEX_WITH_EMPTY_RECORD_BATCH, error_msg}; +} + +libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, + const int32_t num_columns) { + std::stringstream error_message_stream; + error_message_stream << "Invalid column index: "; + error_message_stream << matlab_index; + error_message_stream << ". Column index must be between 1 and the number of columns ("; + error_message_stream << num_columns; + error_message_stream << ")."; + return libmexclass::error::Error{error::RECORD_BATCH_INVALID_NUMERIC_COLUMN_INDEX, + error_message_stream.str()}; +} +} // namespace + +RecordBatch::RecordBatch(std::shared_ptr record_batch) + : record_batch{record_batch} { + REGISTER_METHOD(RecordBatch, toString); + REGISTER_METHOD(RecordBatch, getNumRows); + REGISTER_METHOD(RecordBatch, getNumColumns); + REGISTER_METHOD(RecordBatch, getColumnNames); + REGISTER_METHOD(RecordBatch, getColumnByIndex); + REGISTER_METHOD(RecordBatch, getColumnByName); + REGISTER_METHOD(RecordBatch, getSchema); + REGISTER_METHOD(RecordBatch, getRowAsString); +} + +std::shared_ptr RecordBatch::unwrap() { return record_batch; } + +void RecordBatch::toString(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + const auto utf16_string, arrow::util::UTF8StringToUTF16(record_batch->ToString()), + context, error::UNICODE_CONVERSION_ERROR_ID); + mda::ArrayFactory factory; + auto str_mda = factory.createScalar(utf16_string); + context.outputs[0] = str_mda; +} + +libmexclass::proxy::MakeResult RecordBatch::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; + const mda::StringArray column_names = opts[0]["ColumnNames"]; + + std::vector> arrow_arrays; + // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. + for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { + auto proxy = libmexclass::proxy::ProxyManager::getProxy(arrow_array_proxy_id); + auto arrow_array_proxy = + std::static_pointer_cast(proxy); + auto arrow_array = arrow_array_proxy->unwrap(); + arrow_arrays.push_back(arrow_array); + } + + std::vector> fields; + for (size_t i = 0; i < arrow_arrays.size(); ++i) { + const auto type = arrow_arrays[i]->type(); + const auto column_name_utf16 = std::u16string(column_names[i]); + MATLAB_ASSIGN_OR_ERROR(const auto column_name_utf8, + arrow::util::UTF16StringToUTF8(column_name_utf16), + error::UNICODE_CONVERSION_ERROR_ID); + fields.push_back(std::make_shared(column_name_utf8, type)); + } + + arrow::SchemaBuilder schema_builder; + MATLAB_ERROR_IF_NOT_OK(schema_builder.AddFields(fields), + error::SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID); + MATLAB_ASSIGN_OR_ERROR(const auto schema, schema_builder.Finish(), + error::SCHEMA_BUILDER_FINISH_ERROR_ID); + const auto num_rows = arrow_arrays.size() == 0 ? 0 : arrow_arrays[0]->length(); + const auto record_batch = arrow::RecordBatch::Make(schema, num_rows, arrow_arrays); + auto record_batch_proxy = + std::make_shared(record_batch); + + return record_batch_proxy; +} + +void RecordBatch::getNumRows(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const auto num_rows = record_batch->num_rows(); + auto num_rows_mda = factory.createScalar(num_rows); + context.outputs[0] = num_rows_mda; +} + +void RecordBatch::getNumColumns(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const auto num_columns = record_batch->num_columns(); + auto num_columns_mda = factory.createScalar(num_columns); + context.outputs[0] = num_columns_mda; +} + +void RecordBatch::getColumnNames(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const int num_columns = record_batch->num_columns(); + + std::vector column_names; + for (int i = 0; i < num_columns; ++i) { + const auto column_name_utf8 = record_batch->column_name(i); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto column_name_utf16, + arrow::util::UTF8StringToUTF16(column_name_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + const mda::MATLABString matlab_string = + mda::MATLABString(std::move(column_name_utf16)); + column_names.push_back(matlab_string); + } + auto column_names_mda = + factory.createArray({size_t{1}, static_cast(num_columns)}, + column_names.begin(), column_names.end()); + context.outputs[0] = column_names_mda; +} + +void RecordBatch::getColumnByIndex(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + // arrow::Schema::field does not do any bounds checking. + const int32_t index = matlab_index - 1; + const auto num_columns = record_batch->num_columns(); + + if (num_columns == 0) { + context.error = makeEmptyRecordBatchError(); + return; + } + + if (matlab_index < 1 || matlab_index > num_columns) { + context.error = makeInvalidNumericIndexError(matlab_index, num_columns); + return; + } + + const auto array = record_batch->column(index); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, + arrow::matlab::array::proxy::wrap(array), context, + error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + + const auto array_proxy_id = ProxyManager::manageProxy(array_proxy); + const auto array_proxy_id_mda = factory.createScalar(array_proxy_id); + const auto array_type_id_mda = + factory.createScalar(static_cast(array->type_id())); + + context.outputs[0] = array_proxy_id_mda; + context.outputs[1] = array_type_id_mda; +} +void RecordBatch::getColumnByName(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::StringArray name_mda = args[0]["Name"]; + const auto name_utf16 = std::u16string(name_mda[0]); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, + arrow::util::UTF16StringToUTF8(name_utf16), context, + error::UNICODE_CONVERSION_ERROR_ID); + + const std::vector names = {name}; + const auto& schema = record_batch->schema(); + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, + error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); + + const auto array = record_batch->GetColumnByName(name); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto array_proxy, + arrow::matlab::array::proxy::wrap(array), context, + error::UNKNOWN_PROXY_FOR_ARRAY_TYPE); + + const auto array_proxy_id = ProxyManager::manageProxy(array_proxy); + const auto array_proxy_id_mda = factory.createScalar(array_proxy_id); + const auto array_type_id_mda = + factory.createScalar(static_cast(array->type_id())); + + context.outputs[0] = array_proxy_id_mda; + context.outputs[1] = array_type_id_mda; } + +void RecordBatch::getSchema(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using SchemaProxy = arrow::matlab::tabular::proxy::Schema; + mda::ArrayFactory factory; + + const auto schema = record_batch->schema(); + const auto schema_proxy = std::make_shared(std::move(schema)); + const auto schema_proxy_id = ProxyManager::manageProxy(schema_proxy); + const auto schema_proxy_id_mda = factory.createScalar(schema_proxy_id); + + context.outputs[0] = schema_proxy_id_mda; +} + +void RecordBatch::getRowAsString(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_row_index = int64_t(index_mda[0]); + + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto row_str_utf8, + arrow::matlab::tabular::get_row_as_string(record_batch, matlab_row_index), context, + error::TABULAR_GET_ROW_AS_STRING_FAILED); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf16, + arrow::util::UTF8StringToUTF16(row_str_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + context.outputs[0] = factory.createScalar(row_str_utf16); +} + +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.h b/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.h index c417d8198f9ad..c8285c9b095d5 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.h +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/record_batch.h @@ -23,27 +23,28 @@ namespace arrow::matlab::tabular::proxy { - class RecordBatch : public libmexclass::proxy::Proxy { - public: - RecordBatch(std::shared_ptr record_batch); - - virtual ~RecordBatch() {} - - std::shared_ptr unwrap(); - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - protected: - void toString(libmexclass::proxy::method::Context& context); - void getNumRows(libmexclass::proxy::method::Context& context); - void getNumColumns(libmexclass::proxy::method::Context& context); - void getColumnNames(libmexclass::proxy::method::Context& context); - void getColumnByIndex(libmexclass::proxy::method::Context& context); - void getColumnByName(libmexclass::proxy::method::Context& context); - void getSchema(libmexclass::proxy::method::Context& context); - void getRowAsString(libmexclass::proxy::method::Context& context); - - std::shared_ptr record_batch; - }; - -} +class RecordBatch : public libmexclass::proxy::Proxy { + public: + RecordBatch(std::shared_ptr record_batch); + + virtual ~RecordBatch() {} + + std::shared_ptr unwrap(); + + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); + + protected: + void toString(libmexclass::proxy::method::Context& context); + void getNumRows(libmexclass::proxy::method::Context& context); + void getNumColumns(libmexclass::proxy::method::Context& context); + void getColumnNames(libmexclass::proxy::method::Context& context); + void getColumnByIndex(libmexclass::proxy::method::Context& context); + void getColumnByName(libmexclass::proxy::method::Context& context); + void getSchema(libmexclass::proxy::method::Context& context); + void getRowAsString(libmexclass::proxy::method::Context& context); + + std::shared_ptr record_batch; +}; + +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.cc b/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.cc index db7486bdb1bb7..0d645c4810f8e 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.cc +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.cc @@ -15,13 +15,13 @@ // specific language governing permissions and limitations // under the License. -#include "arrow/matlab/error/error.h" #include "arrow/matlab/tabular/proxy/schema.h" -#include "arrow/matlab/type/proxy/field.h" +#include "arrow/matlab/error/error.h" #include "arrow/matlab/index/validate.h" +#include "arrow/matlab/type/proxy/field.h" -#include "libmexclass/proxy/ProxyManager.h" #include "libmexclass/error/Error.h" +#include "libmexclass/proxy/ProxyManager.h" #include "arrow/util/utf8.h" @@ -29,115 +29,119 @@ namespace arrow::matlab::tabular::proxy { - Schema::Schema(std::shared_ptr schema) : schema{std::move(schema)} { - REGISTER_METHOD(Schema, getFieldByIndex); - REGISTER_METHOD(Schema, getFieldByName); - REGISTER_METHOD(Schema, getNumFields); - REGISTER_METHOD(Schema, getFieldNames); - } - - libmexclass::proxy::MakeResult Schema::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using SchemaProxy = arrow::matlab::tabular::proxy::Schema; - - mda::StructArray args = constructor_arguments[0]; - const mda::TypedArray field_proxy_ids_mda = args[0]["FieldProxyIDs"]; - - std::vector> fields; - for (const auto proxy_id : field_proxy_ids_mda) { - using namespace libmexclass::proxy; - auto proxy = std::static_pointer_cast(ProxyManager::getProxy(proxy_id)); - auto field = proxy->unwrap(); - fields.push_back(field); - } - auto schema = arrow::schema(fields); - return std::make_shared(std::move(schema)); - } - - std::shared_ptr Schema::unwrap() { - return schema; - } - - void Schema::getFieldByIndex(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using FieldProxy = arrow::matlab::type::proxy::Field; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - // Validate there is at least 1 field - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateNonEmptyContainer(schema->num_fields()), - context, - error::INDEX_EMPTY_CONTAINER); - - // Validate the matlab index provided is within the range [1, num_fields] - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateInRange(matlab_index, schema->num_fields()), - context, - error::INDEX_OUT_OF_RANGE); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - // arrow::Schema::field does not do any bounds checking. - const int32_t index = matlab_index - 1; - - auto field = schema->field(index); - auto field_proxy = std::make_shared(std::move(field)); - auto field_proxy_id = ProxyManager::manageProxy(field_proxy); - context.outputs[0] = factory.createScalar(field_proxy_id); - } - - void Schema::getFieldByName(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using FieldProxy = arrow::matlab::type::proxy::Field; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::StringArray name_mda = args[0]["Name"]; - const auto name_utf16 = std::u16string(name_mda[0]); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, arrow::util::UTF16StringToUTF8(name_utf16), context, error::UNICODE_CONVERSION_ERROR_ID); - const std::vector names = {name}; - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); - - const auto field = schema->GetFieldByName(name); - auto field_proxy = std::make_shared(field); - const auto field_proxy_id = ProxyManager::manageProxy(field_proxy); - context.outputs[0] = factory.createScalar(field_proxy_id); - } - - void Schema::getNumFields(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - const auto num_fields = schema->num_fields(); - const auto num_fields_mda = factory.createScalar(num_fields); - - context.outputs[0] = num_fields_mda; - } - - void Schema::getFieldNames(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - const auto field_names_utf8 = schema->field_names(); - const auto num_fields = static_cast(schema->num_fields()); - - std::vector field_names_utf16; - field_names_utf16.reserve(num_fields); - - // Convert the field names from UTF-8 to UTF-16. - for (const auto& field_name_utf8 : field_names_utf8) { - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto field_name_utf16, arrow::util::UTF8StringToUTF16(field_name_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - field_names_utf16.push_back(field_name_utf16); - } - - const auto field_names_mda = factory.createArray({1, num_fields}, field_names_utf16.cbegin(), field_names_utf16.cend()); - - context.outputs[0] = field_names_mda; - } +Schema::Schema(std::shared_ptr schema) : schema{std::move(schema)} { + REGISTER_METHOD(Schema, getFieldByIndex); + REGISTER_METHOD(Schema, getFieldByName); + REGISTER_METHOD(Schema, getNumFields); + REGISTER_METHOD(Schema, getFieldNames); +} + +libmexclass::proxy::MakeResult Schema::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using SchemaProxy = arrow::matlab::tabular::proxy::Schema; + + mda::StructArray args = constructor_arguments[0]; + const mda::TypedArray field_proxy_ids_mda = args[0]["FieldProxyIDs"]; + + std::vector> fields; + for (const auto proxy_id : field_proxy_ids_mda) { + using namespace libmexclass::proxy; + auto proxy = std::static_pointer_cast( + ProxyManager::getProxy(proxy_id)); + auto field = proxy->unwrap(); + fields.push_back(field); + } + auto schema = arrow::schema(fields); + return std::make_shared(std::move(schema)); +} + +std::shared_ptr Schema::unwrap() { return schema; } + +void Schema::getFieldByIndex(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using FieldProxy = arrow::matlab::type::proxy::Field; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + // Validate there is at least 1 field + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + index::validateNonEmptyContainer(schema->num_fields()), context, + error::INDEX_EMPTY_CONTAINER); + + // Validate the matlab index provided is within the range [1, num_fields] + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + index::validateInRange(matlab_index, schema->num_fields()), context, + error::INDEX_OUT_OF_RANGE); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + // arrow::Schema::field does not do any bounds checking. + const int32_t index = matlab_index - 1; + auto field = schema->field(index); + auto field_proxy = std::make_shared(std::move(field)); + auto field_proxy_id = ProxyManager::manageProxy(field_proxy); + context.outputs[0] = factory.createScalar(field_proxy_id); } + +void Schema::getFieldByName(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using FieldProxy = arrow::matlab::type::proxy::Field; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::StringArray name_mda = args[0]["Name"]; + const auto name_utf16 = std::u16string(name_mda[0]); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, + arrow::util::UTF16StringToUTF8(name_utf16), context, + error::UNICODE_CONVERSION_ERROR_ID); + const std::vector names = {name}; + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, + error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); + + const auto field = schema->GetFieldByName(name); + auto field_proxy = std::make_shared(field); + const auto field_proxy_id = ProxyManager::manageProxy(field_proxy); + context.outputs[0] = factory.createScalar(field_proxy_id); +} + +void Schema::getNumFields(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + + const auto num_fields = schema->num_fields(); + const auto num_fields_mda = factory.createScalar(num_fields); + + context.outputs[0] = num_fields_mda; +} + +void Schema::getFieldNames(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + + const auto field_names_utf8 = schema->field_names(); + const auto num_fields = static_cast(schema->num_fields()); + + std::vector field_names_utf16; + field_names_utf16.reserve(num_fields); + + // Convert the field names from UTF-8 to UTF-16. + for (const auto& field_name_utf8 : field_names_utf8) { + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto field_name_utf16, + arrow::util::UTF8StringToUTF16(field_name_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + field_names_utf16.push_back(field_name_utf16); + } + + const auto field_names_mda = factory.createArray( + {1, num_fields}, field_names_utf16.cbegin(), field_names_utf16.cend()); + + context.outputs[0] = field_names_mda; +} + +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.h b/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.h index 9ca4a94e53071..570fbac197ba8 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.h +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/schema.h @@ -24,23 +24,24 @@ namespace arrow::matlab::tabular::proxy { - class Schema : public libmexclass::proxy::Proxy { - public: - Schema(std::shared_ptr Schema); +class Schema : public libmexclass::proxy::Proxy { + public: + Schema(std::shared_ptr Schema); - virtual ~Schema() {} + virtual ~Schema() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - std::shared_ptr unwrap(); + std::shared_ptr unwrap(); - protected: - void getFieldByIndex(libmexclass::proxy::method::Context& context); - void getFieldByName(libmexclass::proxy::method::Context& context); - void getNumFields(libmexclass::proxy::method::Context& context); - void getFieldNames(libmexclass::proxy::method::Context& context); + protected: + void getFieldByIndex(libmexclass::proxy::method::Context& context); + void getFieldByName(libmexclass::proxy::method::Context& context); + void getNumFields(libmexclass::proxy::method::Context& context); + void getFieldNames(libmexclass::proxy::method::Context& context); - std::shared_ptr schema; - }; + std::shared_ptr schema; +}; -} +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc b/matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc index cf628407b1742..d7e31de4e7672 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/table.cc @@ -22,213 +22,234 @@ #include "arrow/matlab/array/proxy/wrap.h" #include "arrow/matlab/error/error.h" -#include "arrow/matlab/tabular/proxy/table.h" -#include "arrow/matlab/tabular/proxy/schema.h" #include "arrow/matlab/tabular/get_row_as_string.h" +#include "arrow/matlab/tabular/proxy/schema.h" +#include "arrow/matlab/tabular/proxy/table.h" #include "arrow/type.h" #include "arrow/util/utf8.h" -#include "libmexclass/proxy/ProxyManager.h" #include "libmexclass/error/Error.h" +#include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::tabular::proxy { - namespace { - libmexclass::error::Error makeEmptyTableError() { - const std::string error_msg = "Numeric indexing using the column method is not supported for tables with no columns."; - return libmexclass::error::Error{error::TABLE_NUMERIC_INDEX_WITH_EMPTY_TABLE, error_msg}; - } - - libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, const int32_t num_columns) { - std::stringstream error_message_stream; - error_message_stream << "Invalid column index: "; - error_message_stream << matlab_index; - error_message_stream << ". Column index must be between 1 and the number of columns ("; - error_message_stream << num_columns; - error_message_stream << ")."; - return libmexclass::error::Error{error::TABLE_INVALID_NUMERIC_COLUMN_INDEX, error_message_stream.str()}; - } - } - - Table::Table(std::shared_ptr table) : table{table} { - REGISTER_METHOD(Table, toString); - REGISTER_METHOD(Table, getNumRows); - REGISTER_METHOD(Table, getNumColumns); - REGISTER_METHOD(Table, getColumnNames); - REGISTER_METHOD(Table, getSchema); - REGISTER_METHOD(Table, getColumnByIndex); - REGISTER_METHOD(Table, getColumnByName); - REGISTER_METHOD(Table, getRowAsString); - } - - std::shared_ptr Table::unwrap() { - return table; - } - - void Table::toString(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_string, arrow::util::UTF8StringToUTF16(table->ToString()), context, error::UNICODE_CONVERSION_ERROR_ID); - mda::ArrayFactory factory; - auto str_mda = factory.createScalar(utf16_string); - context.outputs[0] = str_mda; - } - - libmexclass::proxy::MakeResult Table::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - using ArrayProxy = arrow::matlab::array::proxy::Array; - using TableProxy = arrow::matlab::tabular::proxy::Table; - namespace mda = ::matlab::data; - mda::StructArray opts = constructor_arguments[0]; - const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; - const mda::StringArray column_names = opts[0]["ColumnNames"]; - - std::vector> arrow_arrays; - // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. - for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { - auto proxy = libmexclass::proxy::ProxyManager::getProxy(arrow_array_proxy_id); - auto arrow_array_proxy = std::static_pointer_cast(proxy); - auto arrow_array = arrow_array_proxy->unwrap(); - arrow_arrays.push_back(arrow_array); - } - - std::vector> fields; - for (size_t i = 0; i < arrow_arrays.size(); ++i) { - const auto type = arrow_arrays[i]->type(); - const auto column_name_utf16 = std::u16string(column_names[i]); - MATLAB_ASSIGN_OR_ERROR(const auto column_name_utf8, arrow::util::UTF16StringToUTF8(column_name_utf16), error::UNICODE_CONVERSION_ERROR_ID); - fields.push_back(std::make_shared(column_name_utf8, type)); - } - - arrow::SchemaBuilder schema_builder; - MATLAB_ERROR_IF_NOT_OK(schema_builder.AddFields(fields), error::SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID); - MATLAB_ASSIGN_OR_ERROR(const auto schema, schema_builder.Finish(), error::SCHEMA_BUILDER_FINISH_ERROR_ID); - const auto num_rows = arrow_arrays.size() == 0 ? 0 : arrow_arrays[0]->length(); - const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows); - auto table_proxy = std::make_shared(table); - - return table_proxy; - } - - void Table::getNumRows(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const auto num_rows = table->num_rows(); - auto num_rows_mda = factory.createScalar(num_rows); - context.outputs[0] = num_rows_mda; - } - - void Table::getNumColumns(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const auto num_columns = table->num_columns(); - auto num_columns_mda = factory.createScalar(num_columns); - context.outputs[0] = num_columns_mda; - } - - void Table::getColumnNames(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - const int num_columns = table->num_columns(); - - std::vector column_names; - const auto schema = table->schema(); - const auto field_names = schema->field_names(); - for (int i = 0; i < num_columns; ++i) { - const auto column_name_utf8 = field_names[i]; - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto column_name_utf16, arrow::util::UTF8StringToUTF16(column_name_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - const mda::MATLABString matlab_string = mda::MATLABString(std::move(column_name_utf16)); - column_names.push_back(matlab_string); - } - auto column_names_mda = factory.createArray({size_t{1}, static_cast(num_columns)}, column_names.begin(), column_names.end()); - context.outputs[0] = column_names_mda; - } - - void Table::getSchema(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using SchemaProxy = arrow::matlab::tabular::proxy::Schema; - mda::ArrayFactory factory; - - const auto schema = table->schema(); - const auto schema_proxy = std::make_shared(std::move(schema)); - const auto schema_proxy_id = ProxyManager::manageProxy(schema_proxy); - const auto schema_proxy_id_mda = factory.createScalar(schema_proxy_id); - - context.outputs[0] = schema_proxy_id_mda; - } - - void Table::getColumnByIndex(libmexclass::proxy::method::Context& context) { - using ChunkedArrayProxy = arrow::matlab::array::proxy::ChunkedArray; - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - // arrow::Schema::field does not do any bounds checking. - const int32_t index = matlab_index - 1; - const auto num_columns = table->num_columns(); - - if (num_columns == 0) { - context.error = makeEmptyTableError(); - return; - } - - if (matlab_index < 1 || matlab_index > num_columns) { - context.error = makeInvalidNumericIndexError(matlab_index, num_columns); - return; - } - - const auto chunked_array = table->column(index); - const auto chunked_array_proxy = std::make_shared(chunked_array); - - const auto chunked_array_proxy_id = ProxyManager::manageProxy(chunked_array_proxy); - const auto chunked_array_proxy_id_mda = factory.createScalar(chunked_array_proxy_id); - - context.outputs[0] = chunked_array_proxy_id_mda; - } - - void Table::getColumnByName(libmexclass::proxy::method::Context& context) { - using ChunkedArrayProxy = arrow::matlab::array::proxy::ChunkedArray; - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::StringArray name_mda = args[0]["Name"]; - const auto name_utf16 = std::u16string(name_mda[0]); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, arrow::util::UTF16StringToUTF8(name_utf16), context, error::UNICODE_CONVERSION_ERROR_ID); - - const std::vector names = {name}; - const auto& schema = table->schema(); - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); - - const auto chunked_array = table->GetColumnByName(name); - const auto chunked_array_proxy = std::make_shared(chunked_array); - - const auto chunked_array_proxy_id = ProxyManager::manageProxy(chunked_array_proxy); - const auto chunked_array_proxy_id_mda = factory.createScalar(chunked_array_proxy_id); - - context.outputs[0] = chunked_array_proxy_id_mda; - } - - void Table::getRowAsString(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_row_index = int64_t(index_mda[0]); - - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf8, arrow::matlab::tabular::get_row_as_string(table, matlab_row_index), - context, error::TABULAR_GET_ROW_AS_STRING_FAILED); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf16, arrow::util::UTF8StringToUTF16(row_str_utf8), - context, error::UNICODE_CONVERSION_ERROR_ID); - context.outputs[0] = factory.createScalar(row_str_utf16); - } +namespace { +libmexclass::error::Error makeEmptyTableError() { + const std::string error_msg = + "Numeric indexing using the column method is not supported for tables with no " + "columns."; + return libmexclass::error::Error{error::TABLE_NUMERIC_INDEX_WITH_EMPTY_TABLE, + error_msg}; +} + +libmexclass::error::Error makeInvalidNumericIndexError(const int32_t matlab_index, + const int32_t num_columns) { + std::stringstream error_message_stream; + error_message_stream << "Invalid column index: "; + error_message_stream << matlab_index; + error_message_stream << ". Column index must be between 1 and the number of columns ("; + error_message_stream << num_columns; + error_message_stream << ")."; + return libmexclass::error::Error{error::TABLE_INVALID_NUMERIC_COLUMN_INDEX, + error_message_stream.str()}; +} +} // namespace + +Table::Table(std::shared_ptr table) : table{table} { + REGISTER_METHOD(Table, toString); + REGISTER_METHOD(Table, getNumRows); + REGISTER_METHOD(Table, getNumColumns); + REGISTER_METHOD(Table, getColumnNames); + REGISTER_METHOD(Table, getSchema); + REGISTER_METHOD(Table, getColumnByIndex); + REGISTER_METHOD(Table, getColumnByName); + REGISTER_METHOD(Table, getRowAsString); +} + +std::shared_ptr Table::unwrap() { return table; } + +void Table::toString(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto utf16_string, + arrow::util::UTF8StringToUTF16(table->ToString()), + context, error::UNICODE_CONVERSION_ERROR_ID); + mda::ArrayFactory factory; + auto str_mda = factory.createScalar(utf16_string); + context.outputs[0] = str_mda; +} + +libmexclass::proxy::MakeResult Table::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using ArrayProxy = arrow::matlab::array::proxy::Array; + using TableProxy = arrow::matlab::tabular::proxy::Table; + namespace mda = ::matlab::data; + mda::StructArray opts = constructor_arguments[0]; + const mda::TypedArray arrow_array_proxy_ids = opts[0]["ArrayProxyIDs"]; + const mda::StringArray column_names = opts[0]["ColumnNames"]; + + std::vector> arrow_arrays; + // Retrieve all of the Arrow Array Proxy instances from the libmexclass ProxyManager. + for (const auto& arrow_array_proxy_id : arrow_array_proxy_ids) { + auto proxy = libmexclass::proxy::ProxyManager::getProxy(arrow_array_proxy_id); + auto arrow_array_proxy = std::static_pointer_cast(proxy); + auto arrow_array = arrow_array_proxy->unwrap(); + arrow_arrays.push_back(arrow_array); + } + + std::vector> fields; + for (size_t i = 0; i < arrow_arrays.size(); ++i) { + const auto type = arrow_arrays[i]->type(); + const auto column_name_utf16 = std::u16string(column_names[i]); + MATLAB_ASSIGN_OR_ERROR(const auto column_name_utf8, + arrow::util::UTF16StringToUTF8(column_name_utf16), + error::UNICODE_CONVERSION_ERROR_ID); + fields.push_back(std::make_shared(column_name_utf8, type)); + } + + arrow::SchemaBuilder schema_builder; + MATLAB_ERROR_IF_NOT_OK(schema_builder.AddFields(fields), + error::SCHEMA_BUILDER_ADD_FIELDS_ERROR_ID); + MATLAB_ASSIGN_OR_ERROR(const auto schema, schema_builder.Finish(), + error::SCHEMA_BUILDER_FINISH_ERROR_ID); + const auto num_rows = arrow_arrays.size() == 0 ? 0 : arrow_arrays[0]->length(); + const auto table = arrow::Table::Make(schema, arrow_arrays, num_rows); + auto table_proxy = std::make_shared(table); + + return table_proxy; +} + +void Table::getNumRows(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const auto num_rows = table->num_rows(); + auto num_rows_mda = factory.createScalar(num_rows); + context.outputs[0] = num_rows_mda; +} + +void Table::getNumColumns(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const auto num_columns = table->num_columns(); + auto num_columns_mda = factory.createScalar(num_columns); + context.outputs[0] = num_columns_mda; +} + +void Table::getColumnNames(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + const int num_columns = table->num_columns(); + + std::vector column_names; + const auto schema = table->schema(); + const auto field_names = schema->field_names(); + for (int i = 0; i < num_columns; ++i) { + const auto column_name_utf8 = field_names[i]; + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto column_name_utf16, + arrow::util::UTF8StringToUTF16(column_name_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + const mda::MATLABString matlab_string = + mda::MATLABString(std::move(column_name_utf16)); + column_names.push_back(matlab_string); + } + auto column_names_mda = + factory.createArray({size_t{1}, static_cast(num_columns)}, + column_names.begin(), column_names.end()); + context.outputs[0] = column_names_mda; +} + +void Table::getSchema(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using SchemaProxy = arrow::matlab::tabular::proxy::Schema; + mda::ArrayFactory factory; + + const auto schema = table->schema(); + const auto schema_proxy = std::make_shared(std::move(schema)); + const auto schema_proxy_id = ProxyManager::manageProxy(schema_proxy); + const auto schema_proxy_id_mda = factory.createScalar(schema_proxy_id); + + context.outputs[0] = schema_proxy_id_mda; +} + +void Table::getColumnByIndex(libmexclass::proxy::method::Context& context) { + using ChunkedArrayProxy = arrow::matlab::array::proxy::ChunkedArray; + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + // arrow::Schema::field does not do any bounds checking. + const int32_t index = matlab_index - 1; + const auto num_columns = table->num_columns(); + + if (num_columns == 0) { + context.error = makeEmptyTableError(); + return; + } + + if (matlab_index < 1 || matlab_index > num_columns) { + context.error = makeInvalidNumericIndexError(matlab_index, num_columns); + return; + } + + const auto chunked_array = table->column(index); + const auto chunked_array_proxy = std::make_shared(chunked_array); + + const auto chunked_array_proxy_id = ProxyManager::manageProxy(chunked_array_proxy); + const auto chunked_array_proxy_id_mda = factory.createScalar(chunked_array_proxy_id); + context.outputs[0] = chunked_array_proxy_id_mda; } + +void Table::getColumnByName(libmexclass::proxy::method::Context& context) { + using ChunkedArrayProxy = arrow::matlab::array::proxy::ChunkedArray; + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::StringArray name_mda = args[0]["Name"]; + const auto name_utf16 = std::u16string(name_mda[0]); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto name, + arrow::util::UTF16StringToUTF8(name_utf16), context, + error::UNICODE_CONVERSION_ERROR_ID); + + const std::vector names = {name}; + const auto& schema = table->schema(); + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(schema->CanReferenceFieldsByNames(names), context, + error::ARROW_TABULAR_SCHEMA_AMBIGUOUS_FIELD_NAME); + + const auto chunked_array = table->GetColumnByName(name); + const auto chunked_array_proxy = std::make_shared(chunked_array); + + const auto chunked_array_proxy_id = ProxyManager::manageProxy(chunked_array_proxy); + const auto chunked_array_proxy_id_mda = factory.createScalar(chunked_array_proxy_id); + + context.outputs[0] = chunked_array_proxy_id_mda; +} + +void Table::getRowAsString(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_row_index = int64_t(index_mda[0]); + + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT( + auto row_str_utf8, + arrow::matlab::tabular::get_row_as_string(table, matlab_row_index), context, + error::TABULAR_GET_ROW_AS_STRING_FAILED); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto row_str_utf16, + arrow::util::UTF8StringToUTF16(row_str_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + context.outputs[0] = factory.createScalar(row_str_utf16); +} + +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/tabular/proxy/table.h b/matlab/src/cpp/arrow/matlab/tabular/proxy/table.h index bfcea15bbd1c3..eb8ee6b4eb151 100644 --- a/matlab/src/cpp/arrow/matlab/tabular/proxy/table.h +++ b/matlab/src/cpp/arrow/matlab/tabular/proxy/table.h @@ -23,27 +23,28 @@ namespace arrow::matlab::tabular::proxy { - class Table : public libmexclass::proxy::Proxy { - public: - Table(std::shared_ptr table); +class Table : public libmexclass::proxy::Proxy { + public: + Table(std::shared_ptr table); - virtual ~Table() {} + virtual ~Table() {} - std::shared_ptr unwrap(); + std::shared_ptr unwrap(); - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void toString(libmexclass::proxy::method::Context& context); - void getNumRows(libmexclass::proxy::method::Context& context); - void getNumColumns(libmexclass::proxy::method::Context& context); - void getColumnNames(libmexclass::proxy::method::Context& context); - void getSchema(libmexclass::proxy::method::Context& context); - void getColumnByIndex(libmexclass::proxy::method::Context& context); - void getColumnByName(libmexclass::proxy::method::Context& context); - void getRowAsString(libmexclass::proxy::method::Context& context); + protected: + void toString(libmexclass::proxy::method::Context& context); + void getNumRows(libmexclass::proxy::method::Context& context); + void getNumColumns(libmexclass::proxy::method::Context& context); + void getColumnNames(libmexclass::proxy::method::Context& context); + void getSchema(libmexclass::proxy::method::Context& context); + void getColumnByIndex(libmexclass::proxy::method::Context& context); + void getColumnByName(libmexclass::proxy::method::Context& context); + void getRowAsString(libmexclass::proxy::method::Context& context); - std::shared_ptr table; - }; + std::shared_ptr table; +}; -} +} // namespace arrow::matlab::tabular::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.cc index c699c121efc1b..e98db8bd06fbc 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.cc @@ -19,13 +19,15 @@ namespace arrow::matlab::type::proxy { - Date32Type::Date32Type(std::shared_ptr date32_type) : DateType(std::move(date32_type)) {} +Date32Type::Date32Type(std::shared_ptr date32_type) + : DateType(std::move(date32_type)) {} - libmexclass::proxy::MakeResult Date32Type::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - using Date32TypeProxy = arrow::matlab::type::proxy::Date32Type; +libmexclass::proxy::MakeResult Date32Type::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using Date32TypeProxy = arrow::matlab::type::proxy::Date32Type; - const auto type = arrow::date32(); - const auto date32_type = std::static_pointer_cast(type); - return std::make_shared(std::move(date32_type)); - } + const auto type = arrow::date32(); + const auto date32_type = std::static_pointer_cast(type); + return std::make_shared(std::move(date32_type)); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.h index a239d4e6b45ca..9a9c95b26ac5b 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date32_type.h @@ -21,16 +21,14 @@ namespace arrow::matlab::type::proxy { - class Date32Type : public arrow::matlab::type::proxy::DateType { +class Date32Type : public arrow::matlab::type::proxy::DateType { + public: + Date32Type(std::shared_ptr date32_type); - public: - Date32Type(std::shared_ptr date32_type); + ~Date32Type() {} - ~Date32Type() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - }; - -} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +}; +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.cc index 413b73afa6432..ae769e8550133 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.cc @@ -19,13 +19,15 @@ namespace arrow::matlab::type::proxy { - Date64Type::Date64Type(std::shared_ptr date64_type) : DateType(std::move(date64_type)) {} +Date64Type::Date64Type(std::shared_ptr date64_type) + : DateType(std::move(date64_type)) {} - libmexclass::proxy::MakeResult Date64Type::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - using Date64TypeProxy = arrow::matlab::type::proxy::Date64Type; +libmexclass::proxy::MakeResult Date64Type::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using Date64TypeProxy = arrow::matlab::type::proxy::Date64Type; - const auto type = arrow::date64(); - const auto date64_type = std::static_pointer_cast(type); - return std::make_shared(std::move(date64_type)); - } + const auto type = arrow::date64(); + const auto date64_type = std::static_pointer_cast(type); + return std::make_shared(std::move(date64_type)); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.h index f0712c73b803a..5a76aee4276ae 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date64_type.h @@ -21,16 +21,14 @@ namespace arrow::matlab::type::proxy { - class Date64Type : public arrow::matlab::type::proxy::DateType { +class Date64Type : public arrow::matlab::type::proxy::DateType { + public: + Date64Type(std::shared_ptr date64_type); - public: - Date64Type(std::shared_ptr date64_type); + ~Date64Type() {} - ~Date64Type() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - }; - -} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +}; +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/date_type.cc index 25b639f8477ed..6b2a86b4f9bdb 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date_type.cc @@ -19,19 +19,20 @@ namespace arrow::matlab::type::proxy { - DateType::DateType(std::shared_ptr date_type) : FixedWidthType(std::move(date_type)) { - REGISTER_METHOD(DateType, getDateUnit); - } +DateType::DateType(std::shared_ptr date_type) + : FixedWidthType(std::move(date_type)) { + REGISTER_METHOD(DateType, getDateUnit); +} - void DateType::getDateUnit(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void DateType::getDateUnit(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - auto date_type = std::static_pointer_cast(data_type); - const auto date_unit = date_type->unit(); - // Cast to uint8_t since there are only two supported DateUnit enumeration values: - // Day and Millisecond - auto date_unit_mda = factory.createScalar(static_cast(date_unit)); - context.outputs[0] = date_unit_mda; - } + auto date_type = std::static_pointer_cast(data_type); + const auto date_unit = date_type->unit(); + // Cast to uint8_t since there are only two supported DateUnit enumeration values: + // Day and Millisecond + auto date_unit_mda = factory.createScalar(static_cast(date_unit)); + context.outputs[0] = date_unit_mda; } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/date_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/date_type.h index 72c33751abca8..c3a3c6718d6ab 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/date_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/date_type.h @@ -22,14 +22,13 @@ namespace arrow::matlab::type::proxy { class DateType : public arrow::matlab::type::proxy::FixedWidthType { + public: + DateType(std::shared_ptr date_type); - public: - DateType(std::shared_ptr date_type); + ~DateType() {} - ~DateType() {} - - protected: - void getDateUnit(libmexclass::proxy::method::Context& context); + protected: + void getDateUnit(libmexclass::proxy::method::Context& context); }; -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/field.cc b/matlab/src/cpp/arrow/matlab/type/proxy/field.cc index 138771a35c327..96de0370104fa 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/field.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/field.cc @@ -17,70 +17,71 @@ #include "arrow/util/utf8.h" -#include "arrow/matlab/type/proxy/field.h" #include "arrow/matlab/error/error.h" +#include "arrow/matlab/type/proxy/field.h" #include "arrow/matlab/type/proxy/primitive_ctype.h" -#include "arrow/matlab/type/proxy/timestamp_type.h" #include "arrow/matlab/type/proxy/string_type.h" +#include "arrow/matlab/type/proxy/timestamp_type.h" #include "arrow/matlab/type/proxy/wrap.h" #include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::type::proxy { - Field::Field(std::shared_ptr field) : field{std::move(field)} { - REGISTER_METHOD(Field, getName); - REGISTER_METHOD(Field, getType); - } - - std::shared_ptr Field::unwrap() { - return field; - } - - void Field::getName(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - const auto& str_utf8 = field->name(); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto str_utf16, arrow::util::UTF8StringToUTF16(str_utf8), context, error::UNICODE_CONVERSION_ERROR_ID); - auto str_mda = factory.createScalar(str_utf16); - context.outputs[0] = str_mda; - } - - void Field::getType(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - const auto& datatype = field->type(); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto proxy, type::proxy::wrap(datatype), context, error::FIELD_FAILED_TO_CREATE_TYPE_PROXY); - const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(proxy); - const auto type_id = static_cast(datatype->id()); - - mda::ArrayFactory factory; - mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); - output[0]["ProxyID"] = factory.createScalar(proxy_id); - output[0]["TypeID"] = factory.createScalar(type_id); - context.outputs[0] = output; - } - - libmexclass::proxy::MakeResult Field::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using FieldProxy = arrow::matlab::type::proxy::Field; - - mda::StructArray opts = constructor_arguments[0]; - const mda::StringArray name_mda = opts[0]["Name"]; - const mda::TypedArray type_proxy_id_mda = opts[0]["TypeProxyID"]; - - const std::u16string& name_utf16 = name_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto name, - arrow::util::UTF16StringToUTF8(name_utf16), - error::UNICODE_CONVERSION_ERROR_ID); - - auto proxy = std::static_pointer_cast(libmexclass::proxy::ProxyManager::getProxy(type_proxy_id_mda[0])); - auto type = proxy->unwrap(); - auto field = arrow::field(name, type); - return std::make_shared(std::move(field)); - } +Field::Field(std::shared_ptr field) : field{std::move(field)} { + REGISTER_METHOD(Field, getName); + REGISTER_METHOD(Field, getType); +} + +std::shared_ptr Field::unwrap() { return field; } + +void Field::getName(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + + const auto& str_utf8 = field->name(); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto str_utf16, + arrow::util::UTF8StringToUTF16(str_utf8), context, + error::UNICODE_CONVERSION_ERROR_ID); + auto str_mda = factory.createScalar(str_utf16); + context.outputs[0] = str_mda; +} + +void Field::getType(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + const auto& datatype = field->type(); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto proxy, type::proxy::wrap(datatype), context, + error::FIELD_FAILED_TO_CREATE_TYPE_PROXY); + const auto proxy_id = libmexclass::proxy::ProxyManager::manageProxy(proxy); + const auto type_id = static_cast(datatype->id()); + + mda::ArrayFactory factory; + mda::StructArray output = factory.createStructArray({1, 1}, {"ProxyID", "TypeID"}); + output[0]["ProxyID"] = factory.createScalar(proxy_id); + output[0]["TypeID"] = factory.createScalar(type_id); + context.outputs[0] = output; +} + +libmexclass::proxy::MakeResult Field::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using FieldProxy = arrow::matlab::type::proxy::Field; + + mda::StructArray opts = constructor_arguments[0]; + const mda::StringArray name_mda = opts[0]["Name"]; + const mda::TypedArray type_proxy_id_mda = opts[0]["TypeProxyID"]; + + const std::u16string& name_utf16 = name_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto name, arrow::util::UTF16StringToUTF8(name_utf16), + error::UNICODE_CONVERSION_ERROR_ID); + auto proxy = std::static_pointer_cast( + libmexclass::proxy::ProxyManager::getProxy(type_proxy_id_mda[0])); + auto type = proxy->unwrap(); + auto field = arrow::field(name, type); + return std::make_shared(std::move(field)); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/field.h b/matlab/src/cpp/arrow/matlab/type/proxy/field.h index 3526a6c422ac3..0750621fe6725 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/field.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/field.h @@ -24,20 +24,21 @@ namespace arrow::matlab::type::proxy { class Field : public libmexclass::proxy::Proxy { - public: - Field(std::shared_ptr field); + public: + Field(std::shared_ptr field); - virtual ~Field() {} + virtual ~Field() {} - std::shared_ptr unwrap(); + std::shared_ptr unwrap(); - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: - void getName(libmexclass::proxy::method::Context& context); - void getType(libmexclass::proxy::method::Context& context); + protected: + void getName(libmexclass::proxy::method::Context& context); + void getType(libmexclass::proxy::method::Context& context); - std::shared_ptr field; + std::shared_ptr field; }; -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.cc index b5015797bd660..f68dd66e67678 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.cc @@ -15,20 +15,20 @@ // specific language governing permissions and limitations // under the License. - #include "arrow/matlab/type/proxy/fixed_width_type.h" namespace arrow::matlab::type::proxy { - FixedWidthType::FixedWidthType(std::shared_ptr type) : Type(std::move(type)) { - REGISTER_METHOD(FixedWidthType, getBitWidth); - } +FixedWidthType::FixedWidthType(std::shared_ptr type) + : Type(std::move(type)) { + REGISTER_METHOD(FixedWidthType, getBitWidth); +} + +void FixedWidthType::getBitWidth(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - void FixedWidthType::getBitWidth(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - auto bit_width_mda = factory.createScalar(data_type->bit_width()); - context.outputs[0] = bit_width_mda; - } + auto bit_width_mda = factory.createScalar(data_type->bit_width()); + context.outputs[0] = bit_width_mda; } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.h index c1232462866d1..7da6d7ca165e7 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/fixed_width_type.h @@ -21,14 +21,13 @@ namespace arrow::matlab::type::proxy { class FixedWidthType : public arrow::matlab::type::proxy::Type { - public: - FixedWidthType(std::shared_ptr type); - - virtual ~FixedWidthType() {} + public: + FixedWidthType(std::shared_ptr type); - protected: - void getBitWidth(libmexclass::proxy::method::Context& context); + virtual ~FixedWidthType() {} + protected: + void getBitWidth(libmexclass::proxy::method::Context& context); }; -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/list_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/list_type.cc index 141a7a18750b6..d2a9b08590d80 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/list_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/list_type.cc @@ -16,49 +16,53 @@ // under the License. #include "arrow/matlab/type/proxy/list_type.h" +#include "arrow/matlab/error/error.h" #include "arrow/matlab/type/proxy/wrap.h" #include "libmexclass/proxy/ProxyManager.h" -#include "arrow/matlab/error/error.h" namespace arrow::matlab::type::proxy { - ListType::ListType(std::shared_ptr list_type) : Type(std::move(list_type)) { - REGISTER_METHOD(ListType, getValueType); - } +ListType::ListType(std::shared_ptr list_type) + : Type(std::move(list_type)) { + REGISTER_METHOD(ListType, getValueType); +} - void ListType::getValueType(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void ListType::getValueType(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - const auto list_type = std::static_pointer_cast(data_type); - const auto value_type = list_type->value_type(); - const auto value_type_id = static_cast(value_type->id()); + const auto list_type = std::static_pointer_cast(data_type); + const auto value_type = list_type->value_type(); + const auto value_type_id = static_cast(value_type->id()); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto value_type_proxy, - type::proxy::wrap(value_type), - context, - error::LIST_TYPE_FAILED_TO_CREATE_VALUE_TYPE_PROXY); - const auto value_type_proxy_id = libmexclass::proxy::ProxyManager::manageProxy(value_type_proxy); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(auto value_type_proxy, + type::proxy::wrap(value_type), context, + error::LIST_TYPE_FAILED_TO_CREATE_VALUE_TYPE_PROXY); + const auto value_type_proxy_id = + libmexclass::proxy::ProxyManager::manageProxy(value_type_proxy); - mda::StructArray output = factory.createStructArray({1, 1}, {"ValueTypeProxyID", "ValueTypeID"}); - output[0]["ValueTypeProxyID"] = factory.createScalar(value_type_proxy_id); - output[0]["ValueTypeID"] = factory.createScalar(value_type_id); + mda::StructArray output = + factory.createStructArray({1, 1}, {"ValueTypeProxyID", "ValueTypeID"}); + output[0]["ValueTypeProxyID"] = factory.createScalar(value_type_proxy_id); + output[0]["ValueTypeID"] = factory.createScalar(value_type_id); - context.outputs[0] = output; - } + context.outputs[0] = output; +} - libmexclass::proxy::MakeResult ListType::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using namespace libmexclass::proxy; - using ListTypeProxy = arrow::matlab::type::proxy::ListType; +libmexclass::proxy::MakeResult ListType::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using namespace libmexclass::proxy; + using ListTypeProxy = arrow::matlab::type::proxy::ListType; - mda::StructArray args = constructor_arguments[0]; - const mda::TypedArray value_type_proxy_id_mda = args[0]["ValueTypeProxyID"]; - const auto value_type_proxy_id = value_type_proxy_id_mda[0]; - const auto proxy = ProxyManager::getProxy(value_type_proxy_id); - const auto value_type_proxy = std::static_pointer_cast(proxy); - const auto value_type = value_type_proxy->unwrap(); - const auto list_type = std::static_pointer_cast(arrow::list(value_type)); - return std::make_shared(std::move(list_type)); - } + mda::StructArray args = constructor_arguments[0]; + const mda::TypedArray value_type_proxy_id_mda = args[0]["ValueTypeProxyID"]; + const auto value_type_proxy_id = value_type_proxy_id_mda[0]; + const auto proxy = ProxyManager::getProxy(value_type_proxy_id); + const auto value_type_proxy = std::static_pointer_cast(proxy); + const auto value_type = value_type_proxy->unwrap(); + const auto list_type = + std::static_pointer_cast(arrow::list(value_type)); + return std::make_shared(std::move(list_type)); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/list_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/list_type.h index 1d7599e0537a3..640b15c6159f1 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/list_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/list_type.h @@ -21,16 +21,16 @@ namespace arrow::matlab::type::proxy { - class ListType : public arrow::matlab::type::proxy::Type { +class ListType : public arrow::matlab::type::proxy::Type { + public: + ListType(std::shared_ptr list_type); - public: - ListType(std::shared_ptr list_type); + ~ListType() {} - ~ListType() {} + void getValueType(libmexclass::proxy::method::Context& context); - void getValueType(libmexclass::proxy::method::Context& context); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +}; - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - }; - -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/primitive_ctype.h b/matlab/src/cpp/arrow/matlab/type/proxy/primitive_ctype.h index 0415972b44c5b..c61a58c907322 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/primitive_ctype.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/primitive_ctype.h @@ -22,7 +22,6 @@ #include - namespace arrow::matlab::type::proxy { template @@ -31,25 +30,25 @@ using arrow_type_t = typename arrow::CTypeTraits::ArrowType; template using is_primitive = arrow::is_primitive_ctype>; -template -using enable_if_primitive = std::enable_if_t::value, bool>; +template +using enable_if_primitive = std::enable_if_t::value, bool>; -template = true> +template = true> class PrimitiveCType : public arrow::matlab::type::proxy::FixedWidthType { - - using ArrowDataType = arrow_type_t; - - public: - PrimitiveCType(std::shared_ptr primitive_type) : arrow::matlab::type::proxy::FixedWidthType(std::move(primitive_type)) { - } - - ~PrimitiveCType() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - auto data_type = arrow::CTypeTraits::type_singleton(); - return std::make_shared(std::static_pointer_cast(std::move(data_type))); - } -}; + using ArrowDataType = arrow_type_t; -} + public: + PrimitiveCType(std::shared_ptr primitive_type) + : arrow::matlab::type::proxy::FixedWidthType(std::move(primitive_type)) {} + + ~PrimitiveCType() {} + + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + auto data_type = arrow::CTypeTraits::type_singleton(); + return std::make_shared( + std::static_pointer_cast(std::move(data_type))); + } +}; +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/string_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/string_type.cc index 362dfba7344ea..5287ffdfa5f90 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/string_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/string_type.cc @@ -19,10 +19,12 @@ namespace arrow::matlab::type::proxy { - StringType::StringType(std::shared_ptr string_type) : Type(std::move(string_type)) {} +StringType::StringType(std::shared_ptr string_type) + : Type(std::move(string_type)) {} - libmexclass::proxy::MakeResult StringType::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - auto string_type = std::static_pointer_cast(arrow::utf8()); - return std::make_shared(std::move(string_type)); - } +libmexclass::proxy::MakeResult StringType::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + auto string_type = std::static_pointer_cast(arrow::utf8()); + return std::make_shared(std::move(string_type)); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/string_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/string_type.h index fd1808d9b8058..2635cc9360cf7 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/string_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/string_type.h @@ -22,14 +22,13 @@ namespace arrow::matlab::type::proxy { class StringType : public arrow::matlab::type::proxy::Type { - - public: - StringType(std::shared_ptr string_type); + public: + StringType(std::shared_ptr string_type); - ~StringType() {} + ~StringType() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); }; -} - +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.cc index fbb8dc3f6edbe..a79b76e0147ba 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.cc @@ -21,25 +21,27 @@ namespace arrow::matlab::type::proxy { - StructType::StructType(std::shared_ptr struct_type) : Type(std::move(struct_type)) {} +StructType::StructType(std::shared_ptr struct_type) + : Type(std::move(struct_type)) {} - libmexclass::proxy::MakeResult StructType::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using StructTypeProxy = arrow::matlab::type::proxy::StructType; +libmexclass::proxy::MakeResult StructType::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using StructTypeProxy = arrow::matlab::type::proxy::StructType; - mda::StructArray args = constructor_arguments[0]; - const mda::TypedArray field_proxy_ids_mda = args[0]["FieldProxyIDs"]; + mda::StructArray args = constructor_arguments[0]; + const mda::TypedArray field_proxy_ids_mda = args[0]["FieldProxyIDs"]; - std::vector> fields; - fields.reserve(field_proxy_ids_mda.getNumberOfElements()); - for (const auto proxy_id : field_proxy_ids_mda) { - using namespace libmexclass::proxy; - auto proxy = std::static_pointer_cast(ProxyManager::getProxy(proxy_id)); - auto field = proxy->unwrap(); - fields.push_back(field); - } + std::vector> fields; + fields.reserve(field_proxy_ids_mda.getNumberOfElements()); + for (const auto proxy_id : field_proxy_ids_mda) { + using namespace libmexclass::proxy; + auto proxy = std::static_pointer_cast(ProxyManager::getProxy(proxy_id)); + auto field = proxy->unwrap(); + fields.push_back(field); + } - auto struct_type = std::static_pointer_cast(arrow::struct_(fields)); - return std::make_shared(std::move(struct_type)); - } -} \ No newline at end of file + auto struct_type = std::static_pointer_cast(arrow::struct_(fields)); + return std::make_shared(std::move(struct_type)); +} +} // namespace arrow::matlab::type::proxy \ No newline at end of file diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.h index d3659e5784242..69e13581e1379 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/struct_type.h @@ -21,14 +21,14 @@ namespace arrow::matlab::type::proxy { - class StructType : public arrow::matlab::type::proxy::Type { +class StructType : public arrow::matlab::type::proxy::Type { + public: + StructType(std::shared_ptr struct_type); - public: - StructType(std::shared_ptr struct_type); + ~StructType() {} - ~StructType() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); +}; - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - }; - -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.cc index a3f54ed56a5da..8c0b6a0aa0c57 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.cc @@ -19,9 +19,11 @@ namespace arrow::matlab::type::proxy { - Time32Type::Time32Type(std::shared_ptr time32_type) : TimeType(std::move(time32_type)) {} +Time32Type::Time32Type(std::shared_ptr time32_type) + : TimeType(std::move(time32_type)) {} - libmexclass::proxy::MakeResult Time32Type::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - return make_time_type(constructor_arguments); - } +libmexclass::proxy::MakeResult Time32Type::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + return make_time_type(constructor_arguments); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.h index cf1a9c9fa4045..81ac93790b1a7 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time32_type.h @@ -22,15 +22,13 @@ namespace arrow::matlab::type::proxy { class Time32Type : public arrow::matlab::type::proxy::TimeType { + public: + Time32Type(std::shared_ptr time32_type); - public: - Time32Type(std::shared_ptr time32_type); - - ~Time32Type() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + ~Time32Type() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); }; -} - +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.cc index ab494c909ac56..e2fea97b6ac51 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.cc @@ -19,9 +19,11 @@ namespace arrow::matlab::type::proxy { - Time64Type::Time64Type(std::shared_ptr time64_type) : TimeType(std::move(time64_type)) {} +Time64Type::Time64Type(std::shared_ptr time64_type) + : TimeType(std::move(time64_type)) {} - libmexclass::proxy::MakeResult Time64Type::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - return make_time_type(constructor_arguments); - } +libmexclass::proxy::MakeResult Time64Type::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + return make_time_type(constructor_arguments); } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.h index fff92aa2a14e8..10d56b68934ff 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time64_type.h @@ -22,15 +22,13 @@ namespace arrow::matlab::type::proxy { class Time64Type : public arrow::matlab::type::proxy::TimeType { + public: + Time64Type(std::shared_ptr time64_type); - public: - Time64Type(std::shared_ptr time64_type); - - ~Time64Type() {} - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + ~Time64Type() {} + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); }; -} - +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/time_type.cc index 16d5cc3193e9b..adab21d75cf59 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time_type.cc @@ -16,59 +16,60 @@ // under the License. #include "arrow/matlab/type/proxy/time_type.h" +#include "arrow/matlab/error/error.h" #include "arrow/matlab/type/proxy/traits.h" #include "arrow/matlab/type/time_unit.h" -#include "arrow/matlab/error/error.h" #include "arrow/util/utf8.h" namespace arrow::matlab::type::proxy { - TimeType::TimeType(std::shared_ptr time_type) : FixedWidthType(std::move(time_type)) { - REGISTER_METHOD(TimeType, getTimeUnit); - } +TimeType::TimeType(std::shared_ptr time_type) + : FixedWidthType(std::move(time_type)) { + REGISTER_METHOD(TimeType, getTimeUnit); +} - void TimeType::getTimeUnit(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void TimeType::getTimeUnit(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - auto time_type = std::static_pointer_cast(data_type); - const auto time_unit = time_type->unit(); - // Cast to uint8_t since there are only four supported TimeUnit enumeration values: - // Nanosecond, Microsecond, Millisecond, Second - auto timeunit_mda = factory.createScalar(static_cast(time_unit)); - context.outputs[0] = timeunit_mda; - } + auto time_type = std::static_pointer_cast(data_type); + const auto time_unit = time_type->unit(); + // Cast to uint8_t since there are only four supported TimeUnit enumeration values: + // Nanosecond, Microsecond, Millisecond, Second + auto timeunit_mda = factory.createScalar(static_cast(time_unit)); + context.outputs[0] = timeunit_mda; +} - template - libmexclass::proxy::MakeResult make_time_type(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - using namespace arrow::matlab::type; - using TimeTypeProxy = typename proxy::Traits::TypeProxy; +template +libmexclass::proxy::MakeResult make_time_type( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; + using namespace arrow::matlab::type; + using TimeTypeProxy = typename proxy::Traits::TypeProxy; - mda::StructArray opts = constructor_arguments[0]; + mda::StructArray opts = constructor_arguments[0]; - const mda::StringArray time_unit_mda = opts[0]["TimeUnit"]; + const mda::StringArray time_unit_mda = opts[0]["TimeUnit"]; - // extract the time unit - const std::u16string& time_unit_utf16 = time_unit_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto timeunit, - timeUnitFromString(time_unit_utf16), - error::UNKNOWN_TIME_UNIT_ERROR_ID); + // extract the time unit + const std::u16string& time_unit_utf16 = time_unit_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto timeunit, timeUnitFromString(time_unit_utf16), + error::UNKNOWN_TIME_UNIT_ERROR_ID); - // validate timeunit - MATLAB_ERROR_IF_NOT_OK(validateTimeUnit(timeunit), - error::INVALID_TIME_UNIT); + // validate timeunit + MATLAB_ERROR_IF_NOT_OK(validateTimeUnit(timeunit), error::INVALID_TIME_UNIT); - auto type = std::make_shared(timeunit); - auto time_type = std::static_pointer_cast(type); - return std::make_shared(std::move(time_type)); - } + auto type = std::make_shared(timeunit); + auto time_type = std::static_pointer_cast(type); + return std::make_shared(std::move(time_type)); +} - // Trigger code generation for the allowed template specializations using explicit instantiation. - template - libmexclass::proxy::MakeResult make_time_type(const libmexclass::proxy::FunctionArguments& constructor_arguments); +// Trigger code generation for the allowed template specializations using explicit +// instantiation. +template libmexclass::proxy::MakeResult make_time_type( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - template - libmexclass::proxy::MakeResult make_time_type(const libmexclass::proxy::FunctionArguments& constructor_arguments); +template libmexclass::proxy::MakeResult make_time_type( + const libmexclass::proxy::FunctionArguments& constructor_arguments); -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/time_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/time_type.h index 91d92aa4c40e2..d135e77921118 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/time_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/time_type.h @@ -22,18 +22,17 @@ namespace arrow::matlab::type::proxy { class TimeType : public arrow::matlab::type::proxy::FixedWidthType { + public: + TimeType(std::shared_ptr time_type); - public: - TimeType(std::shared_ptr time_type); + ~TimeType() {} - ~TimeType() {} - - protected: - void getTimeUnit(libmexclass::proxy::method::Context& context); + protected: + void getTimeUnit(libmexclass::proxy::method::Context& context); }; template -libmexclass::proxy::MakeResult make_time_type(const libmexclass::proxy::FunctionArguments& constructor_arguments); - +libmexclass::proxy::MakeResult make_time_type( + const libmexclass::proxy::FunctionArguments& constructor_arguments); -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.cc index 7397e96826e36..1f40253383f08 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.cc @@ -16,65 +16,67 @@ // under the License. #include "arrow/matlab/type/proxy/timestamp_type.h" -#include "arrow/matlab/type/time_unit.h" #include "arrow/matlab/error/error.h" +#include "arrow/matlab/type/time_unit.h" #include "arrow/util/utf8.h" namespace arrow::matlab::type::proxy { - TimestampType::TimestampType(std::shared_ptr timestamp_type) : FixedWidthType(std::move(timestamp_type)) { - REGISTER_METHOD(TimestampType, getTimeUnit); - REGISTER_METHOD(TimestampType, getTimeZone); - } +TimestampType::TimestampType(std::shared_ptr timestamp_type) + : FixedWidthType(std::move(timestamp_type)) { + REGISTER_METHOD(TimestampType, getTimeUnit); + REGISTER_METHOD(TimestampType, getTimeZone); +} + +libmexclass::proxy::MakeResult TimestampType::make( + const libmexclass::proxy::FunctionArguments& constructor_arguments) { + namespace mda = ::matlab::data; - libmexclass::proxy::MakeResult TimestampType::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - namespace mda = ::matlab::data; - - using TimestampTypeProxy = arrow::matlab::type::proxy::TimestampType; + using TimestampTypeProxy = arrow::matlab::type::proxy::TimestampType; - mda::StructArray opts = constructor_arguments[0]; + mda::StructArray opts = constructor_arguments[0]; - // Get the mxArray from constructor arguments - const mda::StringArray timezone_mda = opts[0]["TimeZone"]; - const mda::StringArray timeunit_mda = opts[0]["TimeUnit"]; + // Get the mxArray from constructor arguments + const mda::StringArray timezone_mda = opts[0]["TimeZone"]; + const mda::StringArray timeunit_mda = opts[0]["TimeUnit"]; - // extract the time zone - const std::u16string& utf16_timezone = timezone_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto timezone, - arrow::util::UTF16StringToUTF8(utf16_timezone), - error::UNICODE_CONVERSION_ERROR_ID); + // extract the time zone + const std::u16string& utf16_timezone = timezone_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto timezone, + arrow::util::UTF16StringToUTF8(utf16_timezone), + error::UNICODE_CONVERSION_ERROR_ID); - // extract the time unit - const std::u16string& utf16_timeunit = timeunit_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto timeunit, - arrow::matlab::type::timeUnitFromString(utf16_timeunit), - error::UNKNOWN_TIME_UNIT_ERROR_ID); + // extract the time unit + const std::u16string& utf16_timeunit = timeunit_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto timeunit, + arrow::matlab::type::timeUnitFromString(utf16_timeunit), + error::UNKNOWN_TIME_UNIT_ERROR_ID); - auto type = arrow::timestamp(timeunit, timezone); - auto time_type = std::static_pointer_cast(type); - return std::make_shared(std::move(time_type)); - } + auto type = arrow::timestamp(timeunit, timezone); + auto time_type = std::static_pointer_cast(type); + return std::make_shared(std::move(time_type)); +} - void TimestampType::getTimeZone(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void TimestampType::getTimeZone(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - auto timestamp_type = std::static_pointer_cast(data_type); - const auto timezone_utf8 = timestamp_type->timezone(); - MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto timezone_utf16, - arrow::util::UTF8StringToUTF16(timezone_utf8), - context, error::UNICODE_CONVERSION_ERROR_ID); - auto timezone_mda = factory.createScalar(timezone_utf16); - context.outputs[0] = timezone_mda; - } + auto timestamp_type = std::static_pointer_cast(data_type); + const auto timezone_utf8 = timestamp_type->timezone(); + MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto timezone_utf16, + arrow::util::UTF8StringToUTF16(timezone_utf8), + context, error::UNICODE_CONVERSION_ERROR_ID); + auto timezone_mda = factory.createScalar(timezone_utf16); + context.outputs[0] = timezone_mda; +} - void TimestampType::getTimeUnit(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; +void TimestampType::getTimeUnit(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - auto timestamp_type = std::static_pointer_cast(data_type); - const auto timeunit = timestamp_type->unit(); - auto timeunit_mda = factory.createScalar(static_cast(timeunit)); - context.outputs[0] = timeunit_mda; - } + auto timestamp_type = std::static_pointer_cast(data_type); + const auto timeunit = timestamp_type->unit(); + auto timeunit_mda = factory.createScalar(static_cast(timeunit)); + context.outputs[0] = timeunit_mda; } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.h b/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.h index 93a6585311062..fbb5f2aaec74e 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/timestamp_type.h @@ -23,20 +23,18 @@ namespace arrow::matlab::type::proxy { class TimestampType : public arrow::matlab::type::proxy::FixedWidthType { - - public: - TimestampType(std::shared_ptr timestamp_type); + public: + TimestampType(std::shared_ptr timestamp_type); - ~TimestampType() {} + ~TimestampType() {} - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); + static libmexclass::proxy::MakeResult make( + const libmexclass::proxy::FunctionArguments& constructor_arguments); - protected: + protected: + void getTimeZone(libmexclass::proxy::method::Context& context); - void getTimeZone(libmexclass::proxy::method::Context& context); - - void getTimeUnit(libmexclass::proxy::method::Context& context); + void getTimeUnit(libmexclass::proxy::method::Context& context); }; -} - +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/traits.h b/matlab/src/cpp/arrow/matlab/type/proxy/traits.h index 799a40cd67450..697e8c4beb419 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/traits.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/traits.h @@ -19,96 +19,96 @@ #include "arrow/type_fwd.h" -#include "arrow/matlab/type/proxy/primitive_ctype.h" -#include "arrow/matlab/type/proxy/timestamp_type.h" -#include "arrow/matlab/type/proxy/time32_type.h" -#include "arrow/matlab/type/proxy/time64_type.h" #include "arrow/matlab/type/proxy/date32_type.h" #include "arrow/matlab/type/proxy/date64_type.h" +#include "arrow/matlab/type/proxy/primitive_ctype.h" #include "arrow/matlab/type/proxy/string_type.h" +#include "arrow/matlab/type/proxy/time32_type.h" +#include "arrow/matlab/type/proxy/time64_type.h" +#include "arrow/matlab/type/proxy/timestamp_type.h" namespace arrow::matlab::type::proxy { - template - struct Traits; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = PrimitiveCType; - }; - - template <> - struct Traits { - using TypeProxy = StringType; - }; - - template <> - struct Traits { - using TypeProxy = TimestampType; - }; - - template <> - struct Traits { - using TypeProxy = Time32Type; - }; - - template <> - struct Traits { - using TypeProxy = Time64Type; - }; - - template <> - struct Traits { - using TypeProxy = Date32Type; - }; - - template <> - struct Traits { - using TypeProxy = Date64Type; - }; -} +template +struct Traits; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = PrimitiveCType; +}; + +template <> +struct Traits { + using TypeProxy = StringType; +}; + +template <> +struct Traits { + using TypeProxy = TimestampType; +}; + +template <> +struct Traits { + using TypeProxy = Time32Type; +}; + +template <> +struct Traits { + using TypeProxy = Time64Type; +}; + +template <> +struct Traits { + using TypeProxy = Date32Type; +}; + +template <> +struct Traits { + using TypeProxy = Date64Type; +}; +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/type.cc b/matlab/src/cpp/arrow/matlab/type/proxy/type.cc index 1cbaaf328ee86..b1deaf556ebcb 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/type.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/type.cc @@ -15,93 +15,87 @@ // specific language governing permissions and limitations // under the License. - +#include "arrow/matlab/type/proxy/type.h" #include "arrow/matlab/error/error.h" #include "arrow/matlab/index/validate.h" -#include "arrow/matlab/type/proxy/type.h" #include "arrow/matlab/type/proxy/field.h" #include "libmexclass/proxy/ProxyManager.h" namespace arrow::matlab::type::proxy { - Type::Type(std::shared_ptr type) : data_type{std::move(type)} { - REGISTER_METHOD(Type, getTypeID); - REGISTER_METHOD(Type, getNumFields); - REGISTER_METHOD(Type, getFieldByIndex); - REGISTER_METHOD(Type, isEqual); - } +Type::Type(std::shared_ptr type) : data_type{std::move(type)} { + REGISTER_METHOD(Type, getTypeID); + REGISTER_METHOD(Type, getNumFields); + REGISTER_METHOD(Type, getFieldByIndex); + REGISTER_METHOD(Type, isEqual); +} - std::shared_ptr Type::unwrap() { - return data_type; - } +std::shared_ptr Type::unwrap() { return data_type; } - void Type::getTypeID(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - auto type_number_mda = factory.createScalar(static_cast(data_type->id())); - context.outputs[0] = type_number_mda; - } +void Type::getTypeID(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - void Type::getNumFields(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - auto num_fields_mda = factory.createScalar(data_type->num_fields()); - context.outputs[0] = num_fields_mda; - } + auto type_number_mda = factory.createScalar(static_cast(data_type->id())); + context.outputs[0] = type_number_mda; +} - void Type::getFieldByIndex(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - mda::ArrayFactory factory; - - mda::StructArray args = context.inputs[0]; - const mda::TypedArray index_mda = args[0]["Index"]; - const auto matlab_index = int32_t(index_mda[0]); - - // Validate there is at least 1 field - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateNonEmptyContainer(data_type->num_fields()), - context, - error::INDEX_EMPTY_CONTAINER); - - // Validate the matlab index provided is within the range [1, num_fields] - MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( - index::validateInRange(matlab_index, data_type->num_fields()), - context, - error::INDEX_OUT_OF_RANGE); - - // Note: MATLAB uses 1-based indexing, so subtract 1. - // arrow::DataType::field does not do any bounds checking. - const int32_t index = matlab_index - 1; - - auto field = data_type->field(index); - auto field_proxy = std::make_shared(std::move(field)); - auto field_proxy_id = libmexclass::proxy::ProxyManager::manageProxy(field_proxy); - context.outputs[0] = factory.createScalar(field_proxy_id); - } +void Type::getNumFields(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; - void Type::isEqual(libmexclass::proxy::method::Context& context) { - namespace mda = ::matlab::data; - - const mda::TypedArray type_proxy_ids = context.inputs[0]; - - bool is_equal = true; - const auto check_metadata = false; - for (const auto& type_proxy_id : type_proxy_ids) { - // Retrieve the Type proxy from the ProxyManager - auto proxy = libmexclass::proxy::ProxyManager::getProxy(type_proxy_id); - auto type_proxy = std::static_pointer_cast(proxy); - auto type_to_compare = type_proxy->unwrap(); - - if (!data_type->Equals(type_to_compare, check_metadata)) { - is_equal = false; - break; - } - } - mda::ArrayFactory factory; - context.outputs[0] = factory.createScalar(is_equal); - } + auto num_fields_mda = factory.createScalar(data_type->num_fields()); + context.outputs[0] = num_fields_mda; } +void Type::getFieldByIndex(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + mda::ArrayFactory factory; + + mda::StructArray args = context.inputs[0]; + const mda::TypedArray index_mda = args[0]["Index"]; + const auto matlab_index = int32_t(index_mda[0]); + + // Validate there is at least 1 field + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + index::validateNonEmptyContainer(data_type->num_fields()), context, + error::INDEX_EMPTY_CONTAINER); + + // Validate the matlab index provided is within the range [1, num_fields] + MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT( + index::validateInRange(matlab_index, data_type->num_fields()), context, + error::INDEX_OUT_OF_RANGE); + + // Note: MATLAB uses 1-based indexing, so subtract 1. + // arrow::DataType::field does not do any bounds checking. + const int32_t index = matlab_index - 1; + + auto field = data_type->field(index); + auto field_proxy = std::make_shared(std::move(field)); + auto field_proxy_id = libmexclass::proxy::ProxyManager::manageProxy(field_proxy); + context.outputs[0] = factory.createScalar(field_proxy_id); +} + +void Type::isEqual(libmexclass::proxy::method::Context& context) { + namespace mda = ::matlab::data; + + const mda::TypedArray type_proxy_ids = context.inputs[0]; + + bool is_equal = true; + const auto check_metadata = false; + for (const auto& type_proxy_id : type_proxy_ids) { + // Retrieve the Type proxy from the ProxyManager + auto proxy = libmexclass::proxy::ProxyManager::getProxy(type_proxy_id); + auto type_proxy = std::static_pointer_cast(proxy); + auto type_to_compare = type_proxy->unwrap(); + + if (!data_type->Equals(type_to_compare, check_metadata)) { + is_equal = false; + break; + } + } + mda::ArrayFactory factory; + context.outputs[0] = factory.createScalar(is_equal); +} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/type.h b/matlab/src/cpp/arrow/matlab/type/proxy/type.h index 3a6b287a9254e..62f73dc3013bf 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/type.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/type.h @@ -24,24 +24,23 @@ namespace arrow::matlab::type::proxy { class Type : public libmexclass::proxy::Proxy { - public: - Type(std::shared_ptr type); - - virtual ~Type() {} + public: + Type(std::shared_ptr type); - std::shared_ptr unwrap(); + virtual ~Type() {} - protected: + std::shared_ptr unwrap(); - void getTypeID(libmexclass::proxy::method::Context& context); + protected: + void getTypeID(libmexclass::proxy::method::Context& context); - void getNumFields(libmexclass::proxy::method::Context& context); + void getNumFields(libmexclass::proxy::method::Context& context); - void getFieldByIndex(libmexclass::proxy::method::Context& context); + void getFieldByIndex(libmexclass::proxy::method::Context& context); - void isEqual(libmexclass::proxy::method::Context& context); + void isEqual(libmexclass::proxy::method::Context& context); - std::shared_ptr data_type; + std::shared_ptr data_type; }; -} +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc index df2d561b69df7..bc2921908c474 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc +++ b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc @@ -17,61 +17,80 @@ #include "arrow/matlab/type/proxy/wrap.h" -#include "arrow/matlab/type/proxy/primitive_ctype.h" -#include "arrow/matlab/type/proxy/timestamp_type.h" -#include "arrow/matlab/type/proxy/time32_type.h" -#include "arrow/matlab/type/proxy/time64_type.h" #include "arrow/matlab/type/proxy/date32_type.h" #include "arrow/matlab/type/proxy/date64_type.h" -#include "arrow/matlab/type/proxy/string_type.h" #include "arrow/matlab/type/proxy/list_type.h" +#include "arrow/matlab/type/proxy/primitive_ctype.h" +#include "arrow/matlab/type/proxy/string_type.h" #include "arrow/matlab/type/proxy/struct_type.h" +#include "arrow/matlab/type/proxy/time32_type.h" +#include "arrow/matlab/type/proxy/time64_type.h" +#include "arrow/matlab/type/proxy/timestamp_type.h" namespace arrow::matlab::type::proxy { - arrow::Result> wrap(const std::shared_ptr& type) { - using ID = arrow::Type::type; - switch (type->id()) { - case ID::BOOL: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::UINT8: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::UINT16: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::UINT32: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::UINT64: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::INT8: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::INT16: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::INT32: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::INT64: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::FLOAT: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::DOUBLE: - return std::make_shared>(std::static_pointer_cast(type)); - case ID::TIMESTAMP: - return std::make_shared(std::static_pointer_cast(type)); - case ID::TIME32: - return std::make_shared(std::static_pointer_cast(type)); - case ID::TIME64: - return std::make_shared(std::static_pointer_cast(type)); - case ID::DATE32: - return std::make_shared(std::static_pointer_cast(type)); - case ID::DATE64: - return std::make_shared(std::static_pointer_cast(type)); - case ID::STRING: - return std::make_shared(std::static_pointer_cast(type)); - case ID::LIST: - return std::make_shared(std::static_pointer_cast(type)); - case ID::STRUCT: - return std::make_shared(std::static_pointer_cast(type)); - default: - return arrow::Status::NotImplemented("Unsupported DataType: " + type->ToString()); - } - } +arrow::Result> wrap( + const std::shared_ptr& type) { + using ID = arrow::Type::type; + switch (type->id()) { + case ID::BOOL: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::UINT8: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::UINT16: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::UINT32: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::UINT64: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::INT8: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::INT16: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::INT32: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::INT64: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::FLOAT: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::DOUBLE: + return std::make_shared>( + std::static_pointer_cast(type)); + case ID::TIMESTAMP: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::TIME32: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::TIME64: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::DATE32: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::DATE64: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::STRING: + return std::make_shared( + std::static_pointer_cast(type)); + case ID::LIST: + return std::make_shared(std::static_pointer_cast(type)); + case ID::STRUCT: + return std::make_shared( + std::static_pointer_cast(type)); + default: + return arrow::Status::NotImplemented("Unsupported DataType: " + type->ToString()); + } } +} // namespace arrow::matlab::type::proxy diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.h b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.h index f93240757c4c1..7d433b3e4906b 100644 --- a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.h +++ b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.h @@ -17,8 +17,8 @@ #pragma once -#include "arrow/type.h" #include "arrow/result.h" +#include "arrow/type.h" #include "arrow/matlab/type/proxy/type.h" @@ -26,5 +26,4 @@ namespace arrow::matlab::type::proxy { arrow::Result> wrap(const std::shared_ptr& type); - } diff --git a/matlab/src/cpp/arrow/matlab/type/time_unit.cc b/matlab/src/cpp/arrow/matlab/type/time_unit.cc index 7a7cf7f350828..ef53249b8b180 100644 --- a/matlab/src/cpp/arrow/matlab/type/time_unit.cc +++ b/matlab/src/cpp/arrow/matlab/type/time_unit.cc @@ -20,39 +20,41 @@ namespace arrow::matlab::type { - arrow::Result timeUnitFromString(std::u16string_view unit_str) { - if (unit_str == u"Second") { - return arrow::TimeUnit::type::SECOND; - } else if (unit_str == u"Millisecond") { - return arrow::TimeUnit::type::MILLI; - } else if (unit_str == u"Microsecond") { - return arrow::TimeUnit::type::MICRO; - } else if (unit_str == u"Nanosecond") { - return arrow::TimeUnit::type::NANO; - } else { - auto maybe_utf8 = arrow::util::UTF16StringToUTF8(unit_str); - auto msg = maybe_utf8.ok() ? "Unknown time unit string: " + *maybe_utf8 : "Unknown time unit string"; - return arrow::Status::Invalid(msg); - } - } +arrow::Result timeUnitFromString(std::u16string_view unit_str) { + if (unit_str == u"Second") { + return arrow::TimeUnit::type::SECOND; + } else if (unit_str == u"Millisecond") { + return arrow::TimeUnit::type::MILLI; + } else if (unit_str == u"Microsecond") { + return arrow::TimeUnit::type::MICRO; + } else if (unit_str == u"Nanosecond") { + return arrow::TimeUnit::type::NANO; + } else { + auto maybe_utf8 = arrow::util::UTF16StringToUTF8(unit_str); + auto msg = maybe_utf8.ok() ? "Unknown time unit string: " + *maybe_utf8 + : "Unknown time unit string"; + return arrow::Status::Invalid(msg); + } +} - template<> - arrow::Status validateTimeUnit(arrow::TimeUnit::type unit) { - using arrow::TimeUnit; - if (unit == TimeUnit::type::SECOND || unit == TimeUnit::type::MILLI) { - return arrow::Status::OK(); - } else { - return arrow::Status::Invalid("TimeUnit for Time32 must be Second or Millisecond"); - } - } +template <> +arrow::Status validateTimeUnit(arrow::TimeUnit::type unit) { + using arrow::TimeUnit; + if (unit == TimeUnit::type::SECOND || unit == TimeUnit::type::MILLI) { + return arrow::Status::OK(); + } else { + return arrow::Status::Invalid("TimeUnit for Time32 must be Second or Millisecond"); + } +} - template<> - arrow::Status validateTimeUnit(arrow::TimeUnit::type unit) { - using arrow::TimeUnit; - if (unit == TimeUnit::type::MICRO || unit == TimeUnit::type::NANO) { - return arrow::Status::OK(); - } else { - return arrow::Status::Invalid("TimeUnit for Time64 must be Microsecond or Nanosecond"); - } - } +template <> +arrow::Status validateTimeUnit(arrow::TimeUnit::type unit) { + using arrow::TimeUnit; + if (unit == TimeUnit::type::MICRO || unit == TimeUnit::type::NANO) { + return arrow::Status::OK(); + } else { + return arrow::Status::Invalid( + "TimeUnit for Time64 must be Microsecond or Nanosecond"); + } } +} // namespace arrow::matlab::type diff --git a/matlab/src/cpp/arrow/matlab/type/time_unit.h b/matlab/src/cpp/arrow/matlab/type/time_unit.h index 2470fc53cf434..c25006211391a 100644 --- a/matlab/src/cpp/arrow/matlab/type/time_unit.h +++ b/matlab/src/cpp/arrow/matlab/type/time_unit.h @@ -15,16 +15,16 @@ // specific language governing permissions and limitations // under the License. -#include "arrow/type_fwd.h" #include "arrow/result.h" +#include "arrow/type_fwd.h" #include namespace arrow::matlab::type { - arrow::Result timeUnitFromString(std::u16string_view unit_str); +arrow::Result timeUnitFromString(std::u16string_view unit_str); - template - arrow::Status validateTimeUnit(arrow::TimeUnit::type unit); +template +arrow::Status validateTimeUnit(arrow::TimeUnit::type unit); -} +} // namespace arrow::matlab::type