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,213 @@
1
+ # ----------------------------------------------------------------------------
2
+ #
3
+ # carray/io/fortran_namelist.y
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
+ #
14
+ # racc fortran_namelist.y -> fortan_namelist.tab.rb
15
+ #
16
+
17
+ class FortranNamelistParser
18
+
19
+ prechigh
20
+ left COMMA
21
+ left ','
22
+ left '='
23
+ preclow
24
+
25
+ rule
26
+
27
+ namelist_all :
28
+ namelist
29
+ | namelist namelist_all
30
+
31
+ namelist :
32
+ header paramlist tailer
33
+ { @root[val[0]] = val[1]; @scan.in_namelist = false }
34
+
35
+ header :
36
+ '&' IDENT { result = val[1].downcase }
37
+ | '$' IDENT { result = val[1].downcase }
38
+
39
+ tailer :
40
+ '$'
41
+ | '&'
42
+ | '/'
43
+ | '&' IDENT { on_error unless val[1] =~ /\Aend\Z/i }
44
+ | '$' IDENT { on_error unless val[1] =~ /\Aend\Z/i }
45
+
46
+ paramlist:
47
+ paramdef { result = [val[0]] }
48
+ | paramlist paramdef
49
+ { result = val[0] + [val[1]] }
50
+ | paramlist COMMA paramdef
51
+ { result = val[0] + [val[2]] }
52
+ | paramlist COMMA
53
+ { result = val[0] }
54
+
55
+ paramdef:
56
+ IDENT '=' rvalues
57
+ { result = ParamDef.new(val[0].downcase.intern, nil, val[2]) }
58
+ | IDENT '(' array_spec ')' '=' rvalues
59
+ { result = ParamDef.new(val[0].downcase.intern, val[2], val[5]) }
60
+
61
+ rvalues :
62
+ abbreb { result = val[0] }
63
+ | rvalues abbreb
64
+ { result = val[0] + val[1] }
65
+ | rvalues NIL
66
+ { result = val[0] + [nil] }
67
+ | rvalues ',' abbreb
68
+ { result = val[0] + val[2] }
69
+ | IDENT
70
+ { result = val[0] }
71
+
72
+ abbreb :
73
+ constant { result = [val[0]] }
74
+ | DIGITS '*' constant
75
+ { result = [val[2]] * val[0] }
76
+
77
+ constant :
78
+ STRING
79
+ | DIGITS
80
+ | FLOAT
81
+
82
+ array_spec :
83
+ DIGITS { result = [val[0]-1] }
84
+ | DIGITS ':' DIGITS
85
+ { result = [(val[0]-1)..(val[2]-1)] }
86
+ | DIGITS ',' array_spec
87
+ { result = [val[0]-1] + val[2] }
88
+ | DIGITS ':' DIGITS ',' array_spec
89
+ { result = [(val[0]-1)..(val[2]-1)] + val[4] }
90
+
91
+ end
92
+
93
+ ---- inner
94
+
95
+ def parse (str)
96
+ @scan = FortranNamelistScanner.new(str)
97
+ @root = {}
98
+ do_parse
99
+ return @root
100
+ end
101
+
102
+ def next_token
103
+ return @scan.yylex
104
+ end
105
+
106
+ ---- header
107
+
108
+ require "strscan"
109
+ require "stringio"
110
+
111
+ class FortranNamelistScanner
112
+
113
+ def initialize (text)
114
+ @s = StringScanner.new(text)
115
+ @in_namelist = false
116
+ end
117
+
118
+ attr_accessor :in_namelist
119
+
120
+ def yylex
121
+ while @s.rest?
122
+ unless @in_namelist
123
+ case
124
+ when @s.scan(/\A([\$&])/) ### {$|&}
125
+ @in_namelist = true
126
+ return [
127
+ @s[0],
128
+ nil
129
+ ]
130
+ when @s.scan(/\A[^\$&]/)
131
+ next
132
+ end
133
+ else
134
+ case
135
+ when @s.scan(/\A[+-]?(\d+)\.(\d+)?([ED][+-]?(\d+))?/i) ### float
136
+ return [ ### 1.2E+3, 1.E+3, 1.2E3
137
+ :FLOAT, ### 1.2, 1.
138
+ @s[0].sub(/D/i,'e').sub(/\.e/,".0e").to_f
139
+ ]
140
+ when @s.scan(/\A[+-]?\.(\d+)([ED][+-]?(\d+))?/i) ### float
141
+ return [ ### .2E+3, -.2E+3, .2E3
142
+ :FLOAT, ### .2, -.2
143
+ @s[0].sub(/D/i,'e').sub(/\./, '0.').to_f
144
+ ]
145
+ when @s.scan(/\A[+-]?(\d+)[ED][+-]?(\d+)/i) ### float
146
+ return [ ### 12E+3, 12E3, 0E0
147
+ :FLOAT,
148
+ @s[0].sub(/D/i,'e').to_f
149
+ ]
150
+ when @s.scan(/\A[\-\+]?\d+/) ### digits
151
+ return [
152
+ :DIGITS,
153
+ Integer(@s[0])
154
+ ]
155
+ when @s.scan(/\A'((?:''|[^'])*)'/) ### 'quoted string'
156
+ return [
157
+ :STRING,
158
+ @s[1].gsub(/''/, "'")
159
+ ]
160
+ when @s.scan(/\A"((?:""|[^"])*)"/) ### 'double-quoted string'
161
+ return [
162
+ :STRING,
163
+ @s[1].gsub(/""/, '"')
164
+ ]
165
+ when @s.scan(/\A,/) ### ,
166
+ @s.scan(/\A\s+/)
167
+ while @s.scan(/\A\n\s*/) or @s.scan(/\A\![^\n]*/)
168
+ ### skip comment
169
+ end
170
+ if @s.match?(/\A[a-z]\w*/i) or @s.match?(/\A[\&\$\/\!]/)
171
+ return [
172
+ :COMMA,
173
+ nil
174
+ ]
175
+ elsif @s.match?(/\A,/)
176
+ return [
177
+ :NIL,
178
+ nil
179
+ ]
180
+ else
181
+ return [
182
+ ',',
183
+ nil
184
+ ]
185
+ end
186
+ when @s.scan(/\A[\$&\/=\(\):*]/) ### {$|&|/|,|=|(|)|:|*}
187
+ return [
188
+ @s[0],
189
+ nil
190
+ ]
191
+ when @s.scan(/\A[a-z]\w*/i) ### IDENT
192
+ return [
193
+ :IDENT,
194
+ @s[0]
195
+ ]
196
+ when @s.scan(/\A\s+/) ### blank
197
+ next
198
+ when @s.scan(/\A![^\n]*?\n/) ### comment
199
+ next
200
+ when @s.scan(/\A\n/) ### newline
201
+ next
202
+ else
203
+ @s.rest =~ /\A(.*)$/
204
+ raise "FortranFormat parse error\n\t#{$1}\n\t^"
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ ---- footer
213
+
@@ -0,0 +1,345 @@
1
+ # ----------------------------------------------------------------------------
2
+ #
3
+ # fortio/fortran_sequential.rb
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
+ #
14
+ # Format
15
+ #
16
+ # real*4 : native endian => "f", "F"
17
+ # little endian => "e"
18
+ # big endian => "g"
19
+ #
20
+ # real*8 : native endian => "d", "D"
21
+ # little endian => "E"
22
+ # big endian => "G"
23
+ #
24
+ # integer*2 : native endian => "s"
25
+ # little endian => "v"
26
+ # big endian => "n"
27
+ #
28
+ # integer*4 : native endian => "l"
29
+ # little endian => "V"
30
+ # big endian => "N"
31
+ #
32
+ # character : "a"
33
+ #
34
+
35
+ require "stringio"
36
+ require "carray"
37
+
38
+ class FortranSequential
39
+
40
+ if "ab".unpack("v").pack("s") == "ab"
41
+ ENDIAN = "little"
42
+ else
43
+ ENDIAN = "big"
44
+ end
45
+
46
+ FMT_VAX = {
47
+ "f" => "e", "F" => "e", "e" => "e", "g" => "g",
48
+ "d" => "E", "D" => "E", "E" => "E", "G" => "G",
49
+ "s" => "v", "v" => "v", "n" => "n",
50
+ "l" => "V", "V" => "V", "N" => "N",
51
+ "a" => "a"
52
+ }
53
+
54
+ FMT_NET = {
55
+ "f" => "g", "F" => "g", "e" => "e", "g" => "g",
56
+ "d" => "G", "D" => "G", "E" => "E", "G" => "G",
57
+ "s" => "n", "v" => "v", "n" => "n",
58
+ "l" => "N", "V" => "V", "N" => "N",
59
+ "a" => "a"
60
+ }
61
+
62
+ def self.open (file, mode="r", opt={:endian=>nil})
63
+ io = Kernel::open(file, mode)
64
+ if mode =~ /r/
65
+ fs = FortranSequentialReader.new(io, opt)
66
+ else
67
+ fs = FortranSequentialWriter.new(io, opt)
68
+ end
69
+ if block_given?
70
+ begin
71
+ yield(fs)
72
+ ensure
73
+ fs.close
74
+ end
75
+ else
76
+ return fs
77
+ end
78
+ end
79
+
80
+ def get_pack_fmt (endian)
81
+ case endian
82
+ when "big"
83
+ return FMT_NET
84
+ when "little"
85
+ return FMT_VAX
86
+ else
87
+ raise "unknown endian '#{endian}'"
88
+ end
89
+ end
90
+
91
+ class Record
92
+
93
+ def initialize (data="", endian="little", fmt=nil)
94
+ @io = StringIO.new(data)
95
+ @fmt = fmt
96
+ @endian = endian
97
+ end
98
+
99
+ def to_s
100
+ return @io.string
101
+ end
102
+
103
+ def empty?
104
+ return @io.eof?
105
+ end
106
+
107
+ def rest?
108
+ return (not @io.eof?)
109
+ end
110
+
111
+ def read (*fmts)
112
+ out = []
113
+ while not fmts.empty?
114
+ case fmt = fmts.shift
115
+ when String
116
+ list = []
117
+ specs = fmt.scan(/(?:\d+)(?:a\[\d+\]|\w)/)
118
+ while not specs.empty?
119
+ case specs.shift
120
+ when /(\d+)?a\[(\d+)\]/
121
+ ($1||1).to_i.times do
122
+ list.push(*@io.read($2.to_i).unpack("a#{$2}"))
123
+ end
124
+ when /(\d+)?a/
125
+ ($1||1).to_i.times do
126
+ list.push(*@io.read(1).unpack("a"))
127
+ end
128
+ when /(\d+)?([dDEG])/
129
+ ($1||1).to_i.times do
130
+ list.push(*@io.read(8).unpack(@fmt[$2]))
131
+ end
132
+ when /(\d+)?([lNVefFg])/
133
+ ($1||1).to_i.times do
134
+ list.push(*@io.read(4).unpack(@fmt[$2]))
135
+ end
136
+ when /(\d+)?([nsv])/
137
+ ($1||1).to_i.times do
138
+ list.push(*@io.read(2).unpack(@fmt[$2]))
139
+ end
140
+ else
141
+ raise "invalid format for FortranSequential::Record#read"
142
+ end
143
+ end
144
+ if list.size == 1
145
+ out.push(list.first)
146
+ else
147
+ out.push(list)
148
+ end
149
+ when Integer
150
+ n, tmpl = fmt, fmts.shift
151
+ n.times do
152
+ out.push(tmpl.template.load_binary(@io))
153
+ end
154
+ when CArray
155
+ tmpl = fmt
156
+ if ENDIAN == @endian
157
+ out.push(tmpl.template.load_binary(@io))
158
+ else
159
+ out.push(tmpl.template.load_binary(@io).swap_bytes!)
160
+ end
161
+ when CA::Struct
162
+ if ENDIAN == @endian
163
+ out.push(CScalar.new(fmt.class).load_binary(@io)[0])
164
+ else
165
+ out.push(CScalar.new(fmt.class).load_binary(@io).swap_bytes![0])
166
+ end
167
+ when Class
168
+ if fmt < CA::Struct
169
+ if ENDIAN == @endian
170
+ out.push(CScalar.new(fmt).load_binary(@io)[0])
171
+ else
172
+ out.push(CScalar.new(fmt).load_binary(@io).swap_bytes![0])
173
+ end
174
+ else
175
+ raise "invlaid argument (format string or CArray)"
176
+ end
177
+ else
178
+ raise "invlaid argument (format string or CArray)"
179
+ end
180
+ end
181
+ if out.size == 1
182
+ return out.first
183
+ else
184
+ return out
185
+ end
186
+ end
187
+
188
+ def write (*fmts)
189
+ while fmt = fmts.shift
190
+ if fmt.is_a?(String)
191
+ argv = fmts.shift
192
+ unless argv.is_a?(Array)
193
+ raise "argv should be array"
194
+ end
195
+ argv = argv.clone
196
+ end
197
+ case fmt
198
+ when String
199
+ specs = fmt.scan(/(?:\d+)(?:a\[\d+\]|\w)/)
200
+ while not specs.empty?
201
+ case specs.shift
202
+ when /(\d+)?a\[(\d+)\]/
203
+ ($1||1).to_i.times do
204
+ @io.write [argv.shift].pack("a#{$2}")
205
+ end
206
+ when /(\d+)?([adDEGefFglNVnsv])/
207
+ ($1||1).to_i.times do
208
+ @io.write [argv.shift].pack(@fmt[$2])
209
+ end
210
+ else
211
+ raise "invalid format for FortranSequential::Record#write"
212
+ end
213
+ end
214
+ when CArray
215
+ if ENDIAN == @endian
216
+ fmt.dump_binary(@io)
217
+ else
218
+ fmt.swap_bytes.dump_binary(@io)
219
+ end
220
+ when CA::Struct
221
+ if RUBY_VERSION.to_f >= 1.9
222
+ if ENDIAN == @endian
223
+ @io.write fmt.encode.force_encoding("ASCII-8BIT")
224
+ else
225
+ @io.write fmt.swap_bytes.encode.force_encoding("ASCII-8BIT")
226
+ end
227
+ else
228
+ if ENDIAN == @endian
229
+ @io.write fmt.encode
230
+ else
231
+ @io.write fmt.swap_bytes.encode
232
+ end
233
+ end
234
+ else
235
+ raise "invlaid argument (format string or CArray)"
236
+ end
237
+ end
238
+ end
239
+
240
+ end
241
+
242
+ def eof?
243
+ return @io.eof?
244
+ end
245
+
246
+ end
247
+
248
+ class FortranSequentialReader < FortranSequential
249
+
250
+ def initialize (io, opt={:endian=>nil})
251
+ @io = io
252
+ @endian = opt[:endian] || ENDIAN
253
+ @fmt = get_pack_fmt(@endian)
254
+ end
255
+
256
+ def record (n=nil)
257
+ if n
258
+ @io.rewind
259
+ skip(n)
260
+ end
261
+ data = read
262
+ if data
263
+ rec = FortranSequential::Record.new(data, @endian, @fmt)
264
+ if block_given?
265
+ return yield(rec)
266
+ else
267
+ return rec
268
+ end
269
+ else
270
+ return nil
271
+ end
272
+ end
273
+
274
+ def skip (n=1)
275
+ n.times do
276
+ unless @io.eof?
277
+ length = @io.read(4).unpack(@fmt["l"]).first
278
+ @io.pos += length
279
+ if length != @io.read(4).unpack(@fmt["l"]).first
280
+ raise "invalid record length (should be #{length})"
281
+ end
282
+ end
283
+ end
284
+ end
285
+
286
+ def read (*dummy)
287
+ if @io.eof?
288
+ return nil
289
+ else
290
+ length = @io.read(4).unpack(@fmt["l"]).first
291
+ data = @io.read(length)
292
+ if data.length != length
293
+ raise "record too short (record length should be #{length})"
294
+ end
295
+ if length != @io.read(4).unpack(@fmt["l"]).first
296
+ raise "mismatched record length (should be #{length})"
297
+ end
298
+ return data
299
+ end
300
+ end
301
+
302
+ def close
303
+ @io.close
304
+ end
305
+
306
+ end
307
+
308
+ class FortranSequentialWriter < FortranSequential
309
+
310
+ def initialize (io, opt={:endian=>nil})
311
+ @io = io
312
+ @endian = opt[:endian] || ENDIAN
313
+ @fmt = get_pack_fmt(@endian)
314
+ end
315
+
316
+ def record
317
+ rec = FortranSequential::Record.new("", @endian, @fmt)
318
+ if block_given?
319
+ return yield(rec)
320
+ else
321
+ return rec
322
+ end
323
+ end
324
+
325
+ def write (data)
326
+ if data.respond_to?(:to_s)
327
+ data = data.to_s
328
+ end
329
+ if RUBY_VERSION.to_f >= 1.9
330
+ data = data.force_encoding("ASCII-8BIT")
331
+ end
332
+ @io.write [data.length].pack(@fmt["l"])
333
+ @io.write data
334
+ @io.write [data.length].pack(@fmt["l"])
335
+ end
336
+
337
+ def close
338
+ @io.close
339
+ end
340
+
341
+ end
342
+
343
+ def fortran_sequential_open (file, mode="r", opt={:endian=>nil}, &block)
344
+ return FortranSequential.open(file, mode, opt, &block)
345
+ end