summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorKenta Murata <mrkn@users.noreply.github.com>2020-09-25 20:32:02 +0900
committerGitHub <noreply@github.com>2020-09-25 20:32:02 +0900
commit890bc2cdde4097390f3b71dfeaa36dd92ee0afe2 (patch)
treeb06641556aa22c6d4aa37200c00ffaf23f6838b7 /include
parent6eeacbbc3603bcd63a53e43a2002ca0872945e9f (diff)
Buffer protocol proposal (#3261)
* Add buffer protocol * Modify for some review comments * Per-object buffer availability * Rename to MemoryView from Buffer and make compilable * Support integral repeat count in memory view format * Support 'x' for padding bytes * Add rb_memory_view_parse_item_format * Check type in rb_memory_view_register * Update dependencies in common.mk * Add test of MemoryView * Add test of rb_memory_view_init_as_byte_array * Add native size format test * Add MemoryView test utilities * Add test of rb_memory_view_fill_contiguous_strides * Skip spaces in format string * Support endianness specifiers * Update documentation * Support alignment * Use RUBY_ALIGNOF * Fix format parser to follow the pack format * Support the _ modifier * Parse count specifiers in get_format_size function. * Use STRUCT_ALIGNOF * Fix test * Fix test * Fix total size for the case with tail padding * Fix rb_memory_view_get_item_pointer * Fix rb_memory_view_parse_item_format again
Notes
Notes: Merged-By: mrkn <mrkn@ruby-lang.org>
Diffstat (limited to 'include')
-rw-r--r--include/ruby/memory_view.h136
1 files changed, 136 insertions, 0 deletions
diff --git a/include/ruby/memory_view.h b/include/ruby/memory_view.h
new file mode 100644
index 0000000000..dc6c971593
--- /dev/null
+++ b/include/ruby/memory_view.h
@@ -0,0 +1,136 @@
+#ifndef RUBY_MEMORY_VIEW_H
+#define RUBY_MEMORY_VIEW_H 1
+/**
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ * @brief Memory View.
+ */
+
+#include "ruby/internal/dllexport.h"
+#include "ruby/internal/stdbool.h"
+#include "ruby/internal/value.h"
+#include "ruby/intern.h"
+
+enum ruby_memory_view_flags {
+ RUBY_MEMORY_VIEW_SIMPLE = 0,
+ RUBY_MEMORY_VIEW_WRITABLE = (1<<0),
+ RUBY_MEMORY_VIEW_FORMAT = (1<<1),
+ RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL = (1<<2),
+ RUBY_MEMORY_VIEW_STRIDES = (1<<3) | RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL,
+ RUBY_MEMORY_VIEW_ROW_MAJOR = (1<<4) | RUBY_MEMORY_VIEW_STRIDES,
+ RUBY_MEMORY_VIEW_COLUMN_MAJOR = (1<<5) | RUBY_MEMORY_VIEW_STRIDES,
+ RUBY_MEMORY_VIEW_ANY_CONTIGUOUS = RUBY_MEMORY_VIEW_ROW_MAJOR | RUBY_MEMORY_VIEW_COLUMN_MAJOR,
+ RUBY_MEMORY_VIEW_INDIRECT = (1<<6) | RUBY_MEMORY_VIEW_STRIDES,
+};
+
+typedef struct {
+ char format;
+ unsigned native_size_p: 1;
+ unsigned little_endian_p: 1;
+ size_t offset;
+ size_t size;
+ size_t repeat;
+} rb_memory_view_item_component_t;
+
+typedef struct {
+ /* The original object that have the memory exported via this memory view.
+ * The consumer of this memory view has the responsibility to call rb_gc_mark
+ * for preventing this obj collected by GC. */
+ VALUE obj;
+
+ /* The pointer to the exported memory. */
+ void *data;
+
+ /* The number of bytes in data. */
+ ssize_t len;
+
+ /* 1 for readonly memory, 0 for writable memory. */
+ int readonly;
+
+ /* A string to describe the format of an element, or NULL for unsigned byte.
+ * The format string is a sequence the following pack-template specifiers:
+ *
+ * c, C, s, s!, S, S!, n, v, i, i!, I, I!, l, l!,
+ * L, L!, N, V, f, e, g, d, E, G, j, J, x
+ *
+ * For example, "dd" for an element that consists of two double values,
+ * and "CCC" for an element that consists of three bytes, such as
+ * a RGB color triplet.
+ *
+ * Also, the value endianness can be explicitly specified by '<' or '>'
+ * following a value type specifier.
+ */
+ const char *format;
+
+ /* The number of bytes in each element.
+ * item_size should equal to rb_memory_view_item_size_from_format(format). */
+ ssize_t item_size;
+
+ struct {
+ /* The array of rb_memory_view_item_component_t that describes the
+ * item structure. */
+ rb_memory_view_item_component_t *components;
+
+ /* The number of components in an item. */
+ ssize_t length;
+ } item_desc;
+
+ /* The number of dimension. */
+ int ndim;
+
+ /* ndim size array indicating the number of elements in each dimension.
+ * This can be NULL when ndim == 1. */
+ ssize_t *shape;
+
+ /* ndim size array indicating the number of bytes to skip to go to the
+ * next element in each dimension. */
+ ssize_t *strides;
+
+ /* The offset in each dimension when this memory view exposes a nested array.
+ * Or, NULL when this memory view exposes a flat array. */
+ ssize_t *sub_offsets;
+
+ /* the private data for managing this exported memory */
+ void *const private;
+} rb_memory_view_t;
+
+typedef int (* rb_memory_view_get_func_t)(VALUE obj, rb_memory_view_t *view, int flags);
+typedef int (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view);
+typedef int (* rb_memory_view_available_p_func_t)(VALUE obj);
+
+typedef struct {
+ rb_memory_view_get_func_t get_func;
+ rb_memory_view_release_func_t release_func;
+ rb_memory_view_available_p_func_t available_p_func;
+} rb_memory_view_entry_t;
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+/* memory_view.c */
+bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry);
+
+#define rb_memory_view_is_contiguous(view) ( \
+ rb_memory_view_is_row_major_contiguous(view) \
+ || rb_memory_view_is_column_major_contiguous(view))
+
+int rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view);
+int rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view);
+void rb_memory_view_fill_contiguous_strides(const int ndim, const int item_size, const ssize_t *const shape, const int row_major_p, ssize_t *const strides);
+int rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const int readonly);
+ssize_t rb_memory_view_parse_item_format(const char *format,
+ rb_memory_view_item_component_t **members,
+ ssize_t *n_members, const char **err);
+ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err);
+void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices);
+
+int rb_memory_view_available_p(VALUE obj);
+int rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags);
+int rb_memory_view_release(rb_memory_view_t* memory_view);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RUBY_BUFFER_H */