This is an automated email from the ASF dual-hosted git repository.
kevingurney pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new c37059ad7b GH-38015: [MATLAB] Add `arrow.buffer.Buffer` class to the
MATLAB Interface (#38020)
c37059ad7b is described below
commit c37059ad7b87f0cbb681f6388aca0e3f02860351
Author: sgilmore10 <[email protected]>
AuthorDate: Tue Oct 10 10:29:24 2023 -0400
GH-38015: [MATLAB] Add `arrow.buffer.Buffer` class to the MATLAB Interface
(#38020)
### Rationale for this change
To unblock use cases that are not satisfied by the default Arrow -> MATLAB
conversions (i.e. the `toMATLAB()` on `arrow.array.Array`), we would like
expose the underlying Arrow data representation as a property on
`arrow.array.Array`. One possible name for this property would be `DataLayout`,
which would be an `arrow.array.DataLayout` object. Note, this class does not
yet exist, so we would have to add it.
For example, the `DataLayout` property for temporal array types would
return an object of the following class type:
```matlab
classdef TemporalDataLayout < arrow.array.DataLayout
properties
Values % an arrow.array.Int32Array or an arrow.array.Int64Array
Valid % an arrow.buffer.Buffer
end
end
```
However, the `Valid` property on this class would need to be an
`arrow.buffer.Buffer` object, which does not yet exist in the MATLAB interface.
Therefore, it would be helpful to first add the `arrow.buffer.Buffer` class
before adding the `DataLayout` property/class hierarchy. It's worth mentioning
that adding `arrow.buffer.Buffer` will open up additional advanced use cases in
the future.
### What changes are included in this PR?
Added `arrow.buffer.Buffer` MATLAB class.
*Properties of `arrow.buffer.Buffer`*
1. `NumBytes` - a scalar `int64` value representing the size of the
buffer in bytes.
*Methods of `arrow.buffer.Buffer`*
1. `toMATLAB` - returns the data in the buffer as `Nx1` `uint8` vector,
where `N` is the number of bytes.
2. `fromMATLAB(data)` - Static method that creates an `arrow.buffer.Buffer`
from a numeric array.
**Example:**
```matlab
>> dataIn = [1 2];
>> buffer = arrow.buffer.Buffer.fromMATLAB(dataIn)
buffer =
Buffer with properties:
NumBytes: 16
>> dataOut = toMATLAB(buffer)
dataOut =
16×1 uint8 column vector
0
0
0
0
0
0
240
63
0
0
0
0
0
0
0
64
% Reinterpret bit pattern as a double array
>> toDouble = typecast(dataOut, "double")
toDouble =
1
2
```
### Are these changes tested?
Yes. Added a new test class called `tBuffer.m`
### Are there any user-facing changes?
Yes. Users can now create `arrow.buffer.Buffer` objects via the
`fromMATLAB` static method. However, there's not much users can do with this
object as of now. We implemented this class to facilitate adding `DataLayout`
property to `arrow.array.Array`, as described in the **Rational for this
change** section.
* Closes: #38015
Authored-by: Sarah Gilmore <[email protected]>
Signed-off-by: Kevin Gurney <[email protected]>
---
matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc | 96 ++++++++++
matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h | 46 +++++
matlab/src/cpp/arrow/matlab/error/error.h | 1 +
matlab/src/cpp/arrow/matlab/proxy/factory.cc | 2 +
matlab/src/matlab/+arrow/+buffer/Buffer.m | 81 ++++++++
matlab/test/arrow/buffer/tBuffer.m | 209 +++++++++++++++++++++
matlab/tools/cmake/BuildMatlabArrowInterface.cmake | 4 +-
7 files changed, 438 insertions(+), 1 deletion(-)
diff --git a/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc
b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc
new file mode 100644
index 0000000000..633b82d9fa
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.cc
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// 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"
+#include "libmexclass/proxy/ProxyManager.h"
+
+namespace arrow::matlab::buffer::proxy {
+
+ Buffer::Buffer(std::shared_ptr<arrow::Buffer> 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<uint8_t> values_mda = opts[0]["Values"];
+ auto buffer = std::make_shared<MatlabBuffer>(values_mda);
+ return std::make_shared<BufferProxy>(std::move(buffer));
+ }
+
+ std::shared_ptr<arrow::Buffer> 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<uint64_t> 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::Buffer>(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);
+ }
+
+ 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<uint8_t>({static_cast<size_t>(num_bytes), 1}, data_begin,
data_end);
+ }
+
+}
\ 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
new file mode 100644
index 0000000000..bb6dc5e4c5
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/buffer/proxy/buffer.h
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "arrow/buffer.h"
+
+#include "libmexclass/proxy/Proxy.h"
+
+namespace arrow::matlab::buffer::proxy {
+
+class Buffer : public libmexclass::proxy::Proxy {
+ public:
+ Buffer(std::shared_ptr<arrow::Buffer> buffer);
+
+ ~Buffer() {}
+
+ std::shared_ptr<arrow::Buffer> unwrap();
+
+ static libmexclass::proxy::MakeResult make(const
libmexclass::proxy::FunctionArguments& constructor_arguments);
+
+ protected:
+ void getNumBytes(libmexclass::proxy::method::Context& context);
+
+ void toMATLAB(libmexclass::proxy::method::Context& context);
+
+ void isEqual(libmexclass::proxy::method::Context& context);
+
+ std::shared_ptr<arrow::Buffer> buffer;
+};
+
+}
diff --git a/matlab/src/cpp/arrow/matlab/error/error.h
b/matlab/src/cpp/arrow/matlab/error/error.h
index 347bc25b5f..b8376c0a06 100644
--- a/matlab/src/cpp/arrow/matlab/error/error.h
+++ b/matlab/src/cpp/arrow/matlab/error/error.h
@@ -198,4 +198,5 @@ namespace arrow::matlab::error {
static const char* STRUCT_ARRAY_MAKE_FAILED =
"arrow:array:StructArrayMakeFailed";
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";
}
diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc
b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
index 62ed84fedc..3091d248f8 100644
--- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc
+++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
@@ -40,6 +40,7 @@
#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 "factory.h"
@@ -65,6 +66,7 @@ libmexclass::proxy::MakeResult Factory::make_proxy(const
ClassName& class_name,
REGISTER_PROXY(arrow.array.proxy.Date32Array ,
arrow::matlab::array::proxy::NumericArray<arrow::Date32Type>);
REGISTER_PROXY(arrow.array.proxy.Date64Array ,
arrow::matlab::array::proxy::NumericArray<arrow::Date64Type>);
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);
diff --git a/matlab/src/matlab/+arrow/+buffer/Buffer.m
b/matlab/src/matlab/+arrow/+buffer/Buffer.m
new file mode 100644
index 0000000000..6c46276810
--- /dev/null
+++ b/matlab/src/matlab/+arrow/+buffer/Buffer.m
@@ -0,0 +1,81 @@
+%BUFFER Represents a block of contiguous memory with a specified size.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements. See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License. You may obtain a copy of the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied. See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef Buffer < matlab.mixin.Scalar
+
+ properties (Dependent, GetAccess=public, SetAccess=private)
+ NumBytes
+ end
+
+ properties (Hidden, GetAccess=public, SetAccess=private)
+ Proxy
+ end
+
+ methods
+ function obj = Buffer(proxy)
+ arguments
+ proxy(1, 1) libmexclass.proxy.Proxy {validate(proxy,
"arrow.buffer.proxy.Buffer")}
+ end
+ import arrow.internal.proxy.validate
+ obj.Proxy = proxy;
+ end
+
+ function numBytes = get.NumBytes(obj)
+ numBytes = obj.Proxy.getNumBytes();
+ end
+
+ function data = toMATLAB(obj)
+ data = obj.Proxy.toMATLAB();
+ end
+
+ function tf = isequal(obj, varargin)
+ narginchk(2, inf);
+ tf = false;
+
+ bufferProxyIDs = zeros([1 numel(varargin)], "uint64");
+ for ii = 1:numel(varargin)
+ maybeBuffer = varargin{ii};
+ if ~isa(maybeBuffer, "arrow.buffer.Buffer")
+ % If maybeBuffer is not an instance of
+ % arrow.buffer.Buffer, return false early.
+ return;
+ end
+ % Otherwise, extract the proxy ID associated with
+ % maybeBuffer.
+ bufferProxyIDs(ii) = maybeBuffer.Proxy.ID;
+ end
+
+ % Invoke the isEqual method on the Buffer Proxy class.
+ tf = obj.Proxy.isEqual(bufferProxyIDs);
+ end
+ end
+
+ methods (Static, Hidden)
+ function buffer = fromMATLAB(data)
+ arguments
+ data(:, 1) {mustBeNumeric, mustBeNonsparse, mustBeReal}
+ end
+
+ % Re-interpret bit pattern as uint8s without changing the
+ % underlying data.
+ data = typecast(data, "uint8");
+ args = struct(Values=data);
+ proxy = arrow.internal.proxy.create("arrow.buffer.proxy.Buffer",
args);
+ buffer = arrow.buffer.Buffer(proxy);
+ end
+ end
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/buffer/tBuffer.m
b/matlab/test/arrow/buffer/tBuffer.m
new file mode 100644
index 0000000000..d58af2fc9d
--- /dev/null
+++ b/matlab/test/arrow/buffer/tBuffer.m
@@ -0,0 +1,209 @@
+%TBUFFER Unit tests for arrow.buffer.Buffer
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements. See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License. You may obtain a copy of the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied. See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef tBuffer < matlab.unittest.TestCase
+
+ methods (Test)
+ function Smoke(testCase)
+ import arrow.buffer.Buffer
+
+ source = uint8([1 2 3]);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyInstanceOf(buffer, "arrow.buffer.Buffer");
+ end
+
+ function fromMATLABUInt8Scalar(testCase)
+ % Verifies fromMATLAB returns the expected arrow.buffer.Buffer
+ % instance when given a scalar uint8 value.
+
+ import arrow.buffer.Buffer
+
+ source = uint8(20);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(1));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, source);
+ end
+
+ function fromMATLABFromEmptyUInt8(testCase)
+ % Verifies fromMATLAB returns the expected arrow.buffer.Buffer
+ % value when given an empty uint8 array.
+
+ import arrow.buffer.Buffer
+
+ % Create buffer from 0x0 uint8 array
+ source = uint8.empty(0, 0);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(0));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, uint8.empty(0, 1));
+
+ % Create buffer from 0x1 uint8 array
+ source = uint8.empty(0, 1);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(0));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, uint8.empty(0, 1));
+
+ % Create buffer from 1x0 uint8 array
+ source = uint8.empty(1, 0);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(0));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, uint8.empty(0, 1));
+ end
+
+ function fromMATLABUInt8Vector(testCase)
+ % Verifies fromMATLAB returns the expected arrow.buffer.Buffer
+ % value when given a uint8 vector.
+
+ import arrow.buffer.Buffer
+
+ % Create buffer from 1x3 uint8 array
+ source = uint8([3 9 27]);
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(3));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, uint8([3 9 27]'));
+
+ % Create buffer from 3x1 uint8 array
+ source = uint8([3 9 27]');
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(3));
+ values = toMATLAB(buffer);
+ testCase.verifyEqual(values, uint8([3 9 27]'));
+ end
+
+ function fromMATLABDoubleVector(testCase)
+ % Verifies fromMATLAB returns the expected arrow.buffer.Buffer
+ % value when given a double vector.
+
+ import arrow.buffer.Buffer
+
+ % Create buffer from 1x3 double array
+ source = [3 9 27];
+ buffer = Buffer.fromMATLAB(source);
+ % Since the input vector is a 1x3 double (i.e. 64-bit floating
+ % point value) array - each of the 3 elements takes up 8 bytes
+ % (3 elements * 8 bytes per element = 24 bytes).
+ testCase.verifyEqual(buffer.NumBytes, int64(24));
+ values = toMATLAB(buffer);
+ expected = typecast(source', "uint8");
+ testCase.verifyEqual(values, expected);
+ testCase.verifyEqual(typecast(values, "double"), source');
+
+ % Create buffer from 3x1 double array
+ source = [3 9 27]';
+ buffer = Buffer.fromMATLAB(source);
+ testCase.verifyEqual(buffer.NumBytes, int64(24));
+ values = toMATLAB(buffer);
+ expected = typecast(source, "uint8");
+ testCase.verifyEqual(values, expected);
+ testCase.verifyEqual(typecast(values, "double"), source);
+ end
+
+ function fromMATLABNonNumericError(testCase)
+ % Verify fromMATLAB throws an error if given a non-numeric
+ % array as input.
+ import arrow.buffer.Buffer
+
+ fcn = @() Buffer.fromMATLAB(true);
+ testCase.verifyError(fcn, "MATLAB:validators:mustBeNumeric");
+
+ fcn = @() Buffer.fromMATLAB("A");
+ testCase.verifyError(fcn, "MATLAB:validators:mustBeNumeric");
+
+ fcn = @() Buffer.fromMATLAB(datetime(2023, 1, 1));
+ testCase.verifyError(fcn, "MATLAB:validators:mustBeNumeric");
+ end
+
+ function fromMATLABNonRealError(testCase)
+ % Verify fromMATLAB throws an error if given a complex
+ % numeric array as input.
+ import arrow.buffer.Buffer
+
+ fcn = @() Buffer.fromMATLAB(10 + 3i);
+ testCase.verifyError(fcn, "MATLAB:validators:mustBeReal");
+ end
+
+ function fromMATLABNonSparseError(testCase)
+ % Verify fromMATLAB throws an error if given a sparse
+ % numeric array as input.
+ import arrow.buffer.Buffer
+
+ fcn = @() Buffer.fromMATLAB(sparse(ones([5 1])));
+ testCase.verifyError(fcn, "MATLAB:validators:mustBeNonsparse");
+ end
+
+ function NumBytesNoSetter(testCase)
+ % Verifies the NumBytes property is not settable.
+
+ import arrow.buffer.Buffer
+
+ buffer = Buffer.fromMATLAB([1 2 3]);
+ fcn = @() setfield(buffer, "NumBytes", int64(1));
+ testCase.verifyError(fcn, "MATLAB:class:SetProhibited");
+ end
+
+ function IsEqualTrue(testCase)
+ % Verifies two buffers are considered equal if
+ % 1. They have the same size (NumBytes)
+ % 2. They contain the same bytes
+
+ import arrow.buffer.Buffer
+
+ % Compare two non-empty buffers
+ buffer1 = Buffer.fromMATLAB([1 2 3]);
+ buffer2 = Buffer.fromMATLAB([1 2 3]);
+ testCase.verifyTrue(isequal(buffer1, buffer2));
+
+ % Compare two buffers, one of which was created from a double
+ % array and the other created from a uint8 array. However, both
+ % arrays have the same bit pattern.
+ data = zeros([1 24], "uint8");
+ data([7 8 16 23 24]) = [240 63 64 8 64];
+ buffer3 = Buffer.fromMATLAB(data);
+ testCase.verifyTrue(isequal(buffer1, buffer3));
+
+ % Compare two empty buffers
+ buffer4 = Buffer.fromMATLAB([]);
+ buffer5 = Buffer.fromMATLAB([]);
+ testCase.verifyTrue(isequal(buffer4, buffer5));
+
+ % Compare more than two buffers
+ testCase.verifyTrue(isequal(buffer1, buffer2, buffer3));
+ end
+
+ function IsEqualFalse(testCase)
+ % Verifies two buffers are not considered equal if
+ % 1. They do not have the same size (NumBytes) OR
+ % 2. They do not contain the same bytes
+
+ import arrow.buffer.Buffer
+
+ buffer1 = Buffer.fromMATLAB([1 2 3]);
+ buffer2 = Buffer.fromMATLAB([1 3 2]);
+ buffer3 = Buffer.fromMATLAB([1 2 3 4]);
+ testCase.verifyFalse(isequal(buffer1, buffer2));
+ testCase.verifyFalse(isequal(buffer1, buffer3));
+ testCase.verifyFalse(isequal(buffer1, buffer2, buffer3));
+
+ % Compare a buffer to a string
+ testCase.verifyFalse(isequal(buffer1, "A"));
+ end
+ end
+end
\ No newline at end of file
diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
index 149a688b27..50daab6532 100644
--- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
+++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
@@ -73,7 +73,9 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES
"${CMAKE_SOURCE_DIR}/src/cpp/a
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/io/feather/proxy/reader.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/io/csv/proxy/table_writer.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/io/csv/proxy/table_reader.cc"
-
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/index/validate.cc")
+
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/index/validate.cc"
+
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/buffer/proxy/buffer.cc")
+
set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy")
set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_SOURCES
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy/factory.cc")