8000 Buffer protocol proposal by mrkn · Pull Request #3261 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

Buffer protocol proposal #3261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Sep 25, 2020
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ff82d64
Add buffer protocol
mrkn Jun 26, 2020
add4635
Modify for some review comments
mrkn Jul 16, 2020
0a40fd8
Per-object buffer availability
mrkn Aug 24, 2020
185476f
Rename to MemoryView from Buffer and make compilable
mrkn Aug 24, 2020
12bc6ea
Support integral repeat count in memory view format
mrkn Aug 24, 2020
c97f9b8
Support 'x' for padding bytes
mrkn Aug 24, 2020
12dd500
Add rb_memory_view_parse_item_format
mrkn Aug 24, 2020
11426bc
Check type in rb_memory_view_register
mrkn Aug 24, 2020
ccbb0c9
Update dependencies in common.mk
mrkn Aug 25, 2020
a3b750e
Add test of MemoryView
mrkn Aug 25, 2020
aa6aaf1
Add test of rb_memory_view_init_as_byte_array
mrkn Aug 25, 2020
08c54b7
Add native size format test
mrkn Aug 25, 2020
0166ec6
Add MemoryView test utilities
mrkn Aug 28, 2020
51ee869
Add test of rb_memory_view_fill_contiguous_strides
mrkn Aug 28, 2020
934edd7
Skip spaces in format string
mrkn Sep 1, 2020
1b842a1
Support endianness specifiers
mrkn Sep 1, 2020
39a2a3f
Update documentation
mrkn Sep 1, 2020
01c3e0f
Support alignment
mrkn Sep 1, 2020
71800fc
Use RUBY_ALIGNOF
mrkn Sep 20, 2020
bdb94a0
Fix format parser to follow the pack format
mrkn Sep 20, 2020
72fee2b
Support the _ modifier
mrkn Sep 20, 2020
3d9bdce
Parse count specifiers in get_format_size function.
mrkn Sep 20, 2020
bff9105
Use STRUCT_ALIGNOF
mrkn Sep 21, 2020
cfad9fe
Fix test
mrkn Sep 22, 2020
be8a1ce
Fix test
mrkn Sep 23, 10000 2020
13de9f7
Fix total size for the case with tail padding
mrkn Sep 23, 2020
184fbef
Fix rb_memory_view_get_item_pointer
mrkn Sep 24, 2020
d264358
Fix rb_memory_view_parse_item_format again
mrkn Sep 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Parse count specifiers in get_format_size function.
  • Loading branch information
mrkn committed Sep 25, 2020
commit 3d9bdce5d43bd6825b8f04cfc9ecd59e6509e5c4
91 changes: 38 additions & 53 deletions memory_view.c
10000
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,17 @@ typedef enum {
} endianness_t;

static ssize_t
get_format_size(const char *format, bool *native_p, ssize_t *alignment, endianness_t *endianness, VALUE *error)
get_format_size(const char *format, bool *native_p, ssize_t *alignment, endianness_t *endianness, ssize_t *count, const char **next_format, VALUE *error)
{
RUBY_ASSERT(format != NULL);
RUBY_ASSERT(native_p != NULL);
RUBY_ASSERT(endianness != NULL);
RUBY_ASSERT(count != NULL);
RUBY_ASSERT(next_format != NULL);

*native_p = false;
*endianness = ENDIANNESS_NATIVE;
*count = 1;

const int type_char = *format;

Expand Down Expand Up @@ -174,6 +178,19 @@ get_format_size(const char *format, bool *native_p, ssize_t *alignment, endianne
break;
}

// parse count
int ch = format[i];
if ('0' <= ch && ch <= '9') {
ssize_t n = 0;
while ('0' <= (ch = format[i]) && ch <= '9') {
n = 10*n + ruby_digit36_to_number_table[ch];
++i;
}
*count = n;
}

*next_format = &format[i];

switch (type_char) {
case 'x': // padding
return 1;
Expand Down Expand Up @@ -248,6 +265,17 @@ get_format_size(const char *format, bool *native_p, ssize_t *alignment, endianne
}
}

static inline ssize_t
calculate_padding(ssize_t total, ssize_t alignment_size) {
if (alignment_size > 1) {
ssize_t res = total % alignment_size;
if (res > 0) {
return alignment_size - res;
}
}
return 0;
}

ssize_t
rb_memory_view_parse_item_format(const char *format,
rb_memory_view_item_component_t **members,
Expand All @@ -268,7 +296,6 @@ rb_memory_view_parse_item_format(const char *format,
}
while (*p) {
const char *q = p;
ssize_t count = 0;

// ignore spaces
if (ISSPACE(*p)) {
Expand All @@ -279,40 +306,19 @@ rb_memory_view_parse_item_format(const char *format,
bool native_size_p = false;
ssize_t alignment_size = 0;
endianness_t endianness = ENDIANNESS_NATIVE;
const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &error);
ssize_t count = 0;
const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &count, &p, &error);
if (size < 0) {
if (err) *err = q;
return -1;
}

const int type_char = *p;
p += 1 + (int)native_size_p + (endianness != ENDIANNESS_NATIVE);

// count modifiers
int ch = *p;
if ('0' <= ch && ch <= '9') {
while ('0' <= (ch = *p) && ch <= '9') {
count = 10*count + ruby_digit36_to_number_table[ch];
++p;
}
}
else {
count = 1;
}

ssize_t padding = 0;
if (alignment && alignment_size > 1) {
ssize_t res = total % alignment_size;
if (res > 0) {
padding = alignment_size - res;
}
}
const ssize_t padding = alignment ? calculate_padding(total, alignment_size) : 0;
total += padding + size * count;

if (type_char != 'x') {
if (*q != 'x') {
++len;
}

total += padding + size * count;
}

if (members && n_members) {
Expand All @@ -321,36 +327,15 @@ rb_memory_view_parse_item_format(const char *format,
ssize_t i = 0, offset = 0;
const char *p = format;
while (*p) {
ssize_t count = 0;
const int type_char = *p;

bool native_size_p;
ssize_t alignment_size = 0;
endianness_t endianness = ENDIANNESS_NATIVE;
const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, NULL);

const int type_char = *p;
p += 1 + (int)native_size_p + (endianness != ENDIANNESS_NATIVE);

// count modifiers
int ch = *p;
if ('0' <= ch && ch <= '9') {
while ('0' <= (ch = *p) && ch <= '9') {
count = 10*count + ruby_digit36_to_number_table[ch];
++p;
}
}
else {
count = 1;
}

ssize_t padding = 0;
if (alignment && alignment_size > 1) {
ssize_t res = offset % alignment_size;
if (res > 0) {
padding = alignment_size - res;
}
}
ssize_t count = 0;
const ssize_t size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &count, &p, NULL);

const ssize_t padding = alignment ? calculate_padding(offset, alignment_size) : 0;
offset += padding;

if (type_char != 'x') {
Expand Down
0