carray 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +56 -0
  3. data/GPL +340 -0
  4. data/Gemfile +9 -0
  5. data/Gemfile.lock +33 -0
  6. data/LEGAL +50 -0
  7. data/NOTE +73 -0
  8. data/Rakefile +20 -0
  9. data/TODO +5 -0
  10. data/ca_iter_block.c +242 -0
  11. data/ca_iter_dimension.c +287 -0
  12. data/ca_iter_window.c +202 -0
  13. data/ca_obj_array.c +1189 -0
  14. data/ca_obj_bitarray.c +523 -0
  15. data/ca_obj_bitfield.c +636 -0
  16. data/ca_obj_block.c +885 -0
  17. data/ca_obj_fake.c +405 -0
  18. data/ca_obj_farray.c +482 -0
  19. data/ca_obj_field.c +625 -0
  20. data/ca_obj_grid.c +738 -0
  21. data/ca_obj_mapping.c +614 -0
  22. data/ca_obj_object.c +777 -0
  23. data/ca_obj_reduce.c +299 -0
  24. data/ca_obj_refer.c +627 -0
  25. data/ca_obj_repeat.c +640 -0
  26. data/ca_obj_select.c +558 -0
  27. data/ca_obj_shift.c +952 -0
  28. data/ca_obj_transpose.c +582 -0
  29. data/ca_obj_unbound_repeat.c +557 -0
  30. data/ca_obj_window.c +1023 -0
  31. data/carray.h +1381 -0
  32. data/carray_access.c +1798 -0
  33. data/carray_attribute.c +903 -0
  34. data/carray_call_cfunc.c +1107 -0
  35. data/carray_cast.c +1155 -0
  36. data/carray_cast_func.rb +498 -0
  37. data/carray_class.c +132 -0
  38. data/carray_conversion.c +518 -0
  39. data/carray_copy.c +453 -0
  40. data/carray_core.c +1307 -0
  41. data/carray_element.c +572 -0
  42. data/carray_generate.c +681 -0
  43. data/carray_iterator.c +630 -0
  44. data/carray_loop.c +462 -0
  45. data/carray_mask.c +1174 -0
  46. data/carray_math.rb +834 -0
  47. data/carray_numeric.c +257 -0
  48. data/carray_operator.c +582 -0
  49. data/carray_order.c +1040 -0
  50. data/carray_random.c +529 -0
  51. data/carray_sort_addr.c +261 -0
  52. data/carray_stat.c +2102 -0
  53. data/carray_stat_proc.rb +1990 -0
  54. data/carray_test.c +602 -0
  55. data/carray_undef.c +69 -0
  56. data/carray_utils.c +740 -0
  57. data/ext/calculus/carray_calculus.c +792 -0
  58. data/ext/calculus/carray_interp.c +355 -0
  59. data/ext/calculus/extconf.rb +12 -0
  60. data/ext/calculus/lib/autoload/autoload_math_calculus.rb +2 -0
  61. data/ext/calculus/lib/math/calculus.rb +119 -0
  62. data/ext/calculus/lib/math/interp/adapter_interp1d.rb +31 -0
  63. data/ext/dataframe/API.txt +11 -0
  64. data/ext/dataframe/extconf.rb +3 -0
  65. data/ext/dataframe/lib/carray/autoload/autoload_dataframe_dataframe.rb +14 -0
  66. data/ext/dataframe/lib/carray/dataframe/dataframe.rb +1104 -0
  67. data/ext/dataframe/sample/test_uniq_sort.rb +5 -0
  68. data/ext/fortio/extconf.rb +3 -0
  69. data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +5 -0
  70. data/ext/fortio/lib/carray/io/fortran_format.rb +43 -0
  71. data/ext/fortio/lib/fortio.rb +3 -0
  72. data/ext/fortio/lib/fortio/fortran_format.rb +603 -0
  73. data/ext/fortio/lib/fortio/fortran_format.tab.rb +536 -0
  74. data/ext/fortio/lib/fortio/fortran_format.y +215 -0
  75. data/ext/fortio/lib/fortio/fortran_namelist.rb +151 -0
  76. data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +470 -0
  77. data/ext/fortio/lib/fortio/fortran_namelist.y +213 -0
  78. data/ext/fortio/lib/fortio/fortran_sequential.rb +345 -0
  79. data/ext/fortio/ruby_fortio.c +182 -0
  80. data/ext/fortio/test/test_H.rb +5 -0
  81. data/ext/fortio/test/test_T.rb +7 -0
  82. data/ext/fortio/test/test_fortran_format.rb +86 -0
  83. data/ext/fortio/test/test_namelist.rb +25 -0
  84. data/ext/fortio/test/test_sequential.rb +13 -0
  85. data/ext/fortio/test/test_sequential2.rb +13 -0
  86. data/ext/fortio/work/test.rb +10 -0
  87. data/ext/fortio/work/test_e.rb +19 -0
  88. data/ext/fortio/work/test_ep.rb +10 -0
  89. data/ext/fortio/work/test_parse.rb +12 -0
  90. data/ext/imagemap/carray_imagemap.c +495 -0
  91. data/ext/imagemap/doc/call_graph.dot +28 -0
  92. data/ext/imagemap/draw.c +567 -0
  93. data/ext/imagemap/extconf.rb +13 -0
  94. data/ext/imagemap/lib/autoload/autoload_graphics_imagemap.rb +1 -0
  95. data/ext/imagemap/lib/graphics/imagemap.rb +273 -0
  96. data/ext/imagemap/lib/image_map.rb +4 -0
  97. data/ext/imagemap/test/swath_index.rb +83 -0
  98. data/ext/imagemap/test/swath_warp.rb +99 -0
  99. data/ext/imagemap/test/test.rb +23 -0
  100. data/ext/imagemap/test/test_image.rb +42 -0
  101. data/ext/imagemap/test/test_line.rb +14 -0
  102. data/ext/imagemap/test/test_rotate.rb +17 -0
  103. data/ext/imagemap/test/test_triangle.rb +20 -0
  104. data/ext/imagemap/test/test_warp.rb +26 -0
  105. data/ext/mathfunc/carray_mathfunc.c +321 -0
  106. data/ext/mathfunc/extconf.rb +18 -0
  107. data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +1 -0
  108. data/ext/mathfunc/lib/math/mathfunc.rb +15 -0
  109. data/ext/mathfunc/test/test_hypot.rb +5 -0
  110. data/ext/mathfunc/test/test_j0.rb +22 -0
  111. data/ext/mathfunc/test/test_jn.rb +8 -0
  112. data/ext/mathfunc/test/test_sph.rb +9 -0
  113. data/ext/narray/README +22 -0
  114. data/ext/narray/ca_wrap_narray.c +491 -0
  115. data/ext/narray/carray_narray.c +21 -0
  116. data/ext/narray/extconf.rb +57 -0
  117. data/ext/narray/lib/autoload/autoload_math_narray.rb +1 -0
  118. data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +11 -0
  119. data/ext/narray/lib/math/narray.rb +17 -0
  120. data/ext/narray/lib/math/narray_miss.rb +45 -0
  121. data/extconf.rb +3 -25
  122. data/lib/carray.rb +28 -0
  123. data/lib/carray/autoload/autoload_base.rb +23 -0
  124. data/lib/carray/autoload/autoload_graphics_gnuplot.rb +2 -0
  125. data/lib/carray/autoload/autoload_io_csv.rb +14 -0
  126. data/lib/carray/autoload/autoload_io_excel.rb +5 -0
  127. data/lib/carray/autoload/autoload_io_imagemagick.rb +6 -0
  128. data/lib/carray/autoload/autoload_io_pg.rb +6 -0
  129. data/lib/carray/autoload/autoload_io_sqlite3.rb +12 -0
  130. data/lib/carray/autoload/autoload_io_table.rb +1 -0
  131. data/lib/carray/autoload/autoload_math_histogram.rb +5 -0
  132. data/lib/carray/autoload/autoload_math_interp.rb +4 -0
  133. data/lib/carray/autoload/autoload_math_recurrence.rb +6 -0
  134. data/lib/carray/autoload/autoload_object_iterator.rb +1 -0
  135. data/lib/carray/autoload/autoload_object_link.rb +1 -0
  136. data/lib/carray/autoload/autoload_object_pack.rb +2 -0
  137. data/lib/carray/base/autoload.rb +94 -0
  138. data/lib/carray/base/basic.rb +1051 -0
  139. data/lib/carray/base/inspect.rb +252 -0
  140. data/lib/carray/base/iterator.rb +367 -0
  141. data/lib/carray/base/math.rb +403 -0
  142. data/lib/carray/base/obsolete.rb +93 -0
  143. data/lib/carray/base/serialize.rb +260 -0
  144. data/lib/carray/base/struct.rb +634 -0
  145. data/lib/carray/graphics/gnuplot.rb +2116 -0
  146. data/lib/carray/info.rb +112 -0
  147. data/lib/carray/io/csv.rb +560 -0
  148. data/lib/carray/io/excel.rb +26 -0
  149. data/lib/carray/io/imagemagick.rb +231 -0
  150. data/lib/carray/io/pg.rb +101 -0
  151. data/lib/carray/io/sqlite3.rb +202 -0
  152. data/lib/carray/io/table.rb +77 -0
  153. data/lib/carray/math/histogram.rb +179 -0
  154. data/lib/carray/math/interp.rb +57 -0
  155. data/lib/carray/math/interp/adapter_gsl_spline.rb +47 -0
  156. data/lib/carray/math/recurrence.rb +95 -0
  157. data/lib/carray/mkmf.rb +145 -0
  158. data/lib/carray/object/ca_obj_iterator.rb +52 -0
  159. data/lib/carray/object/ca_obj_link.rb +52 -0
  160. data/lib/carray/object/ca_obj_pack.rb +101 -0
  161. data/mkmath.rb +731 -0
  162. data/mt19937ar.c +182 -0
  163. data/mt19937ar.h +86 -0
  164. data/rdoc_main.rb +27 -0
  165. data/rdoc_math.rb +5 -0
  166. data/rdoc_stat.rb +31 -0
  167. data/ruby_carray.c +242 -0
  168. data/ruby_ccomplex.c +497 -0
  169. data/ruby_float_func.c +83 -0
  170. data/spec/CABlockIterator/CABlockIterator_spec.rb +113 -0
  171. data/spec/CArray/bug/store_spec.rb +27 -0
  172. data/spec/CArray/index/repeat_spec.rb +10 -0
  173. data/spec/CArray/method/eq_spec.rb +80 -0
  174. data/spec/CArray/method/is_nan_spec.rb +12 -0
  175. data/spec/CArray/method/ne_spec.rb +18 -0
  176. data/spec/CArray/method/round_spec.rb +11 -0
  177. data/spec/CArray/object/_attribute_spec.rb +32 -0
  178. data/spec/CArray/object/s_new_spec.rb +31 -0
  179. data/spec/CArray/serialize/Serialization_spec.rb +89 -0
  180. data/spec/spec_all.rb +11 -0
  181. data/test/test_ALL.rb +50 -0
  182. data/test/test_CABitfield.rb +59 -0
  183. data/test/test_CABlock.rb +208 -0
  184. data/test/test_CAField.rb +40 -0
  185. data/test/test_CAGrid.rb +76 -0
  186. data/test/test_CAMapping.rb +106 -0
  187. data/test/test_CAMmap.rb +11 -0
  188. data/test/test_CARefer.rb +94 -0
  189. data/test/test_CARepeat.rb +66 -0
  190. data/test/test_CASelect.rb +23 -0
  191. data/test/test_CAShift.rb +17 -0
  192. data/test/test_CATranspose.rb +61 -0
  193. data/test/test_CAVirtual.rb +214 -0
  194. data/test/test_CAWindow.rb +55 -0
  195. data/test/test_CAWrap.rb +9 -0
  196. data/test/test_CArray.rb +228 -0
  197. data/test/test_CComplex.rb +83 -0
  198. data/test/test_CScalar.rb +91 -0
  199. data/test/test_attribute.rb +281 -0
  200. data/test/test_block_iterator.rb +17 -0
  201. data/test/test_boolean.rb +99 -0
  202. data/test/test_cast.rb +33 -0
  203. data/test/test_class.rb +85 -0
  204. data/test/test_complex.rb +43 -0
  205. data/test/test_composite.rb +125 -0
  206. data/test/test_convert.rb +79 -0
  207. data/test/test_copy.rb +141 -0
  208. data/test/test_creation.rb +85 -0
  209. data/test/test_element.rb +146 -0
  210. data/test/test_extream.rb +55 -0
  211. data/test/test_generate.rb +75 -0
  212. data/test/test_index.rb +71 -0
  213. data/test/test_mask.rb +578 -0
  214. data/test/test_math.rb +98 -0
  215. data/test/test_narray.rb +64 -0
  216. data/test/test_order.rb +147 -0
  217. data/test/test_random.rb +15 -0
  218. data/test/test_ref_store.rb +211 -0
  219. data/test/test_stat.rb +414 -0
  220. data/test/test_struct.rb +72 -0
  221. data/test/test_virtual.rb +49 -0
  222. data/utils/ca_ase.rb +21 -0
  223. data/utils/ca_methods.rb +15 -0
  224. data/utils/cast_checker.rb +30 -0
  225. data/utils/create_rdoc.sh +9 -0
  226. data/utils/diff_method.rb +52 -0
  227. data/utils/extract_rdoc.rb +27 -0
  228. data/utils/make_tgz.sh +3 -0
  229. data/utils/remove_resource_fork.sh +5 -0
  230. data/version.h +3 -3
  231. metadata +266 -1
