arraybuffer 0.0.3 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/arraybuffer/arraybuffer.c +78 -36
- data/ext/arraybuffer/arraybuffer.h +1 -0
- data/ext/arraybuffer/dataview.c +110 -0
- data/ext/arraybuffer/extconf.rb +4 -0
- data/extconf.h +2 -0
- data/lib/arraybuffer_ext.bundle +0 -0
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 517c77a2de7cbcd60febb5217cd77f8b249848c7947519a50f9a63fb291713a4
|
4
|
+
data.tar.gz: 56cfdbea1a7222001ebd918d7e8e10674837b51621d490de97d104b059ee8301
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bae4c20202057631b3f554adecee91ade37f2d7f12de3cb88dc03405c321be5f79fac4931f6642af74d73e38dd2cab35857cc826eb2e45d6f9275ad3621c3213
|
7
|
+
data.tar.gz: a6955800866b293dfd7fbcd55b56b936876124081044e14024fe9f21b2ccbec0193a77c435f11ab0b5133fa2ba86de267f0f024a1cb00e22f93ad664c87cc746
|
@@ -1,6 +1,11 @@
|
|
1
1
|
#include "arraybuffer.h"
|
2
2
|
#include "extconf.h"
|
3
3
|
#include <string.h>
|
4
|
+
#include <ruby/version.h>
|
5
|
+
|
6
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
7
|
+
#include <ruby/memory_view.h>
|
8
|
+
#endif
|
4
9
|
|
5
10
|
extern VALUE cArrayBuffer;
|
6
11
|
|
@@ -12,15 +17,43 @@ extern VALUE cArrayBuffer;
|
|
12
17
|
rb_raise(rb_eArgError, "Index out of bounds: %d", (idx)); \
|
13
18
|
}
|
14
19
|
|
20
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
21
|
+
static bool
|
22
|
+
r_bb_mv_get(VALUE self, rb_memory_view_t *view, int flags) {
|
23
|
+
DECLAREBB(self);
|
24
|
+
if (!bb->size)
|
25
|
+
return 0;
|
26
|
+
rb_memory_view_init_as_byte_array(view, self, bb->ptr, (const ssize_t)bb->size, 0);
|
27
|
+
return 1;
|
28
|
+
}
|
29
|
+
|
30
|
+
// static bool
|
31
|
+
// r_bb_mv_release(VALUE self, rb_memory_view_t *view) {
|
32
|
+
// return 1;
|
33
|
+
// }
|
34
|
+
|
35
|
+
static bool
|
36
|
+
r_bb_mv_available_p(VALUE self) {
|
37
|
+
DECLAREBB(self);
|
38
|
+
return bb->size > 0 ? 1 : 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
static rb_memory_view_entry_t cArrayBufferMemoryView = {
|
42
|
+
r_bb_mv_get,
|
43
|
+
NULL, // r_bb_mv_release,
|
44
|
+
r_bb_mv_available_p
|
45
|
+
};
|
46
|
+
#endif
|
47
|
+
|
15
48
|
static void
|
16
49
|
t_bb_gc_mark(struct LLC_ArrayBuffer *bb) {
|
50
|
+
if (bb->backing_str) {
|
51
|
+
rb_gc_mark(bb->backing_str);
|
52
|
+
}
|
17
53
|
}
|
18
54
|
|
19
55
|
static void
|
20
56
|
t_bb_free(struct LLC_ArrayBuffer *bb) {
|
21
|
-
if (bb->ptr)
|
22
|
-
xfree(bb->ptr);
|
23
|
-
|
24
57
|
xfree(bb);
|
25
58
|
}
|
26
59
|
|
@@ -29,18 +62,46 @@ t_bb_allocator(VALUE klass) {
|
|
29
62
|
struct LLC_ArrayBuffer *bb = (struct LLC_ArrayBuffer*)xmalloc(sizeof(struct LLC_ArrayBuffer));
|
30
63
|
bb->ptr = NULL;
|
31
64
|
bb->size = 0;
|
65
|
+
bb->backing_str = NULL;
|
32
66
|
|
33
67
|
return Data_Wrap_Struct(klass, t_bb_gc_mark, t_bb_free, bb);
|
34
68
|
}
|
35
69
|
|
70
|
+
#if (RUBY_API_VERSION_CODE >= 30100)
|
71
|
+
// Ruby 3.1 and later
|
72
|
+
|
73
|
+
#define BB_BACKING_PTR(bb) \
|
74
|
+
(FL_TEST((bb)->backing_str, RSTRING_NOEMBED) ? RSTRING((bb)->backing_str)->as.heap.ptr : &RSTRING(bb->backing_str)->as.embed.ary)
|
75
|
+
#else
|
76
|
+
// Before ruby 3.1
|
77
|
+
|
78
|
+
#define BB_BACKING_PTR(bb) \
|
79
|
+
(FL_TEST((bb)->backing_str, RSTRING_NOEMBED) ? RSTRING((bb)->backing_str)->as.heap.ptr : &RSTRING(bb->backing_str)->as.ary)
|
80
|
+
#endif
|
81
|
+
|
82
|
+
static void
|
83
|
+
t_bb_reassign_ptr(struct LLC_ArrayBuffer *bb) {
|
84
|
+
if (!bb->backing_str) {
|
85
|
+
bb->ptr = NULL;
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
rb_str_set_len(bb->backing_str, bb->size);
|
90
|
+
bb->ptr = BB_BACKING_PTR(bb);
|
91
|
+
bb->ptr[bb->size] = 0;
|
92
|
+
}
|
93
|
+
|
36
94
|
static VALUE
|
37
95
|
t_bb_initialize(VALUE self, VALUE size) {
|
38
96
|
DECLAREBB(self);
|
39
97
|
unsigned int s = NUM2UINT(size);
|
40
98
|
bb->size = s;
|
41
|
-
if (bb->
|
42
|
-
|
43
|
-
|
99
|
+
if (bb->backing_str)
|
100
|
+
rb_gc_mark(bb->backing_str);
|
101
|
+
|
102
|
+
bb->backing_str = rb_str_buf_new(s);
|
103
|
+
|
104
|
+
t_bb_reassign_ptr(bb);
|
44
105
|
memset(bb->ptr, 0, (size_t)s);
|
45
106
|
return self;
|
46
107
|
}
|
@@ -96,31 +157,9 @@ t_bb_realloc(VALUE self, VALUE _new_size) {
|
|
96
157
|
if (new_size == bb->size)
|
97
158
|
return self;
|
98
159
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
if (old_ptr) {
|
103
|
-
if (new_size > bb->size) {
|
104
|
-
size_t diff = (size_t)(new_size - bb->size);
|
105
|
-
memcpy(new_ptr, old_ptr, (size_t)bb->size);
|
106
|
-
xfree(old_ptr);
|
107
|
-
old_ptr = NULL;
|
108
|
-
memset((char*)new_ptr + (size_t)bb->size, 0, diff);
|
109
|
-
} else {
|
110
|
-
memcpy(new_ptr, old_ptr, (size_t)new_size);
|
111
|
-
}
|
112
|
-
} else {
|
113
|
-
memset(new_ptr, 0, new_size);
|
114
|
-
}
|
115
|
-
bb->size = new_size;
|
116
|
-
bb->ptr = (unsigned char*)new_ptr;
|
117
|
-
} else {
|
118
|
-
bb->size = 0;
|
119
|
-
bb->ptr = NULL;
|
120
|
-
}
|
121
|
-
|
122
|
-
if (old_ptr)
|
123
|
-
xfree(old_ptr);
|
160
|
+
rb_str_resize(bb->backing_str, new_size);
|
161
|
+
bb->size = new_size;
|
162
|
+
t_bb_reassign_ptr(bb);
|
124
163
|
|
125
164
|
return self;
|
126
165
|
}
|
@@ -128,8 +167,8 @@ t_bb_realloc(VALUE self, VALUE _new_size) {
|
|
128
167
|
/*
|
129
168
|
* Returns a ASCII-8BIT string with the contents of the buffer
|
130
169
|
*
|
131
|
-
* The returned string is
|
132
|
-
* ASCII-8BIT.
|
170
|
+
* The returned string is the backing string of the buffer.
|
171
|
+
* It's encoding is always ASCII-8BIT.
|
133
172
|
* If the buffer has size zero, an empty string is returned.
|
134
173
|
*
|
135
174
|
* @return [String]
|
@@ -137,9 +176,7 @@ t_bb_realloc(VALUE self, VALUE _new_size) {
|
|
137
176
|
static VALUE
|
138
177
|
t_bb_bytes(VALUE self) {
|
139
178
|
DECLAREBB(self);
|
140
|
-
return
|
141
|
-
(const char*)bb->ptr,
|
142
|
-
bb->size);
|
179
|
+
return bb->backing_str;
|
143
180
|
}
|
144
181
|
|
145
182
|
void
|
@@ -156,4 +193,9 @@ Init_arraybuffer() {
|
|
156
193
|
rb_define_method(cArrayBuffer, "each", t_bb_each, 0);
|
157
194
|
rb_define_method(cArrayBuffer, "realloc", t_bb_realloc, 1);
|
158
195
|
rb_define_method(cArrayBuffer, "bytes", t_bb_bytes, 0);
|
196
|
+
rb_define_method(cArrayBuffer, "to_s", t_bb_bytes, 0);
|
197
|
+
|
198
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
199
|
+
rb_memory_view_register(cArrayBuffer, &cArrayBufferMemoryView);
|
200
|
+
#endif
|
159
201
|
}
|
data/ext/arraybuffer/dataview.c
CHANGED
@@ -6,6 +6,10 @@
|
|
6
6
|
#include <string.h>
|
7
7
|
#endif
|
8
8
|
|
9
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
10
|
+
#include <ruby/memory_view.h>
|
11
|
+
#endif
|
12
|
+
|
9
13
|
extern VALUE cArrayBuffer;
|
10
14
|
extern VALUE cDataView;
|
11
15
|
|
@@ -42,6 +46,39 @@ t_dv_allocator(VALUE klass) {
|
|
42
46
|
return Data_Wrap_Struct(klass, t_dv_gc_mark, t_dv_free, dv);
|
43
47
|
}
|
44
48
|
|
49
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
50
|
+
static bool
|
51
|
+
r_dv_mv_get(VALUE self, rb_memory_view_t *view, int flags) {
|
52
|
+
DECLAREDV(self);
|
53
|
+
if (!dv->size)
|
54
|
+
return 0;
|
55
|
+
|
56
|
+
DECLAREBB(dv->bb_obj);
|
57
|
+
|
58
|
+
char *ptr = (char*)bb->ptr + (size_t)dv->offset;
|
59
|
+
|
60
|
+
rb_memory_view_init_as_byte_array(view, self, ptr, (const ssize_t)dv->size, 0);
|
61
|
+
return 1;
|
62
|
+
}
|
63
|
+
|
64
|
+
// static bool
|
65
|
+
// r_dv_mv_release(VALUE self, rb_memory_view_t *view) {
|
66
|
+
// return 1;
|
67
|
+
// }
|
68
|
+
|
69
|
+
static bool
|
70
|
+
r_dv_mv_available_p(VALUE self) {
|
71
|
+
DECLAREDV(self);
|
72
|
+
return dv->size > 0 ? 1 : 0;
|
73
|
+
}
|
74
|
+
|
75
|
+
static rb_memory_view_entry_t cDataViewMemoryView = {
|
76
|
+
r_dv_mv_get,
|
77
|
+
NULL, // r_dv_mv_release,
|
78
|
+
r_dv_mv_available_p
|
79
|
+
};
|
80
|
+
#endif
|
81
|
+
|
45
82
|
/*
|
46
83
|
* call-seq:
|
47
84
|
* initialize(buffer, offset, size, endianess:)
|
@@ -434,6 +471,71 @@ t_dv_setu32(VALUE self, VALUE index, VALUE value) {
|
|
434
471
|
return self;
|
435
472
|
}
|
436
473
|
|
474
|
+
static VALUE
|
475
|
+
t_dv_setbytes(VALUE self, VALUE index, VALUE bytes) {
|
476
|
+
DECLAREDV(self); DECLARENCHECKIDX(index); DECLAREBB(dv->bb_obj);
|
477
|
+
unsigned int idx0 = dv->offset + (unsigned int)idx;
|
478
|
+
CHECKBOUNDSBB(idx0);
|
479
|
+
|
480
|
+
if (RB_TYPE_P(bytes, T_ARRAY)) {
|
481
|
+
const unsigned int length = (unsigned int)rb_array_len(bytes);
|
482
|
+
const VALUE* items = rb_array_const_ptr(bytes);
|
483
|
+
CHECKBOUNDSBB(idx0 + length);
|
484
|
+
|
485
|
+
for (unsigned int i = 0; i < length; i++) {
|
486
|
+
if (!RB_FIXNUM_P(items[i]))
|
487
|
+
rb_raise(rb_eRuntimeError, "array contains non fixnum value at index %d", i);
|
488
|
+
int num = NUM2INT(items[i]);
|
489
|
+
ADJUSTBOUNDS(num, 0xFF);
|
490
|
+
bb->ptr[idx0 + i] = (unsigned char)num;
|
491
|
+
}
|
492
|
+
} else if (RB_TYPE_P(bytes, T_STRING)) {
|
493
|
+
const char *str_ptr = RSTRING_PTR(bytes);
|
494
|
+
const unsigned int length = (unsigned int)RSTRING_LEN(bytes);
|
495
|
+
CHECKBOUNDSBB(idx0 + length);
|
496
|
+
|
497
|
+
for (unsigned int i = 0; i < length; i++) {
|
498
|
+
bb->ptr[idx0 + i] = (unsigned char)str_ptr[i];
|
499
|
+
}
|
500
|
+
} else if (RB_TYPE_P(bytes, T_DATA) &&
|
501
|
+
(CLASS_OF(bytes) == cArrayBuffer || CLASS_OF(bytes) == cDataView)) {
|
502
|
+
unsigned int length;
|
503
|
+
const char *src_bytes;
|
504
|
+
if (CLASS_OF(bytes) == cArrayBuffer) {
|
505
|
+
struct LLC_ArrayBuffer *src_bb = (struct LLC_ArrayBuffer*)rb_data_object_get(bytes);
|
506
|
+
length = src_bb->size;
|
507
|
+
src_bytes = (const char*)src_bb->ptr;
|
508
|
+
} else {
|
509
|
+
struct LLC_DataView *src_dv = (struct LLC_DataView*)rb_data_object_get(bytes);
|
510
|
+
struct LLC_ArrayBuffer *src_bb = (struct LLC_ArrayBuffer*)rb_data_object_get(src_dv->bb_obj);
|
511
|
+
length = src_dv->size;
|
512
|
+
src_bytes = (const char*)(src_bb->ptr + (size_t)src_dv->offset);
|
513
|
+
if (src_dv->offset >= src_bb->size)
|
514
|
+
rb_raise(rb_eRuntimeError, "offset exceeds the underlying source buffer size");
|
515
|
+
if (src_dv->offset + length >= src_bb->size)
|
516
|
+
rb_raise(rb_eRuntimeError, "offset + size exceeds the underlying source buffer size");
|
517
|
+
}
|
518
|
+
|
519
|
+
CHECKBOUNDSBB(idx0 + length);
|
520
|
+
memcpy((void*)(bb->ptr + (size_t)idx0), src_bytes, (size_t)length);
|
521
|
+
} else {
|
522
|
+
rb_raise(rb_eArgError, "Invalid type: %+"PRIsVALUE, CLASS_OF(bytes));
|
523
|
+
}
|
524
|
+
|
525
|
+
return self;
|
526
|
+
}
|
527
|
+
|
528
|
+
VALUE
|
529
|
+
t_dv_to_s(VALUE self) {
|
530
|
+
DECLAREDV(self);
|
531
|
+
DECLAREBB(dv->bb_obj);
|
532
|
+
|
533
|
+
const char *ptr = (const char*)bb->ptr + (size_t)dv->offset;
|
534
|
+
size_t len = (size_t)dv->size;
|
535
|
+
|
536
|
+
return rb_str_new(ptr, len);
|
537
|
+
}
|
538
|
+
|
437
539
|
void
|
438
540
|
Init_dataview() {
|
439
541
|
idEndianess = rb_intern("endianess");
|
@@ -456,6 +558,8 @@ Init_dataview() {
|
|
456
558
|
rb_define_method(cDataView, "setU24", t_dv_setu24, 2);
|
457
559
|
rb_define_method(cDataView, "setU32", t_dv_setu32, 2);
|
458
560
|
|
561
|
+
rb_define_method(cDataView, "setBytes", t_dv_setbytes, 2);
|
562
|
+
|
459
563
|
rb_define_method(cDataView, "endianess", t_dv_endianess, 0);
|
460
564
|
rb_define_method(cDataView, "offset=", t_dv_setoffset, 1);
|
461
565
|
rb_define_method(cDataView, "offset", t_dv_offset, 0);
|
@@ -464,4 +568,10 @@ Init_dataview() {
|
|
464
568
|
rb_define_method(cDataView, "size", t_dv_size, 0);
|
465
569
|
rb_define_alias(cDataView, "length", "size");
|
466
570
|
rb_define_method(cDataView, "each", t_dv_each, 0);
|
571
|
+
|
572
|
+
rb_define_method(cDataView, "to_s", t_dv_to_s, 0);
|
573
|
+
|
574
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
575
|
+
rb_memory_view_register(cDataView, &cDataViewMemoryView);
|
576
|
+
#endif
|
467
577
|
}
|
data/ext/arraybuffer/extconf.rb
CHANGED
data/extconf.h
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arraybuffer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- André Diego Piske
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -24,7 +24,21 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.9'
|
27
|
-
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.2'
|
41
|
+
description:
|
28
42
|
email:
|
29
43
|
- andrepiske@gmail.com
|
30
44
|
executables: []
|
@@ -40,12 +54,13 @@ files:
|
|
40
54
|
- ext/arraybuffer/extconf.rb
|
41
55
|
- extconf.h
|
42
56
|
- lib/arraybuffer.rb
|
57
|
+
- lib/arraybuffer_ext.bundle
|
43
58
|
homepage: https://github.com/andrepiske/rb-arraybuffer
|
44
59
|
licenses:
|
45
60
|
- MIT
|
46
61
|
metadata:
|
47
62
|
source_code_uri: https://github.com/andrepiske/rb-arraybuffer
|
48
|
-
post_install_message:
|
63
|
+
post_install_message:
|
49
64
|
rdoc_options: []
|
50
65
|
require_paths:
|
51
66
|
- lib
|
@@ -60,8 +75,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
75
|
- !ruby/object:Gem::Version
|
61
76
|
version: '0'
|
62
77
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
64
|
-
signing_key:
|
78
|
+
rubygems_version: 3.3.11
|
79
|
+
signing_key:
|
65
80
|
specification_version: 4
|
66
|
-
summary:
|
81
|
+
summary: An array buffer (a.k.a. byte array) implementation forRuby, implemented natively.
|
67
82
|
test_files: []
|