carray 3.0.5 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +233 -0
- data/README.md +1 -1
- data/carray.gemspec +3 -2
- data/ext/ca_axis_dispatch.c +6 -0
- data/ext/ca_axis_group.c +1 -1
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.c +116 -231
- data/ext/ca_kernel_iterator.h +410 -254
- data/ext/ca_obj_bincmp.c +9 -1
- data/ext/ca_obj_binop.c +10 -1
- data/ext/ca_obj_bitfield.c +2 -0
- data/ext/ca_obj_byte_swap.c +2 -0
- data/ext/ca_obj_face.c +2 -0
- data/ext/ca_obj_fake.c +3 -1
- data/ext/ca_obj_grid.c +167 -12
- data/ext/ca_obj_meld.c +69 -113
- data/ext/ca_obj_moncmp.c +9 -1
- data/ext/ca_obj_monop.c +40 -2
- data/ext/ca_obj_object.c +54 -20
- data/ext/ca_obj_reduce.c +15 -1
- data/ext/ca_obj_refer.c +65 -20
- data/ext/ca_obj_remap.c +69 -10
- data/ext/ca_obj_roll.c +1 -0
- data/ext/ca_obj_select.c +4 -1
- data/ext/ca_obj_select_axis.c +1 -0
- data/ext/ca_obj_shift.c +1 -0
- data/ext/ca_obj_stack.c +310 -111
- data/ext/ca_obj_stride.c +131 -45
- data/ext/ca_obj_string.c +18 -2
- data/ext/ca_obj_tile.c +1 -0
- data/ext/ca_obj_triop.c +9 -1
- data/ext/ca_obj_window.c +1 -0
- data/ext/ca_op_ipower.c +8 -8
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +2 -1
- data/ext/carray_access.c +27 -64
- data/ext/carray_address_basis.c +134 -0
- data/ext/carray_attribute.c +8 -0
- data/ext/carray_broadcast.c +3 -4
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_cast.c +8 -11
- data/ext/carray_conversion.c +9 -5
- data/ext/carray_core.c +811 -72
- data/ext/carray_element.c +13 -9
- data/ext/carray_histogram.c +25 -3
- data/ext/carray_internal.h +147 -12
- data/ext/carray_kernels_bincmp.c +2007 -3
- data/ext/carray_kernels_binop.c +25365 -5199
- data/ext/carray_kernels_init.c +8 -8
- data/ext/carray_kernels_monop.c +10696 -3678
- data/ext/carray_kernels_reduce_aggregate.c +4429 -702
- data/ext/carray_kernels_reduce_boolean.c +1533 -15
- data/ext/carray_kernels_reduce_cumulative.c +1808 -248
- data/ext/carray_kernels_reduce_extreme.c +4508 -511
- data/ext/carray_kernels_reduce_variance.c +2284 -152
- data/ext/carray_kernels_scan.c +240 -240
- data/ext/carray_kernels_search.c +4211 -264
- data/ext/carray_kernels_sort.c +367 -450
- data/ext/carray_lazy.c +47 -0
- data/ext/carray_loop.c +1 -1
- data/ext/carray_mask.c +130 -139
- data/ext/carray_median_percentile.c +4 -4
- data/ext/carray_memory_view.c +13 -7
- data/ext/carray_operator.c +147 -44
- data/ext/carray_order.c +3 -2
- data/ext/carray_random.c +4 -1
- data/ext/carray_slab.c +97 -21
- data/ext/carray_sort.c +1 -1
- data/ext/carray_test.c +74 -19
- data/ext/carray_time_text.c +2 -2
- data/ext/extconf.rb +11 -0
- data/ext/mkkernel.rb +346 -94
- data/ext/ruby_carray.c +4 -1
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +25 -1
- data/lib/carray/autoload_carray.rb +3 -3
- data/lib/carray/autoload_method_extension.rb +5 -3
- data/lib/carray/axis_group.rb +13 -7
- data/lib/carray/basics.rb +1 -1
- data/lib/carray/block_iterator.rb +17 -3
- data/lib/carray/categorical.rb +6 -8
- data/lib/carray/categorical_iterator.rb +2 -2
- data/lib/carray/complex.rb +2 -2
- data/lib/carray/conditional.rb +3 -2
- data/lib/carray/frame/column_verbs.rb +45 -14
- data/lib/carray/frame/convert.rb +19 -0
- data/lib/carray/frame/csv_parser.rb +32 -32
- data/lib/carray/frame/describe.rb +4 -2
- data/lib/carray/frame/frame.rb +399 -78
- data/lib/carray/frame/group.rb +679 -53
- data/lib/carray/frame/io.rb +209 -71
- data/lib/carray/frame/join.rb +146 -37
- data/lib/carray/frame/records.rb +3 -3
- data/lib/carray/frame/reshape.rb +89 -11
- data/lib/carray/frame/sort.rb +57 -9
- data/lib/carray/frame/verbs.rb +384 -49
- data/lib/carray/frame/windows.rb +44 -6
- data/lib/carray/inspect.rb +7 -2
- data/lib/carray/iterator.rb +32 -0
- data/lib/carray/lazy.rb +17 -8
- data/lib/carray/mask_gap_fill.rb +37 -17
- data/lib/carray/meld_reduce.rb +1 -1
- data/lib/carray/methods/choose.rb +3 -2
- data/lib/carray/methods/meshgrid.rb +3 -1
- data/lib/carray/runtime.rb +47 -8
- data/lib/carray/segment_iterator.rb +23 -8
- data/lib/carray/serialize.rb +34 -17
- data/lib/carray/stack.rb +18 -6
- data/lib/carray/time.rb +5 -0
- data/lib/carray/window_iterator.rb +16 -4
- data/yard-stubs/ca_obj_array.rb +26 -1
- data/yard-stubs/carray_cast.rb +8 -5
- data/yard-stubs/carray_conversion.rb +8 -2
- data/yard-stubs/carray_mask.rb +20 -1
- data/yard-stubs/carray_math.rb +31 -16
- data/yard-stubs/carray_memory_view.rb +7 -0
- data/yard-stubs/carray_test.rb +7 -4
- metadata +18 -4
data/ext/carray_address_basis.c
CHANGED
|
@@ -965,6 +965,139 @@ address_basis_tier (VALUE module, VALUE object)
|
|
|
965
965
|
return INT2NUM(tier_for(ca));
|
|
966
966
|
}
|
|
967
967
|
|
|
968
|
+
/* ------------------------------------------------------------------- */
|
|
969
|
+
|
|
970
|
+
/*
|
|
971
|
+
* call-seq:
|
|
972
|
+
* CArray::AddressBasis.sweep(function, fsync, arrays, *parts) -> nil
|
|
973
|
+
*
|
|
974
|
+
* Runs ca_call_cslab_N_r over `arrays` with the slab function at the address
|
|
975
|
+
* `function`, and hands it as `userdata` a table of pointers to the bytes of
|
|
976
|
+
* each of `parts`, in order.
|
|
977
|
+
*
|
|
978
|
+
* This is what a consumer did through Fiddle: copy the parts into memory
|
|
979
|
+
* from malloc, write the table in front of them, and call the family member
|
|
980
|
+
* for the arity. The copy was there because a String's bytes may be moved
|
|
981
|
+
* by GC compaction, and the sweep allocates -- so a collection can run
|
|
982
|
+
* between taking an address and the slab reading it. It is not needed
|
|
983
|
+
* here: every part is also held in an array on the machine stack for the
|
|
984
|
+
* length of this call, and an object referenced from there is pinned. The
|
|
985
|
+
* VM stack is not enough by itself -- a splat of 128 or more arguments
|
|
986
|
+
* reaches a C method as a heap array, whose elements compaction moves.
|
|
987
|
+
* The machine stack is why the parts are limited to 1024.
|
|
988
|
+
*
|
|
989
|
+
* A part that is not frozen is the slab's to write (an error slot), and is
|
|
990
|
+
* made unshared first so the write lands in that String alone. A frozen
|
|
991
|
+
* part is read only. Each part has to start on an 8-byte boundary, since a
|
|
992
|
+
* slab reads doubles and int64s out of them.
|
|
993
|
+
*/
|
|
994
|
+
static VALUE
|
|
995
|
+
address_basis_sweep (int argc, VALUE *argv, VALUE module)
|
|
996
|
+
{
|
|
997
|
+
volatile VALUE rfunction, rfsync, rarrays;
|
|
998
|
+
ca_cslab_r_t function;
|
|
999
|
+
const char *fsync;
|
|
1000
|
+
VALUE vholder = 0;
|
|
1001
|
+
void **table;
|
|
1002
|
+
VALUE *arrays;
|
|
1003
|
+
volatile VALUE *parts;
|
|
1004
|
+
int i, n, nparts;
|
|
1005
|
+
|
|
1006
|
+
rb_check_arity(argc, 3, UNLIMITED_ARGUMENTS);
|
|
1007
|
+
rfunction = argv[0];
|
|
1008
|
+
rfsync = argv[1];
|
|
1009
|
+
rarrays = argv[2];
|
|
1010
|
+
nparts = argc - 3;
|
|
1011
|
+
|
|
1012
|
+
if ( nparts > 1024 ) {
|
|
1013
|
+
rb_raise(rb_eArgError, "%s: a sweep takes at most 1024 parts, got %d",
|
|
1014
|
+
ca_calling_method_name(), nparts);
|
|
1015
|
+
}
|
|
1016
|
+
/* Held on the machine stack, which the GC scans conservatively and so
|
|
1017
|
+
pins. argv is not written: it may be the storage of a heap array. */
|
|
1018
|
+
parts = ALLOCA_N(VALUE, nparts > 0 ? nparts : 1);
|
|
1019
|
+
for ( i = 0; i < nparts; i++ ) {
|
|
1020
|
+
parts[i] = argv[3 + i];
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
Check_Type(rarrays, T_ARRAY);
|
|
1024
|
+
n = (int) RARRAY_LEN(rarrays);
|
|
1025
|
+
if ( n < 1 || n > 7 ) {
|
|
1026
|
+
rb_raise(rb_eArgError, "%s: a sweep takes 1 to 7 arrays, got %d",
|
|
1027
|
+
ca_calling_method_name(), n);
|
|
1028
|
+
}
|
|
1029
|
+
fsync = StringValueCStr(rfsync);
|
|
1030
|
+
if ( (int) strlen(fsync) != n ) {
|
|
1031
|
+
rb_raise(rb_eArgError, "%s: fsync has %d characters for %d arrays",
|
|
1032
|
+
ca_calling_method_name(), (int) strlen(fsync), n);
|
|
1033
|
+
}
|
|
1034
|
+
for ( i = 0; i < n; i++ ) {
|
|
1035
|
+
if ( fsync[i] != '0' && fsync[i] != '1' ) {
|
|
1036
|
+
rb_raise(rb_eArgError,
|
|
1037
|
+
"%s: fsync character %d is '%c', not '0' (read) or '1' (written)",
|
|
1038
|
+
ca_calling_method_name(), i, fsync[i]);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function = (ca_cslab_r_t) (uintptr_t) NUM2ULL(rfunction);
|
|
1042
|
+
if ( ! function ) {
|
|
1043
|
+
rb_raise(rb_eArgError, "%s: the slab function's address is zero",
|
|
1044
|
+
ca_calling_method_name());
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
arrays = RARRAY_PTR(rarrays);
|
|
1048
|
+
for ( i = 0; i < n; i++ ) {
|
|
1049
|
+
if ( ! rb_obj_is_kind_of(arrays[i], rb_cCArray) ) {
|
|
1050
|
+
rb_raise(rb_eTypeError, "%s: array %d is not a CArray",
|
|
1051
|
+
ca_calling_method_name(), i);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
for ( i = 0; i < nparts; i++ ) {
|
|
1056
|
+
VALUE part = parts[i];
|
|
1057
|
+
StringValue(part);
|
|
1058
|
+
parts[i] = part;
|
|
1059
|
+
if ( ! OBJ_FROZEN(part) ) {
|
|
1060
|
+
rb_str_modify(part);
|
|
1061
|
+
}
|
|
1062
|
+
if ( (uintptr_t) RSTRING_PTR(part) & 7 ) {
|
|
1063
|
+
rb_raise(rb_eArgError, "%s: part %d does not start on an 8-byte boundary",
|
|
1064
|
+
ca_calling_method_name(), i);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/* Taken after every check, so a refusal has nothing to free. The sweep
|
|
1069
|
+
itself can raise (a shape that will not broadcast); then the table is
|
|
1070
|
+
left to ALLOCV's own holder, which the GC reclaims. */
|
|
1071
|
+
table = ALLOCV_N(void *, vholder, nparts > 0 ? nparts : 1);
|
|
1072
|
+
for ( i = 0; i < nparts; i++ ) {
|
|
1073
|
+
table[i] = RSTRING_PTR(parts[i]);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
switch ( n ) {
|
|
1077
|
+
case 1: ca_call_cslab_1_r(function, fsync, arrays[0], table); break;
|
|
1078
|
+
case 2: ca_call_cslab_2_r(function, fsync, arrays[0], arrays[1], table); break;
|
|
1079
|
+
case 3: ca_call_cslab_3_r(function, fsync, arrays[0], arrays[1], arrays[2],
|
|
1080
|
+
table); break;
|
|
1081
|
+
case 4: ca_call_cslab_4_r(function, fsync, arrays[0], arrays[1], arrays[2],
|
|
1082
|
+
arrays[3], table); break;
|
|
1083
|
+
case 5: ca_call_cslab_5_r(function, fsync, arrays[0], arrays[1], arrays[2],
|
|
1084
|
+
arrays[3], arrays[4], table); break;
|
|
1085
|
+
case 6: ca_call_cslab_6_r(function, fsync, arrays[0], arrays[1], arrays[2],
|
|
1086
|
+
arrays[3], arrays[4], arrays[5], table); break;
|
|
1087
|
+
case 7: ca_call_cslab_7_r(function, fsync, arrays[0], arrays[1], arrays[2],
|
|
1088
|
+
arrays[3], arrays[4], arrays[5], arrays[6],
|
|
1089
|
+
table); break;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
ALLOCV_END(vholder);
|
|
1093
|
+
for ( i = 0; i < nparts; i++ ) {
|
|
1094
|
+
RB_GC_GUARD(parts[i]);
|
|
1095
|
+
}
|
|
1096
|
+
RB_GC_GUARD(rarrays);
|
|
1097
|
+
RB_GC_GUARD(rfsync);
|
|
1098
|
+
return Qnil;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
968
1101
|
/* ------------------------------------------------------------------- */
|
|
969
1102
|
/* Init_carray_address_basis */
|
|
970
1103
|
/* ------------------------------------------------------------------- */
|
|
@@ -978,6 +1111,7 @@ Init_carray_address_basis (void)
|
|
|
978
1111
|
rb_define_singleton_method(mAddressBasis, "classify",
|
|
979
1112
|
address_basis_classify, 1);
|
|
980
1113
|
rb_define_singleton_method(mAddressBasis, "tier", address_basis_tier, 1);
|
|
1114
|
+
rb_define_singleton_method(mAddressBasis, "sweep", address_basis_sweep, -1);
|
|
981
1115
|
|
|
982
1116
|
rb_define_const(mAddressBasis, "TIER_ENTITY", INT2NUM(TIER_ENTITY));
|
|
983
1117
|
rb_define_const(mAddressBasis, "TIER_STRIDE", INT2NUM(TIER_STRIDE));
|
data/ext/carray_attribute.c
CHANGED
|
@@ -223,6 +223,14 @@ ca_is_readonly (void *ap)
|
|
|
223
223
|
return 1;
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
+
if ( ca_test_flag(ca, CA_FLAG_FOLDED) ) {
|
|
227
|
+
/* a folded reshape: its source is not on the parent chain */
|
|
228
|
+
CArray *src = ca_fold_source(ca);
|
|
229
|
+
if ( src && ca_is_readonly(src) ) {
|
|
230
|
+
ca_set_flag(ca, CA_FLAG_READ_ONLY);
|
|
231
|
+
return 1;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
226
234
|
return 0; /* all test -> false */
|
|
227
235
|
}
|
|
228
236
|
}
|
data/ext/carray_broadcast.c
CHANGED
|
@@ -85,13 +85,12 @@ ca_broadcast_to_destination (VALUE dst, volatile VALUE *src)
|
|
|
85
85
|
for ( i = 0; agree && i < dst_ndim; i++ ) {
|
|
86
86
|
if ( dst_dim[i] != src_dim[i] ) agree = 0;
|
|
87
87
|
}
|
|
88
|
-
if (
|
|
89
|
-
return;
|
|
88
|
+
if ( agree ) return;
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
/* A size-1 axis repeated onto an axis of length 0 leaves the source
|
|
93
|
-
larger than an empty destination
|
|
94
|
-
the same. */
|
|
92
|
+
larger than an empty destination, or as large when it is empty too
|
|
93
|
+
((1,0) onto (2,0)); the axes say it is a repeat all the same. */
|
|
95
94
|
if ( ( cs->elements < cd->elements || cd->elements == 0 )
|
|
96
95
|
&& cs->ndim == cd->ndim ) {
|
|
97
96
|
int i;
|
data/ext/carray_build_flags.h
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* GENERATED by extconf.rb: the flags this build's arithmetic
|
|
2
2
|
was compiled with. See CArray::BUILD_FLAGS. */
|
|
3
|
-
#define CA_BUILD_FLAGS "-O3 -fno-fast-math -fwrapv -fopenmp-simd -march=native"
|
|
3
|
+
#define CA_BUILD_FLAGS "-O3 -fno-fast-math -fwrapv -fno-math-errno -fopenmp-simd -march=native"
|
data/ext/carray_cast.c
CHANGED
|
@@ -1609,7 +1609,6 @@ static VALUE
|
|
|
1609
1609
|
rb_ca_as_type_internal (int argc, VALUE *argv, VALUE self)
|
|
1610
1610
|
{
|
|
1611
1611
|
volatile VALUE obj, rtype = Qnil, ropt, rbytes = Qnil;
|
|
1612
|
-
CArray *ca;
|
|
1613
1612
|
int8_t data_type;
|
|
1614
1613
|
ca_size_t bytes;
|
|
1615
1614
|
|
|
@@ -1618,14 +1617,12 @@ rb_ca_as_type_internal (int argc, VALUE *argv, VALUE self)
|
|
|
1618
1617
|
|
|
1619
1618
|
rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
|
|
1620
1619
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1620
|
+
rb_check_carray_object(self);
|
|
1621
|
+
|
|
1622
|
+
/* A view also when the data_type is the receiver's own: what is done to
|
|
1623
|
+
it (an attribute, a freeze) stays with it.
|
|
1627
1624
|
|
|
1628
|
-
|
|
1625
|
+
Natural-width cast: dispatch via helper (CAMonOp for numeric,
|
|
1629
1626
|
CAFake for CA_FIXLEN sizing / CA_OBJECT / class-rtype). */
|
|
1630
1627
|
if ( bytes == (ca_size_t) ca_sizeof[data_type] ) {
|
|
1631
1628
|
obj = ca_type_adapt_view(self, rtype, data_type, CA_ADAPT_VIEW);
|
|
@@ -3434,7 +3431,7 @@ rb_ca_read_text_as_number (int argc, VALUE *argv, VALUE self)
|
|
|
3434
3431
|
if ( ca->data_type != CA_OBJECT ) {
|
|
3435
3432
|
rb_raise(rb_eArgError, "decimal reading needs an object array");
|
|
3436
3433
|
}
|
|
3437
|
-
if ( ! ca_is_entity(ca) ) {
|
|
3434
|
+
if ( ! ca_is_entity(ca) || ! ca->ptr ) {
|
|
3438
3435
|
src = rb_ca_copy(src);
|
|
3439
3436
|
TypedData_Get_Struct(src, CArray, &carray_data_type, ca);
|
|
3440
3437
|
}
|
|
@@ -3571,7 +3568,7 @@ rb_ca_infer_number_type_of_text (VALUE self)
|
|
|
3571
3568
|
if ( ca->data_type != CA_OBJECT ) {
|
|
3572
3569
|
rb_raise(rb_eArgError, "type inference needs an object array");
|
|
3573
3570
|
}
|
|
3574
|
-
if ( ! ca_is_entity(ca) ) {
|
|
3571
|
+
if ( ! ca_is_entity(ca) || ! ca->ptr ) {
|
|
3575
3572
|
src = rb_ca_copy(src);
|
|
3576
3573
|
TypedData_Get_Struct(src, CArray, &carray_data_type, ca);
|
|
3577
3574
|
}
|
|
@@ -3634,7 +3631,7 @@ ca_const_string_buffer_and_ranges (VALUE cs, VALUE *buffer, CArray **ranges)
|
|
|
3634
3631
|
*buffer = rb_funcall(cs, rb_intern("buffer"), 0);
|
|
3635
3632
|
vranges = rb_ca_parent(cs);
|
|
3636
3633
|
TypedData_Get_Struct(vranges, CArray, &carray_data_type, *ranges);
|
|
3637
|
-
if ( ! ca_is_entity(*ranges) ) {
|
|
3634
|
+
if ( ! ca_is_entity(*ranges) || ! (*ranges)->ptr ) {
|
|
3638
3635
|
vranges = rb_ca_copy(vranges);
|
|
3639
3636
|
TypedData_Get_Struct(vranges, CArray, &carray_data_type, *ranges);
|
|
3640
3637
|
}
|
data/ext/carray_conversion.c
CHANGED
|
@@ -369,7 +369,8 @@ rb_ca_convert (int argc, VALUE *argv, VALUE self)
|
|
|
369
369
|
|
|
370
370
|
list[0] = c.ca;
|
|
371
371
|
list[1] = c.co;
|
|
372
|
-
|
|
372
|
+
ca_attach_window_yielding(rb_assoc_new(self, obj), 2, list, "rw",
|
|
373
|
+
ca_convert_body, (VALUE) &c);
|
|
373
374
|
|
|
374
375
|
return obj;
|
|
375
376
|
}
|
|
@@ -417,9 +418,11 @@ rb_ca_dump_binary (int argc, VALUE *argv, VALUE self)
|
|
|
417
418
|
ca_size_t total = ca_length(ca);
|
|
418
419
|
GetOpenFile(io, iop);
|
|
419
420
|
rb_io_check_writable(iop);
|
|
420
|
-
if ( ca_is_entity(ca) ) {
|
|
421
|
+
if ( ca_is_entity(ca) && ca->ptr ) {
|
|
421
422
|
/* Owned ca->ptr: write through the IO buffer machinery so peak
|
|
422
|
-
stays at ca_length instead of doubling via a Ruby String.
|
|
423
|
+
stays at ca_length instead of doubling via a Ruby String. An
|
|
424
|
+
entity that leaves ptr NULL at rest (a CASource) takes the
|
|
425
|
+
gather below. */
|
|
423
426
|
ssize_t n = rb_io_bufwrite(io, ca->ptr, (size_t) total);
|
|
424
427
|
if ( n < 0 || (ca_size_t) n != total ) {
|
|
425
428
|
rb_raise(rb_eRuntimeError,
|
|
@@ -428,7 +431,8 @@ rb_ca_dump_binary (int argc, VALUE *argv, VALUE self)
|
|
|
428
431
|
}
|
|
429
432
|
}
|
|
430
433
|
else {
|
|
431
|
-
/* View: no chunked gather API, so
|
|
434
|
+
/* View, or entity without a ptr: no chunked gather API, so
|
|
435
|
+
materialise into one buffer. */
|
|
432
436
|
volatile VALUE buf = rb_str_new(NULL, total);
|
|
433
437
|
ca_copy_data(ca, RSTRING_PTR(buf));
|
|
434
438
|
rb_io_write(io, buf);
|
|
@@ -545,7 +549,7 @@ rb_ca_load_binary (VALUE self, VALUE io)
|
|
|
545
549
|
}
|
|
546
550
|
|
|
547
551
|
/* The double nearest to the shortest decimal that reads back as x, the
|
|
548
|
-
float32 value, as
|
|
552
|
+
float32 value, as read_csv reads text into float32: strtod, then the cast
|
|
549
553
|
to float. Its digits are those of the decimal (at most 9, which a double
|
|
550
554
|
holds), so Float#to_s writes them. */
|
|
551
555
|
static double
|