@@ -0,0 +1,1307 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ carray_core.c
4
+
5
+ This file is part of Ruby/CArray extension library.
6
+ You can redistribute it and/or modify it under the terms of
7
+ the Ruby Licence.
8
+
9
+ Copyright (C) 2005 Hiroki Motoyoshi
10
+
11
+ ---------------------------------------------------------------------------- */
12
+
13
+ #include "carray.h"
14
+ #include <stdarg.h>
15
+
16
+ /* definition of ca_endian */
17
+
18
+ #ifdef WORDS_BIGENDIAN
19
+ const int ca_endian = CA_BIG_ENDIAN;
20
+ #else
21
+ const int ca_endian = CA_LITTLE_ENDIAN;
22
+ #endif
23
+
24
+ /* definition of variables for ca_func mechanism */
25
+
26
+ VALUE ca_class[CA_OBJ_TYPE_MAX];
27
+ ca_operation_function_t ca_func[CA_OBJ_TYPE_MAX];
28
+ int ca_obj_num = 0;
29
+
30
+ /*
31
+ definition of validity of each data_type [1 for valid, 0 for invalid]
32
+
33
+ The validity is determined in the configuration by extconf.rb.
34
+ */
35
+
36
+ const int32_t
37
+ ca_valid[CA_NTYPE] = {
38
+ 1 /* fixlen type */,
39
+ #ifdef HAVE_TYPE_INT8_T
40
+ 1,
41
+ #else
42
+ 0,
43
+ #endif
44
+ #ifdef HAVE_TYPE_INT8_T
45
+ 1,
46
+ #else
47
+ 0,
48
+ #endif
49
+ #ifdef HAVE_TYPE_UINT8_T
50
+ 1,
51
+ #else
52
+ 0,
53
+ #endif
54
+ #ifdef HAVE_TYPE_INT16_T
55
+ 1,
56
+ #else
57
+ 0,
58
+ #endif
59
+ #ifdef HAVE_TYPE_UINT16_T
60
+ 1,
61
+ #else
62
+ 0,
63
+ #endif
64
+ #ifdef HAVE_TYPE_INT32_T
65
+ 1,
66
+ #else
67
+ 0,
68
+ #endif
69
+ #ifdef HAVE_TYPE_UINT32_T
70
+ 1,
71
+ #else
72
+ 0,
73
+ #endif
74
+ #ifdef HAVE_TYPE_INT64_T
75
+ 1,
76
+ #else
77
+ 0,
78
+ #endif
79
+ #ifdef HAVE_TYPE_UINT64_T
80
+ 1,
81
+ #else
82
+ 0,
83
+ #endif
84
+ #ifdef HAVE_TYPE_FLOAT32_T
85
+ 1,
86
+ #else
87
+ 0,
88
+ #endif
89
+ #ifdef HAVE_TYPE_FLOAT64_T
90
+ 1,
91
+ #else
92
+ 0,
93
+ #endif
94
+ #ifdef HAVE_TYPE_FLOAT128_T
95
+ 1,
96
+ #else
97
+ 0,
98
+ #endif
99
+ #ifdef HAVE_TYPE_CMPLX64_T
100
+ 1,
101
+ #else
102
+ 0,
103
+ #endif
104
+ #ifdef HAVE_TYPE_CMPLX128_T
105
+ 1,
106
+ #else
107
+ 0,
108
+ #endif
109
+ #ifdef HAVE_TYPE_CMPLX256_T
110
+ 1,
111
+ #else
112
+ 0,
113
+ #endif
114
+ 1
115
+ };
116
+
117
+ /* definition of ca_sizeof, the element data size */
118
+
119
+ const int32_t
120
+ ca_sizeof[CA_NTYPE] = {
121
+ 0 /* fixlen type */,
122
+ sizeof(boolean8_t),
123
+ sizeof(int8_t),
124
+ sizeof(uint8_t),
125
+ sizeof(int16_t),
126
+ sizeof(uint16_t),
127
+ sizeof(int32_t),
128
+ sizeof(uint32_t),
129
+ sizeof(int64_t),
130
+ sizeof(uint64_t),
131
+ sizeof(float32_t),
132
+ sizeof(float64_t),
133
+ sizeof(float128_t),
134
+ sizeof(cmplx64_t),
135
+ sizeof(cmplx128_t),
136
+ sizeof(cmplx256_t),
137
+ sizeof(VALUE),
138
+ };
139
+
140
+ /* definition of ca_type_name, the data type name */
141
+
142
+ const char *
143
+ ca_type_name[CA_NTYPE] = {
144
+ "fixlen",
145
+ "boolean",
146
+ "int8",
147
+ "uint8",
148
+ "int16",
149
+ "uint16",
150
+ "int32",
151
+ "uint32",
152
+ "int64",
153
+ "uint64",
154
+ "float32",
155
+ "float64",
156
+ "float128",
157
+ "cmplx64",
158
+ "cmplx128",
159
+ "cmplx256",
160
+ "object",
161
+ };
162
+
163
+ /*
164
+ casting table for ARRAY -> ARRAY
165
+
166
+ test = ca_cast_table[ary1->data_type][ary2->data_type]
167
+
168
+ test == 1 -> ary1 should be casted to ary2->data_type
169
+ test == 0 -> ary1 need not to be casted
170
+ test == -1 -> ary1 can't be casted to ary2->data_type,
171
+ try casting for ary2 vs ary1
172
+ */
173
+
174
+ const int
175
+ ca_cast_table[CA_NTYPE][CA_NTYPE] = {
176
+ /* fix bol i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 f12 c64 c12 c25 obj */
177
+ /*fix*/ { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1},
178
+ /*bol*/ {-1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
179
+ /* i8*/ {-1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
180
+ /* u8*/ {-1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
181
+ /*i16*/ {-1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
182
+ /*u16*/ {-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
183
+ /*i32*/ {-1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
184
+ /*u32*/ {-1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
185
+ /*i64*/ {-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
186
+ /*u64*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1},
187
+ /*f32*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1},
188
+ /*f64*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1},
189
+ /*f12*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1},
190
+ /*c64*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1},
191
+ /*c12*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1},
192
+ /*c25*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1},
193
+ /*obj*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0},
194
+ };
195
+
196
+ /*
197
+ casting table for SCALAR -> ARRAY
198
+
199
+ test = ca_cast_table[scl->data_type][ary->data_type]
200
+
201
+ test == 1 -> scl should be casted to ary->data_type
202
+ test == 0 -> scl need not to be casted
203
+ test == -1 -> scl can't be casted to ary->data_type
204
+ */
205
+
206
+ const int
207
+ ca_cast_table2[CA_NTYPE][CA_NTYPE] = {
208
+ /* fix bol i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 f12 c64 c12 c25 obj */
209
+ /*fix*/ { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1},
210
+ /*bol*/ {-1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
211
+ /* i8*/ {-1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
212
+ /* u8*/ {-1, -1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
213
+ /*i16*/ {-1, -1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
214
+ /*u16*/ {-1, -1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
215
+ /*i32*/ {-1, -1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
216
+ /*u32*/ {-1, -1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
217
+ /*i64*/ {-1, -1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
218
+ /*u64*/ {-1, -1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1},
219
+ /*f32*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1},
220
+ /*f64*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 1, 1, 1, 1},
221
+ /*f12*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 0, 1, 1, 1, 1},
222
+ /*c64*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1},
223
+ /*c12*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 1},
224
+ /*c25*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 0, 1},
225
+ /*obj*/ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0},
226
+ };
227
+
228
+ /* ------------------------------------------------------------------- */
229
+
230
+ /*
231
+ initialization of fundamental classes
232
+ * CArray
233
+ * CAWrap
234
+ * CScalar
235
+ * CARefer
236
+ * CABlock
237
+ * CASelect
238
+ * CAObject
239
+ * CARepeat
240
+ * CAUnboundRepeat
241
+ */
242
+
243
+ void
244
+ ca_init_obj_type ()
245
+ {
246
+ extern ca_operation_function_t ca_array_func;
247
+ extern ca_operation_function_t ca_wrap_func;
248
+ extern ca_operation_function_t ca_scalar_func;
249
+ extern ca_operation_function_t ca_refer_func;
250
+ extern ca_operation_function_t ca_block_func;
251
+ extern ca_operation_function_t ca_select_func;
252
+ extern ca_operation_function_t ca_object_func;
253
+ extern ca_operation_function_t ca_repeat_func;
254
+ extern ca_operation_function_t ca_ubrep_func;
255
+
256
+ /* CArray */
257
+ ca_func[CA_OBJ_ARRAY] = ca_array_func;
258
+ ca_class[CA_OBJ_ARRAY] = rb_cCArray;
259
+
260
+ /* CAWrap */
261
+ ca_func[CA_OBJ_ARRAY_WRAP] = ca_wrap_func;
262
+ ca_class[CA_OBJ_ARRAY_WRAP] = rb_cCAWrap;
263
+
264
+ /* CAScalar */
265
+ ca_func[CA_OBJ_SCALAR] = ca_scalar_func;
266
+ ca_class[CA_OBJ_SCALAR] = rb_cCScalar;
267
+
268
+ /* CARefer */
269
+ ca_func[CA_OBJ_REFER] = ca_refer_func;
270
+ ca_class[CA_OBJ_REFER] = rb_cCARefer;
271
+
272
+ /* CABlock */
273
+ ca_func[CA_OBJ_BLOCK] = ca_block_func;
274
+ ca_class[CA_OBJ_BLOCK] = rb_cCABlock;
275
+
276
+ /* CASelect */
277
+ ca_func[CA_OBJ_SELECT] = ca_select_func;
278
+ ca_class[CA_OBJ_SELECT] = rb_cCASelect;
279
+
280
+ /* CAObject */
281
+ ca_func[CA_OBJ_OBJECT] = ca_object_func;
282
+ ca_class[CA_OBJ_OBJECT] = rb_cCAObject;
283
+
284
+ /* CARepeat */
285
+ ca_func[CA_OBJ_REPEAT] = ca_repeat_func;
286
+ ca_class[CA_OBJ_REPEAT] = rb_cCARepeat;
287
+
288
+ /* CAUnboundRepeat */
289
+ ca_func[CA_OBJ_UNBOUND_REPEAT] = ca_ubrep_func;
290
+ ca_class[CA_OBJ_UNBOUND_REPEAT] = rb_cCAUnboundRepeat;
291
+
292
+ ca_obj_num = 9;
293
+ }
294
+
295
+ /* api: ca_install_obj_type
296
+ regsters a sub-class of CArray
297
+ */
298
+
299
+ int
300
+ ca_install_obj_type (VALUE klass, ca_operation_function_t func)
301
+ {
302
+ int obj_type = ca_obj_num++;
303
+
304
+ if ( ca_obj_num >= CA_OBJ_TYPE_MAX ) {
305
+ rb_raise(rb_eRuntimeError,
306
+ "too many CArray object types installed <CA_OBJ_TYPE_MAX = %i>",
307
+ CA_OBJ_TYPE_MAX);
308
+ }
309
+
310
+ func.obj_type = obj_type;
311
+
312
+ ca_class[obj_type] = klass;
313
+ ca_func[obj_type] = func;
314
+
315
+ return obj_type;
316
+ }
317
+
318
+ /* ------------------------------------------------------------------- */
319
+
320
+ /* api: ca_mark
321
+ mark function for any carray object
322
+ */
323
+
324
+ void
325
+ ca_mark (void *ap)
326
+ {
327
+ CArray *ca = (CArray *) ap;
328
+
329
+ if ( ca_is_object_type(ca) ) { /* object type array */
330
+ if ( ca_is_attached(ca) ) { /* entity array */
331
+ VALUE *p = (VALUE*) ca->ptr;
332
+ int32_t n = ca->elements;
333
+ while ( n-- ) {
334
+ rb_gc_mark(*p++);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ /* api: ca_free
341
+ free function for the carray object needs free operation.
342
+ */
343
+
344
+ void
345
+ ca_free (void *ap)
346
+ {
347
+ if ( ap ) {
348
+ CArray *ca = (CArray *) ap;
349
+ ca_func[ca->obj_type].free_object(ap); /* delegate */
350
+ }
351
+ }
352
+
353
+ /* api: ca_free_nop
354
+ (dummy) free function for the carray object does not need free operation.
355
+ */
356
+
357
+ void
358
+ ca_free_nop (void *ap)
359
+ {
360
+ }
361
+
362
+ /* ------------------------------------------------------------------- */
363
+
364
+ /* api: ca_wrap_struct
365
+ wraps CArray struct in C -> Ruby's object
366
+ */
367
+
368
+ VALUE
369
+ ca_wrap_struct (void *ap)
370
+ {
371
+ CArray *ca = (CArray *) ap;
372
+ return Data_Wrap_Struct(ca_class[ca->obj_type], ca_mark, ca_free, ca);
373
+ }
374
+
375
+ /* ------------------------------------------------------------------- */
376
+
377
+ /* calculate index from address */
378
+
379
+ void
380
+ ca_addr2index (void *ap, int32_t addr, int32_t *idx)
381
+ {
382
+ CArray *ca = (CArray *) ap;
383
+ int32_t *dim = ca->dim;
384
+ int32_t i;
385
+ for (i=ca->rank-1; i>=0; i--) {
386
+ idx[i] = addr % dim[i];
387
+ addr /= dim[i];
388
+ }
389
+ }
390
+
391
+ /* calculate address from index */
392
+
393
+ int32_t
394
+ ca_index2addr (void *ap, int32_t *idx)
395
+ {
396
+ CArray *ca = (CArray *) ap;
397
+ int32_t *dim = ca->dim;
398
+ int32_t n, i;
399
+ n = idx[0];
400
+ for (i=1; i<ca->rank; i++) {
401
+ n = dim[i]*n+idx[i];
402
+ }
403
+ return n;
404
+ }
405
+
406
+ /* ------------------------------------------------------------------- */
407
+
408
+ /* The cyclic reference detection should be done in
409
+ + ca_fetch_addr, ca_fetch_index,
410
+ + ca_store_addr, ca_store_index,
411
+ to avoid the system stack error in reference of the object array.
412
+ */
413
+
414
+ void
415
+ ca_set_cyclic_check(void *ap)
416
+ {
417
+ CArray *ca = (CArray *) ap;
418
+ /* ca.data_type == CA_OBJECT */
419
+ if ( ca_is_object_type(ca) ) {
420
+ if ( ca->flags & CA_FLAG_CYCLE_CHECK ) {
421
+ rb_raise(rb_eRuntimeError, "cyclic reference is not allowed in CArray");
422
+ }
423
+ ca_set_flag(ca, CA_FLAG_CYCLE_CHECK);
424
+ }
425
+ }
426
+
427
+ void
428
+ ca_clear_cyclic_check(void *ap)
429
+ {
430
+ CArray *ca = (CArray *) ap;
431
+ /* ca.data_type == CA_OBJECT */
432
+ if ( ca_is_object_type(ca) ) {
433
+ ca_unset_flag(ca, CA_FLAG_CYCLE_CHECK);
434
+ }
435
+ }
436
+
437
+ void
438
+ ca_test_cyclic_check(void *ap, void *ptr)
439
+ {
440
+ CArray *ca = (CArray *) ap;
441
+
442
+ /* ca.data_type == CA_OBJECT */
443
+ if ( ca_is_object_type(ca) ) {
444
+ VALUE rval = *(VALUE*) ptr;
445
+ if ( rb_obj_is_carray(rval) ) {
446
+ CArray *cv;
447
+ Data_Get_Struct(rval, CArray, cv);
448
+ if ( ca_test_flag(cv, CA_FLAG_CYCLE_CHECK) ) {
449
+ rb_raise(rb_eRuntimeError, "cyclic reference is not allowed in CArray");
450
+ }
451
+ }
452
+ }
453
+ }
454
+
455
+ /* ------------------------------------------------------------------- */
456
+
457
+ /* return pointer of the element at given address */
458
+
459
+ void *
460
+ ca_ptr_at_addr (void *ap, int32_t addr)
461
+ {
462
+ CArray *ca = (CArray *) ap;
463
+
464
+ if ( ca->ptr ) {
465
+ switch ( ca->obj_type ) {
466
+ case CA_OBJ_SCALAR:
467
+ return ca->ptr;
468
+ case CA_OBJ_REFER:
469
+ return ((CARefer*)ca)->parent->ptr + ca->bytes * addr;
470
+ default:
471
+ return ca->ptr + ca->bytes * addr;
472
+ }
473
+ }
474
+
475
+ return ca_func[ca->obj_type].ptr_at_addr(ap, addr);
476
+ }
477
+
478
+ /* return pointer of the element at given index */
479
+
480
+ void *
481
+ ca_ptr_at_index (void *ap, int32_t *idx)
482
+ {
483
+ CArray *ca = (CArray *) ap;
484
+ return ca_func[ca->obj_type].ptr_at_index(ca, idx);
485
+ }
486
+
487
+ /* fetch data of the element at given address to memory pointed by pval */
488
+
489
+ void
490
+ ca_fetch_addr (void *ap, int32_t addr, void *pval)
491
+ {
492
+ CArray *ca = (CArray *) ap;
493
+ char *ptr = (char *)pval;
494
+
495
+ ca_set_cyclic_check(ca);
496
+
497
+ if ( ca->ptr ) {
498
+ memcpy(ptr, ca->ptr + ca->bytes * addr, ca->bytes);
499
+ }
500
+ else if ( ca_func[ca->obj_type].fetch_addr ) {
501
+ ca_func[ca->obj_type].fetch_addr(ca, addr, ptr);
502
+ }
503
+ else if ( ca_func[ca->obj_type].fetch_index ) { /* delegate -> fetch_index */
504
+ int32_t idx[CA_RANK_MAX];
505
+ ca_addr2index(ca, addr, idx);
506
+ ca_func[ca->obj_type].fetch_index(ca, idx, ptr);
507
+ }
508
+ else {
509
+ rb_raise(rb_eRuntimeError,
510
+ "[BUG] fetch_addr or fetch_index " \
511
+ "are not defined for object type <%i>",
512
+ ca->obj_type);
513
+ }
514
+
515
+ ca_test_cyclic_check(ca, ptr);
516
+
517
+ ca_clear_cyclic_check(ca);
518
+ }
519
+
520
+ /* store value pointed by pval to the element at given address */
521
+
522
+ void
523
+ ca_store_addr (void *ap, int32_t addr, void *pval)
524
+ {
525
+ CArray *ca = (CArray *) ap;
526
+ char *ptr = (char *)pval;
527
+
528
+ if ( ca_is_readonly(ca) ) { /* read only array */
529
+ rb_raise(rb_eRuntimeError,
530
+ "can not store data to read-only array");
531
+ }
532
+
533
+ ca_set_cyclic_check(ca);
534
+
535
+ if ( ca->ptr ) {
536
+ memcpy(ca->ptr + ca->bytes * addr, ptr, ca->bytes);
537
+ }
538
+ else if ( ca_func[ca->obj_type].store_addr ) {
539
+ ca_func[ca->obj_type].store_addr(ca, addr, ptr);
540
+ }
541
+ else if ( ca_func[ca->obj_type].store_index ) { /* delegate -> store_index */
542
+ int32_t idx[CA_RANK_MAX];
543
+ ca_addr2index(ca, addr, idx);
544
+ ca_func[ca->obj_type].store_index(ca, idx, ptr);
545
+ }
546
+ else {
547
+ ca_clear_cyclic_check(ca);
548
+ rb_raise(rb_eRuntimeError,
549
+ "[BUG] store_addr or store_index "\
550
+ "are not defined for object type <%i>",
551
+ ca->obj_type);
552
+ }
553
+
554
+ ca_clear_cyclic_check(ca);
555
+
556
+ }
557
+
558
+ /* fetch data of the element at given index to memory pointed by pval */
559
+
560
+ void
561
+ ca_fetch_index (void *ap, int32_t *idx, void *pval)
562
+ {
563
+ CArray *ca = (CArray *) ap;
564
+ char *ptr = (char *)pval;
565
+
566
+ ca_set_cyclic_check(ca);
567
+
568
+ if ( ca_func[ca->obj_type].fetch_index ) {
569
+ ca_func[ca->obj_type].fetch_index(ca, idx, ptr);
570
+ }
571
+ else if ( ca_func[ca->obj_type].fetch_addr ) { /* delegate -> fetch_addr */
572
+ int32_t addr = ca_index2addr(ca, idx);
573
+ ca_func[ca->obj_type].fetch_addr(ca, addr, ptr);
574
+ }
575
+ else {
576
+ ca_clear_cyclic_check(ca);
577
+ rb_raise(rb_eRuntimeError,
578
+ "[BUG] fetch_addr or fetch_index " \
579
+ "are not defined for object type <%i>",
580
+ ca->obj_type);
581
+ }
582
+
583
+ ca_test_cyclic_check(ca, ptr);
584
+
585
+ ca_clear_cyclic_check(ca);
586
+ }
587
+
588
+ /* store value pointed by pval to the element at given index */
589
+
590
+ void
591
+ ca_store_index (void *ap, int32_t *idx, void *pval)
592
+ {
593
+ CArray *ca = (CArray *) ap;
594
+ char *ptr = (char *) pval;
595
+
596
+ if ( ca_is_readonly(ca) ) { /* read only array */
597
+ rb_raise(rb_eRuntimeError,
598
+ "can not store data to read-only array");
599
+ }
600
+
601
+ ca_set_cyclic_check(ca);
602
+
603
+ if ( ca_func[ca->obj_type].store_index ) {
604
+ ca_func[ca->obj_type].store_index(ca, idx, ptr);
605
+ }
606
+ else if ( ca_func[ca->obj_type].store_addr ) { /* delegate -> store_addr */
607
+ int32_t addr = ca_index2addr(ca, idx);
608
+ ca_func[ca->obj_type].store_addr(ca, addr, ptr);
609
+ }
610
+ else {
611
+ rb_raise(rb_eRuntimeError,
612
+ "[BUG] store_addr or store_index "\
613
+ "are not defined for object type <%i>",
614
+ ca->obj_type);
615
+ }
616
+
617
+ ca_clear_cyclic_check(ca);
618
+
619
+ }
620
+
621
+ /* ------------------------------------------------------------------- */
622
+
623
+ /* make ca->ptr to point the allocated memory block */
624
+
625
+ void
626
+ ca_allocate (void *ap)
627
+ {
628
+ CArray *ca = (CArray *) ap;
629
+
630
+ if ( ! ca ) {
631
+ return;
632
+ }
633
+
634
+ if ( ca_is_virtual(ca) ) { /* virtual array */
635
+
636
+ CAVIRTUAL(ca)->attach += 1; /* increments attach level */
637
+ if ( CAVIRTUAL(ca)->attach > CA_ATTACH_MAX ) {
638
+ rb_raise(rb_eRuntimeError,
639
+ "too large attach count of virtual array");
640
+ }
641
+
642
+ if ( ! ca->ptr ) {
643
+ ca_func[ca->obj_type].allocate(ap);
644
+ }
645
+ }
646
+ else { /* entity array */
647
+ ca_func[ca->obj_type].allocate(ap);
648
+ }
649
+
650
+ if ( ca->data_type == CA_OBJECT ) { /* protection against GC */
651
+ volatile VALUE rzero = INT2FIX(0);
652
+ VALUE *p = (VALUE*)ca->ptr;
653
+ int32_t i;
654
+ for (i=0; i<ca->elements; i++) {
655
+ *p++ = rzero;
656
+ }
657
+ }
658
+
659
+ ca_clear_mask(ca); /* ca_update_mask called in ca_clear_mask */
660
+ ca_allocate(ca->mask);
661
+ }
662
+
663
+ /* attach parent's data to ca->ptr */
664
+
665
+ void
666
+ ca_attach (void *ap)
667
+ {
668
+ CArray *ca = (CArray *) ap;
669
+
670
+ if ( ! ca ) {
671
+ return;
672
+ }
673
+
674
+ if ( ca_is_virtual(ca) ) { /* virtual array */
675
+
676
+ CAVIRTUAL(ca)->attach += 1; /* increments attach level */
677
+ if ( CAVIRTUAL(ca)->attach > CA_ATTACH_MAX ) {
678
+ rb_raise(rb_eRuntimeError,
679
+ "too large attach count of virtual array");
680
+ }
681
+
682
+ if ( ! ca->ptr ) {
683
+ ca_func[ca->obj_type].attach(ap);
684
+ }
685
+ }
686
+ else { /* entity array */
687
+ ca_func[ca->obj_type].attach(ap);
688
+ }
689
+
690
+ ca_update_mask(ca);
691
+ ca_attach(ca->mask);
692
+ }
693
+
694
+ /* attach parent's data to ca->ptr */
695
+
696
+ void
697
+ ca_update (void *ap)
698
+ {
699
+ CArray *ca = (CArray *) ap;
700
+
701
+ if ( ! ca ) {
702
+ return;
703
+ }
704
+
705
+ if ( ca_is_virtual(ca) ) { /* virtual array */
706
+
707
+ if ( ca->ptr ) {
708
+ ca_func[ca->obj_type].copy_data(ca, ca->ptr);
709
+ }
710
+ else {
711
+ rb_raise(rb_eRuntimeError,
712
+ "[BUG] ca_update() called for not-attached virtal array");
713
+ }
714
+
715
+ }
716
+
717
+ ca_update_mask(ca);
718
+ ca_update(ca->mask);
719
+ }
720
+
721
+ /* synchronize the data pointed by ca->ptr to parent's memory block */
722
+
723
+ void
724
+ ca_sync (void *ap)
725
+ {
726
+ CArray *ca = (CArray *) ap;
727
+
728
+ if ( ! ca ) {
729
+ return;
730
+ }
731
+
732
+ if ( ! ca->ptr ) {
733
+ rb_raise(rb_eRuntimeError,
734
+ "[BUG] tried to sync data to detached array");
735
+ }
736
+
737
+ if ( ca_is_readonly(ca) ) {
738
+ rb_raise(rb_eRuntimeError,
739
+ "can not modify read-only array");
740
+ }
741
+
742
+ ca_update_mask(ca);
743
+ ca_sync(ca->mask);
744
+
745
+ if ( ca_is_virtual(ca) ) { /* virtual array */
746
+ if ( ! CAVIRTUAL(ca)->nosync ) { /* FIXME : */
747
+ ca_func[ca->obj_type].sync(ap);
748
+ }
749
+ }
750
+ else { /* enitity array */
751
+ ca_func[ca->obj_type].sync(ap);
752
+ }
753
+
754
+ }
755
+
756
+ /* make ca->ptr to be detached */
757
+
758
+ void
759
+ ca_detach (void *ap)
760
+ {
761
+ CArray *ca = (CArray *) ap;
762
+
763
+ if ( ! ca ) {
764
+ return;
765
+ }
766
+
767
+ if ( ! ca->ptr ) {
768
+ rb_raise(rb_eRuntimeError,
769
+ "[BUG] tried to detach a detached array");
770
+ }
771
+
772
+ if ( ca_is_virtual(ca) ) { /* virtual array */
773
+ if ( CAVIRTUAL(ca)->attach == 1 ) {
774
+ ca_func[ca->obj_type].detach(ap);
775
+ }
776
+ CAVIRTUAL(ca)->attach -= 1;
777
+ }
778
+ else { /* entity array */
779
+ ca_func[ca->obj_type].detach(ap);
780
+ }
781
+
782
+ ca_update_mask(ca);
783
+ ca_detach(ca->mask);
784
+ }
785
+
786
+ /* multiple versions of ca_allocate, ca_attach, ca_sync, ca_detach */
787
+
788
+ void
789
+ ca_allocate_n (int n, ...)
790
+ {
791
+ va_list args;
792
+ va_start(args, n);
793
+ while ( n-- ) {
794
+ ca_allocate(va_arg(args, CArray *));
795
+ }
796
+ va_end(args);
797
+ }
798
+
799
+ void
800
+ ca_attach_n (int n, ...)
801
+ {
802
+ va_list args;
803
+ va_start(args, n);
804
+ while ( n-- ) {
805
+ ca_attach(va_arg(args, CArray *));
806
+ }
807
+ va_end(args);
808
+ }
809
+
810
+ void
811
+ ca_update_n (int n, ...)
812
+ {
813
+ va_list args;
814
+ va_start(args, n);
815
+ while ( n-- ) {
816
+ ca_update(va_arg(args, CArray *));
817
+ }
818
+ va_end(args);
819
+ }
820
+
821
+ void
822
+ ca_sync_n (int n, ...)
823
+ {
824
+ va_list args;
825
+ va_start(args, n);
826
+ while ( n-- ) {
827
+ ca_sync(va_arg(args, CArray *));
828
+ }
829
+ va_end(args);
830
+ }
831
+
832
+ void
833
+ ca_detach_n (int n, ...)
834
+ {
835
+ va_list args;
836
+ va_start(args, n);
837
+ while ( n-- )
838
+ ca_detach(va_arg(args, CArray *));
839
+ va_end(args);
840
+ }
841
+
842
+ /* ------------------------------------------------------------------- */
843
+
844
+ /* attach parent's data to given pointer, not to ca->ptr */
845
+
846
+ void
847
+ ca_copy_data (void *ap, char *ptr)
848
+ {
849
+ CArray *ca = (CArray *) ap;
850
+ ca_func[ca->obj_type].copy_data(ap, ptr); /* delegate */
851
+ }
852
+
853
+ /* synchronize the data pointed by given pointer to parent's data */
854
+
855
+ void
856
+ ca_sync_data (void *ap, char *ptr)
857
+ {
858
+ CArray *ca = (CArray *) ap;
859
+
860
+ if ( ca_is_readonly(ca) ) {
861
+ rb_raise(rb_eRuntimeError,
862
+ "can not sync data to read-only array");
863
+ }
864
+
865
+ if ( ca_is_virtual(ca) ) { /* virtual array */
866
+ if ( CAVIRTUAL(ca)->nosync ) { /* ca is to be attached */
867
+ ca_func[CA_OBJ_ARRAY].sync_data(ap, ptr);
868
+ }
869
+ else {
870
+ ca_func[ca->obj_type].sync_data(ap, ptr);
871
+ }
872
+ }
873
+ else { /* entity array */
874
+ ca_func[ca->obj_type].sync_data(ap, ptr);
875
+ }
876
+ }
877
+
878
+ /* fill data from given pointer */
879
+
880
+ void
881
+ ca_fill_data (void *ap, void *aptr)
882
+ {
883
+ CArray *ca = (CArray *) ap;
884
+ char *ptr = (char *) aptr;
885
+
886
+ if ( ca_is_readonly(ca) ) {
887
+ rb_raise(rb_eRuntimeError,
888
+ "can not fill data to read-only array");
889
+ }
890
+
891
+ if ( ca_is_virtual(ca) ) { /* virtual array */
892
+ if ( ca_is_attached(ca) ) { /* ca is to be attached */
893
+ ca_func[CA_OBJ_ARRAY].fill_data(ap, ptr);
894
+ }
895
+ else {
896
+ ca_func[ca->obj_type].fill_data(ap, ptr);
897
+ }
898
+ }
899
+ else { /* entity array */
900
+ ca_func[ca->obj_type].fill_data(ap, ptr);
901
+ }
902
+ }
903
+
904
+ /* ------------------------------------------------------------------- */
905
+
906
+ /* clone CArray struct */
907
+
908
+ void *
909
+ ca_clone (void *ap)
910
+ {
911
+ CArray *ca = (CArray *) ap;
912
+ return ca_func[ca->obj_type].clone(ap);
913
+ }
914
+
915
+ /* fill parent's data with the data pointed by aptr */
916
+
917
+ void
918
+ ca_fill (void *ap, void *aptr)
919
+ {
920
+ CArray *ca = (CArray *) ap;
921
+ char *ptr = (char *) aptr;
922
+
923
+ if ( ca_is_readonly(ca) ) {
924
+ rb_raise(rb_eRuntimeError, "can't fill read-only carray");
925
+ }
926
+
927
+ ca_fill_data(ap, ptr);
928
+ }
929
+
930
+ /* ------------------------------------------------------------------- */
931
+
932
+ /* subroutines for CArray.attach, CArray.attach!
933
+ CArray#attach, CArray#attach! */
934
+
935
+ static void
936
+ rb_ca_attach_i (VALUE self)
937
+ {
938
+ CArray *ca;
939
+ if ( rb_obj_is_carray(self) ) {
940
+ Data_Get_Struct(self, CArray, ca);
941
+ ca_attach(ca);
942
+ if ( ca_is_virtual(ca) ) {
943
+ CAVIRTUAL(ca)->nosync += 1;
944
+ if ( CAVIRTUAL(ca)->nosync > 64 ) {
945
+ rb_raise(rb_eRuntimeError, "nosync count exceeds 64");
946
+ }
947
+ }
948
+ }
949
+ }
950
+
951
+ static void
952
+ rb_ca_sync_i (VALUE self)
953
+ {
954
+ CArray *ca;
955
+ if ( rb_obj_is_carray(self) ) {
956
+ Data_Get_Struct(self, CArray, ca);
957
+ if ( ca_is_virtual(ca) ) {
958
+ CAVIRTUAL(ca)->nosync -= 1;
959
+ ca_sync(ca);
960
+ CAVIRTUAL(ca)->nosync += 1;
961
+ }
962
+ else {
963
+ ca_sync(ca);
964
+ }
965
+ }
966
+ }
967
+
968
+ static void
969
+ rb_ca_detach_i (VALUE self)
970
+ {
971
+ CArray *ca;
972
+ if ( rb_obj_is_carray(self) ) {
973
+ Data_Get_Struct(self, CArray, ca);
974
+ if ( ca_is_virtual(ca) ) { /* virtual array */
975
+ CAVIRTUAL(ca)->nosync -= 1;
976
+ ca_detach(ca);
977
+ }
978
+ else { /* entity array */
979
+ ca_detach(ca);
980
+ }
981
+ }
982
+ }
983
+
984
+ /* ------------------------------------------------------------------- */
985
+
986
+ static VALUE
987
+ rb_ca_s_ensure_detach (VALUE list)
988
+ {
989
+ volatile VALUE obj;
990
+ int i;
991
+
992
+ for (i=0; i<RARRAY_LEN(list); i++) {
993
+ obj = rb_ary_entry(list, i);
994
+ rb_ca_detach_i(obj);
995
+ }
996
+
997
+ return Qnil;
998
+ }
999
+
1000
+ /* rdoc:
1001
+ def CArray.attach(*argv) # :nodoc:
1002
+ yield
1003
+ end
1004
+ */
1005
+
1006
+ static VALUE
1007
+ rb_ca_s_attach (int argc, VALUE *argv, VALUE self)
1008
+ {
1009
+ volatile VALUE list, obj;
1010
+ int i;
1011
+
1012
+ list = rb_ary_new4(argc, argv);
1013
+
1014
+ for (i=0; i<RARRAY_LEN(list); i++) {
1015
+ obj = rb_ary_entry(list, i);
1016
+ rb_ca_attach_i(obj);
1017
+ }
1018
+
1019
+ return rb_ensure(rb_yield_splat, list, rb_ca_s_ensure_detach, list);
1020
+ }
1021
+
1022
+ static VALUE
1023
+ rb_ca_s_ensure_sync_detach (VALUE list)
1024
+ {
1025
+ volatile VALUE obj;
1026
+ int i;
1027
+
1028
+ for (i=0; i<RARRAY_LEN(list); i++) {
1029
+ obj = rb_ary_entry(list, i);
1030
+ rb_ca_sync_i(obj);
1031
+ rb_ca_detach_i(obj);
1032
+ }
1033
+
1034
+ return Qnil;
1035
+ }
1036
+
1037
+ /* rdoc:
1038
+ def CArray.attach!(*argv) # :nodoc:
1039
+ yield
1040
+ end
1041
+ */
1042
+
1043
+ static VALUE
1044
+ rb_ca_s_attach_bang (int argc, VALUE *argv, VALUE self)
1045
+ {
1046
+ volatile VALUE list, obj;
1047
+ int i;
1048
+
1049
+ list = rb_ary_new4(argc, argv);
1050
+
1051
+ for (i=0; i<RARRAY_LEN(list); i++) {
1052
+ obj = rb_ary_entry(list, i);
1053
+ rb_ca_modify(obj);
1054
+ rb_ca_attach_i(obj);
1055
+ }
1056
+
1057
+ return rb_ensure(rb_yield_splat, list, rb_ca_s_ensure_sync_detach, list);
1058
+ }
1059
+
1060
+ static VALUE
1061
+ rb_ca_ensure_detach (VALUE self)
1062
+ {
1063
+ rb_ca_detach_i(self);
1064
+ return Qnil;
1065
+ }
1066
+
1067
+ /* rdoc:
1068
+ class CArray
1069
+ def attach () # :nodoc:
1070
+ yield
1071
+ end
1072
+ end
1073
+ */
1074
+
1075
+ static VALUE
1076
+ rb_ca_attach (VALUE self)
1077
+ {
1078
+ rb_ca_attach_i(self);
1079
+ return rb_ensure(rb_yield, self, rb_ca_ensure_detach, self);
1080
+ }
1081
+
1082
+ static VALUE
1083
+ rb_ca_ensure_sync_detach (VALUE self)
1084
+ {
1085
+ rb_ca_sync_i(self);
1086
+ rb_ca_detach_i(self);
1087
+ return Qnil;
1088
+ }
1089
+
1090
+ /* rdoc:
1091
+ class CArray
1092
+ def attach! () # :nodoc:
1093
+ yield
1094
+ end
1095
+ end
1096
+ */
1097
+
1098
+ static VALUE
1099
+ rb_ca_attach_bang (VALUE self)
1100
+ {
1101
+ rb_ca_modify(self);
1102
+ rb_ca_attach_i(self);
1103
+ return rb_ensure(rb_yield, self, rb_ca_ensure_sync_detach, self);
1104
+ }
1105
+
1106
+ /* CArray#__attach__ */
1107
+
1108
+ static VALUE
1109
+ rb_ca__attach__ (VALUE self)
1110
+ {
1111
+ rb_ca_attach_i(self);
1112
+ return self;
1113
+ }
1114
+
1115
+ /* CArray#__sync__ */
1116
+
1117
+ static VALUE
1118
+ rb_ca__sync__ (VALUE self)
1119
+ {
1120
+ rb_ca_modify(self);
1121
+ rb_ca_sync_i(self);
1122
+ return self;
1123
+ }
1124
+
1125
+ /* CArray#__detach__ */
1126
+
1127
+ static VALUE
1128
+ rb_ca__detach__ (VALUE self)
1129
+ {
1130
+ rb_ca_detach_i(self);
1131
+ return self;
1132
+ }
1133
+
1134
+ /* ------------------------------------------------------------------- */
1135
+
1136
+ static ID id_decode, id_encode;
1137
+
1138
+ VALUE
1139
+ rb_ca_data_class_decode (VALUE self, VALUE str)
1140
+ {
1141
+ if ( rb_ca_has_data_class(self) ) {
1142
+ volatile VALUE data_class = rb_ca_data_class(self);
1143
+ return rb_funcall(data_class, id_decode, 1, str);
1144
+ }
1145
+ else {
1146
+ return str;
1147
+ }
1148
+ }
1149
+
1150
+ VALUE
1151
+ rb_ca_data_class_encode (VALUE self, VALUE obj)
1152
+ {
1153
+ if ( rb_ca_has_data_class(self) ) {
1154
+ volatile VALUE data_class = rb_ca_data_class(self);
1155
+ if ( rb_obj_is_kind_of(obj, data_class) ) {
1156
+ return rb_funcall(obj, id_encode, 0);
1157
+ }
1158
+ }
1159
+ return obj;
1160
+ }
1161
+
1162
+ /* ------------------------------------------------------------------- */
1163
+
1164
+ /* rdoc:
1165
+ class CArray
1166
+ # Returns data class member names
1167
+ def members
1168
+ end
1169
+ end
1170
+ */
1171
+
1172
+ VALUE
1173
+ rb_ca_members (VALUE self)
1174
+ {
1175
+ VALUE data_class = rb_ca_data_class(self);
1176
+ if ( NIL_P(data_class) ) {
1177
+ rb_raise(rb_eRuntimeError, "carray doesn't have data class");
1178
+ }
1179
+ else {
1180
+ return rb_obj_clone(rb_const_get(data_class, rb_intern("MEMBERS")));
1181
+ }
1182
+ }
1183
+
1184
+ VALUE
1185
+ rb_ca_field_as_member (VALUE self, VALUE sym)
1186
+ {
1187
+ VALUE data_class = rb_ca_data_class(self);
1188
+ VALUE member;
1189
+ VALUE obj;
1190
+
1191
+ if ( NIL_P(data_class) ) {
1192
+ rb_raise(rb_eRuntimeError, "carray doesn't have data class");
1193
+ }
1194
+
1195
+ member = rb_ivar_get(self, rb_intern("member"));
1196
+
1197
+ if ( NIL_P(member) ) {
1198
+ rb_raise(rb_eRuntimeError,
1199
+ "[BUG] instance variable member doesn't defined "\
1200
+ "for data_class array");
1201
+ }
1202
+
1203
+ if ( TYPE(sym) == T_SYMBOL ) {
1204
+ sym = rb_funcall(sym, rb_intern("to_s"), 0);
1205
+ }
1206
+ else if ( rb_obj_is_kind_of(sym, rb_cInteger) ) {
1207
+ VALUE member_names = rb_const_get(data_class, rb_intern("MEMBERS"));
1208
+ sym = rb_ary_entry(member_names, NUM2INT(sym));
1209
+ }
1210
+
1211
+ obj = rb_hash_aref(member, sym);
1212
+
1213
+ if ( rb_obj_is_carray(obj) ) {
1214
+ return obj;
1215
+ }
1216
+ else {
1217
+ VALUE MEMBER_TABLE = rb_const_get(data_class, rb_intern("MEMBER_TABLE"));
1218
+ VALUE info = rb_hash_aref(MEMBER_TABLE, sym);
1219
+ if ( NIL_P(info) ) {
1220
+ rb_raise(rb_eRuntimeError,
1221
+ "can't find data_member named <%s>", StringValuePtr(sym));
1222
+ }
1223
+ Check_Type(info, T_ARRAY);
1224
+ obj = rb_apply(self, rb_intern("field"), info);
1225
+ rb_hash_aset(member, sym, obj);
1226
+ return obj;
1227
+ }
1228
+ }
1229
+
1230
+ /* rdoc:
1231
+ class CArray
1232
+ # Returns an array of data class members (fields)
1233
+ def fields
1234
+ end
1235
+ end
1236
+ */
1237
+
1238
+ VALUE
1239
+ rb_ca_fields (VALUE self)
1240
+ {
1241
+ VALUE data_class = rb_ca_data_class(self);
1242
+ volatile VALUE member_names, list;
1243
+ int i;
1244
+ if ( NIL_P(data_class) ) {
1245
+ rb_raise(rb_eRuntimeError, "carray doesn't have data class");
1246
+ }
1247
+ member_names = rb_const_get(data_class, rb_intern("MEMBERS"));
1248
+ list = rb_ary_new2(RARRAY_LEN(member_names));
1249
+ for (i=0; i<RARRAY_LEN(member_names); i++) {
1250
+ VALUE name = rb_ary_entry(member_names, i);
1251
+ rb_ary_store(list, i, rb_ca_field_as_member(self, name));
1252
+ }
1253
+ return list;
1254
+ }
1255
+
1256
+ /* rdoc:
1257
+ class CArray
1258
+ # Returns an array of data class members (fields) with names specified
1259
+ def fields_at (*names)
1260
+ end
1261
+ end
1262
+ */
1263
+
1264
+ VALUE
1265
+ rb_ca_fields_at (int argc, VALUE *argv, VALUE self)
1266
+ {
1267
+ VALUE data_class = rb_ca_data_class(self);
1268
+ volatile VALUE member_names, list;
1269
+ int i;
1270
+ if ( NIL_P(data_class) ) {
1271
+ rb_raise(rb_eRuntimeError, "carray doesn't have data class");
1272
+ }
1273
+ member_names = rb_ary_new4(argc, argv);
1274
+ list = rb_ary_new2(RARRAY_LEN(member_names));
1275
+ for (i=0; i<RARRAY_LEN(member_names); i++) {
1276
+ VALUE name = rb_ary_entry(member_names, i);
1277
+ rb_ary_store(list, i, rb_ca_field_as_member(self, name));
1278
+ }
1279
+ return list;
1280
+ }
1281
+
1282
+ /* ------------------------------------------------------------------- */
1283
+
1284
+ void
1285
+ Init_carray_core ()
1286
+ {
1287
+ id_decode = rb_intern("decode");
1288
+ id_encode = rb_intern("encode");
1289
+
1290
+ ca_init_obj_type();
1291
+
1292
+ rb_define_singleton_method(rb_cCArray, "attach", rb_ca_s_attach, -1);
1293
+ rb_define_singleton_method(rb_cCArray, "attach!", rb_ca_s_attach_bang, -1);
1294
+
1295
+ rb_define_method(rb_cCArray, "attach", rb_ca_attach, 0);
1296
+ rb_define_method(rb_cCArray, "attach!", rb_ca_attach_bang, 0);
1297
+
1298
+ rb_define_method(rb_cCArray, "__attach__", rb_ca__attach__, 0);
1299
+ rb_define_method(rb_cCArray, "__sync__", rb_ca__sync__, 0);
1300
+ rb_define_method(rb_cCArray, "__detach__", rb_ca__detach__, 0);
1301
+
1302
+ rb_define_method(rb_cCArray, "members", rb_ca_members, 0);
1303
+
1304
+ rb_define_method(rb_cCArray, "fields", rb_ca_fields, 0);
1305
+ rb_define_method(rb_cCArray, "fields_at", rb_ca_fields_at, -1);
1306
+ }
1307
+