carray 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -7
  3. data/Rakefile +31 -0
  4. data/carray.gemspec +9 -14
  5. data/carray.h +4 -0
  6. data/carray_access.c +50 -8
  7. data/carray_conversion.c +3 -3
  8. data/carray_generate.c +67 -1
  9. data/carray_math.rb +22 -22
  10. data/carray_operator.c +23 -0
  11. data/devel/im2col.rb +17 -0
  12. data/ext/calculus/carray_calculus.c +235 -95
  13. data/ext/calculus/carray_interp.c +3 -1
  14. data/ext/calculus/lib/math/calculus.rb +4 -4
  15. data/lib/carray.rb +32 -1
  16. data/lib/carray/autoload/autoload_base.rb +0 -4
  17. data/lib/carray/autoload/autoload_gem_cairo.rb +9 -0
  18. data/lib/carray/autoload/autoload_gem_ffi.rb +9 -0
  19. data/lib/carray/autoload/autoload_gem_gnuplot.rb +2 -0
  20. data/lib/carray/autoload/autoload_gem_io_csv.rb +14 -0
  21. data/lib/carray/autoload/autoload_gem_io_pg.rb +6 -0
  22. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +12 -0
  23. data/lib/carray/autoload/autoload_gem_narray.rb +10 -0
  24. data/lib/carray/autoload/autoload_gem_numo_narray.rb +14 -0
  25. data/lib/carray/autoload/autoload_gem_opencv.rb +16 -0
  26. data/lib/carray/autoload/autoload_gem_rmagick.rb +23 -0
  27. data/lib/carray/autoload/{autoload_graphics_zimg.rb → autoload_gem_zimg.rb} +0 -0
  28. data/lib/carray/base/autoload.rb +47 -5
  29. data/lib/carray/base/basic.rb +70 -6
  30. data/lib/carray/base/math.rb +1 -1
  31. data/lib/carray/base/string.rb +242 -0
  32. data/lib/carray/base/struct.rb +4 -4
  33. data/lib/carray/io/table.rb +1 -0
  34. data/mkmath.rb +12 -2
  35. data/version.h +5 -5
  36. metadata +48 -141
  37. data/Gemfile +0 -8
  38. data/Gemfile.lock +0 -33
  39. data/ext/calculus/lib/autoload/autoload_math_calculus.rb +0 -2
  40. data/ext/fortio/extconf.rb +0 -3
  41. data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +0 -5
  42. data/ext/fortio/lib/carray/io/fortran_format.rb +0 -43
  43. data/ext/fortio/lib/fortio.rb +0 -3
  44. data/ext/fortio/lib/fortio/fortran_format.rb +0 -605
  45. data/ext/fortio/lib/fortio/fortran_format.tab.rb +0 -536
  46. data/ext/fortio/lib/fortio/fortran_format.y +0 -215
  47. data/ext/fortio/lib/fortio/fortran_namelist.rb +0 -151
  48. data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +0 -470
  49. data/ext/fortio/lib/fortio/fortran_namelist.y +0 -213
  50. data/ext/fortio/lib/fortio/fortran_sequential.rb +0 -345
  51. data/ext/fortio/ruby_fortio.c +0 -182
  52. data/ext/fortio/test/test_H.rb +0 -5
  53. data/ext/fortio/test/test_T.rb +0 -7
  54. data/ext/fortio/test/test_fortran_format.rb +0 -86
  55. data/ext/fortio/test/test_namelist.rb +0 -25
  56. data/ext/fortio/test/test_namelist_write.rb +0 -10
  57. data/ext/fortio/test/test_sequential.rb +0 -13
  58. data/ext/fortio/test/test_sequential2.rb +0 -13
  59. data/ext/fortio/work/test.rb +0 -10
  60. data/ext/fortio/work/test_e.rb +0 -19
  61. data/ext/fortio/work/test_ep.rb +0 -10
  62. data/ext/fortio/work/test_parse.rb +0 -12
  63. data/ext/imagemap/carray_imagemap.c +0 -495
  64. data/ext/imagemap/doc/call_graph.dot +0 -28
  65. data/ext/imagemap/draw.c +0 -567
  66. data/ext/imagemap/extconf.rb +0 -13
  67. data/ext/imagemap/lib/autoload/autoload_graphics_imagemap.rb +0 -1
  68. data/ext/imagemap/lib/graphics/imagemap.rb +0 -273
  69. data/ext/imagemap/lib/image_map.rb +0 -4
  70. data/ext/imagemap/test/swath_index.rb +0 -83
  71. data/ext/imagemap/test/swath_warp.rb +0 -99
  72. data/ext/imagemap/test/test.rb +0 -23
  73. data/ext/imagemap/test/test_image.rb +0 -42
  74. data/ext/imagemap/test/test_line.rb +0 -14
  75. data/ext/imagemap/test/test_rotate.rb +0 -17
  76. data/ext/imagemap/test/test_triangle.rb +0 -20
  77. data/ext/imagemap/test/test_warp.rb +0 -26
  78. data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +0 -1
  79. data/ext/mathfunc/lib/math/mathfunc.rb +0 -15
  80. data/ext/narray/README +0 -22
  81. data/ext/narray/ca_wrap_narray.c +0 -500
  82. data/ext/narray/carray_narray.c +0 -21
  83. data/ext/narray/extconf.rb +0 -57
  84. data/ext/narray/lib/autoload/autoload_math_narray.rb +0 -1
  85. data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +0 -11
  86. data/ext/narray/lib/math/narray.rb +0 -17
  87. data/ext/narray/lib/math/narray_miss.rb +0 -45
  88. data/lib/carray/autoload/autoload_graphics_gnuplot.rb +0 -2
  89. data/lib/carray/autoload/autoload_io_csv.rb +0 -14
  90. data/lib/carray/autoload/autoload_io_pg.rb +0 -6
  91. data/lib/carray/autoload/autoload_io_sqlite3.rb +0 -12
  92. data/lib/carray/graphics/gnuplot.rb +0 -2131
  93. data/lib/carray/graphics/zimg.rb +0 -296
  94. data/lib/carray/io/csv.rb +0 -572
  95. data/lib/carray/io/pg.rb +0 -101
  96. data/lib/carray/io/sqlite3.rb +0 -215
  97. data/mkmf.log +0 -18
@@ -1,296 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/graphics/zimg.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
- =begin
15
-
16
- option
17
-
18
- :debug => (true|false)
19
- :output => filename
20
- :complex => (abs|length|phase|real|imaginary)
21
- :colormap => (red|blue|gray) | "filename" | [r,g,b]
22
- :invert => (true|false)
23
- :crange => [min,max]
24
- :nda_color => color
25
- :scale => [x[,y]]
26
- :align => [h,[,v,bcol]]
27
- :quality => quality
28
- :interlace => (true|false)
29
- :colorbox => (true|false)
30
- :cbox_tics => n
31
- :cbox_label => string
32
- :cbox_format => string
33
- :display => (true|false) | "program"
34
- :legend => string
35
- :label => [[x1,y1,s1], [x2,y2,s2], ...]
36
- :vlabel => [[x1,y1,s1], [x2,y2,s2], ...]
37
- :textfont => n
38
- :textcolor => "xxx"|"xxxxxx"
39
- :smooth => threshold
40
- :contors => [levels,"log",bg,fg] ### Not Implemented
41
-
42
- =end
43
-
44
- class CArray
45
-
46
- @@zimg_count = 0
47
-
48
- def zimg (option={}) # :nodoc:
49
-
50
- tempfile = "%zimg_#{$$}_#{@@zimg_count}.dat"
51
- @@zimg_count += 1
52
-
53
- if self.rank != 2
54
- raise "zimg accept only 2-D data"
55
- end
56
-
57
- option.each do |k, v|
58
- if k.kind_of?(String)
59
- option[k.intern] = v
60
- end
61
- end
62
-
63
- if option[:output]
64
- output = option[:output]
65
- case output
66
- when /.ppm$/
67
- outfmt = "--ppm"
68
- when /.pgm$/
69
- outfmt = "--pgm"
70
- when /.jpg$/i, /.jpeg$/i
71
- if option[:quality]
72
- outfmt = "--jpeg=" + option[:quality].to_s
73
- else
74
- outfmt = "--jpeg"
75
- end
76
- else
77
- outfmt = ""
78
- end
79
- else
80
- output = "-"
81
- outfmt = ""
82
- end
83
-
84
- if option[:interlace]
85
- interlace = "--interlace"
86
- else
87
- interlace = ""
88
- end
89
-
90
- case self.data_type
91
- when CA_UINT8
92
- type_spec = "--unsigned-char"
93
- when CA_INT8, CA_BOOLEAN
94
- type_spec = "--char"
95
- when CA_UINT16
96
- type_spec = "--unsigned-short"
97
- when CA_INT16
98
- type_spec = "--short"
99
- when CA_UINT32
100
- type_spec = "--unsigned-int"
101
- when CA_INT32
102
- type_spec = "--int"
103
- when CA_FLOAT32
104
- type_spec = "--float"
105
- when CA_FLOAT64
106
- type_spec = "--double"
107
- when CA_CMPLX64
108
- type_spec = "--complex-float=" + ( option[:complex] || "abs" )
109
- when CA_CMPLX128
110
- type_spec = "--complex-double=" + ( option[:complex] || "abs" )
111
- else
112
- raise "can't create image for invalid numerical data"
113
- end
114
-
115
- case option[:colormap]
116
- when "red", "blue", "gray"
117
- colormap = "--" + option[:colormap]
118
- when String
119
- if File.exist?(option[:colormap])
120
- colormap = "--colormap=" + option[:colormap]
121
- else
122
- raise "can't find colomap file"
123
- end
124
- when Array
125
- colormap = "--colormap=" + option[:colormap].join(",")
126
- else
127
- colormap = ""
128
- end
129
-
130
- if option[:crange]
131
- crange = "--crange=" + option[:crange].join(',')
132
- else
133
- crange = ''
134
- end
135
-
136
- if option[:nda_color]
137
- if option[:fill_value]
138
- nda = "--nda=" + [option[:fill_value], option[:nda_color]].join(',')
139
- else
140
- nda = "--nda=" + ["Infinity", option[:nda_color]].join(',')
141
- end
142
- else
143
- nda = ""
144
- end
145
-
146
- if option[:scale]
147
- scale = "--scale=" + option[:scale].join(',')
148
- else
149
- scale = ''
150
- end
151
-
152
- if option[:align]
153
- if option[:align].last.kind_of?(String)
154
- align = "--align=" + option[:align][0..-2].join('x')
155
- "," + option[:align].last
156
- else
157
- align = "--align=" + option[:align].join('x')
158
- end
159
- else
160
- align = ''
161
- end
162
-
163
- if option[:colorbox]
164
- if option[:cbox_tics]
165
- colorbox = "--colorbox=" + option[:cbox_tics].to_s
166
- else
167
- colorbox = "--colorbox"
168
- end
169
- else
170
- colorbox = ""
171
- end
172
-
173
- if option[:cbox_format]
174
- cbox_format = option[:cbox_format]
175
- else
176
- cbox_format = ""
177
- end
178
-
179
- if option[:cbox_label]
180
- cbox_label = option[:cbox_label]
181
- else
182
- cbox_label = ""
183
- end
184
-
185
- geom = lambda{|x,y|
186
- [ (x > 0 ? "+" : '') + x.to_s, (y > 0 ? '+' :'') + y.to_s].join
187
- }
188
-
189
- label = ""
190
- if option[:label]
191
- option[:label].each do |x, y, s|
192
- label << "--label=" + [geom[x, y],s].join(',') + " "
193
- end
194
- end
195
-
196
- vlabel = ""
197
- if option[:vlabel]
198
- option[:vlabel].each do |x, y, s|
199
- vlabel << "--vlabel=" + [geom[x, y],s].join(',') + " "
200
- end
201
- end
202
-
203
- if option[:textfont]
204
- textfont = "--font=" + option[:textfont].to_s
205
- else
206
- textfont = ""
207
- end
208
-
209
- if option[:textcolor]
210
- textcolor = "--textcolor=" + option[:textcolor].to_s
211
- else
212
- textcolor = ""
213
- end
214
-
215
- case option[:smooth]
216
- when Numeric
217
- smooth = "--smooth=" + option[:smooth].to_s
218
- else
219
- if option[:smooth]
220
- smooth = "--smooth"
221
- else
222
- smooth = ""
223
- end
224
- end
225
-
226
- command = [
227
- "zimg",
228
- "--output=#{output}",
229
- outfmt,
230
- interlace,
231
- type_spec,
232
- "--size=" + self.dim.reverse.join(","),
233
- scale,
234
- align,
235
- colormap,
236
- option[:invert] ? "--invert" : "",
237
- crange,
238
- nda,
239
- colorbox,
240
- cbox_label,
241
- cbox_format,
242
- label,
243
- vlabel,
244
- textfont,
245
- textcolor,
246
- smooth,
247
- tempfile
248
- ].join(" ")
249
-
250
- if option[:nda_color] and self.has_mask?
251
- if option[:fill_value]
252
- out = self.unmask(option[:fill_value])
253
- else
254
- out = self.unmask(nan)
255
- end
256
- else
257
- out = self
258
- end
259
-
260
- open(tempfile, "w"){ |io|
261
- out.dump_binary(io)
262
- }
263
-
264
- if option[:debug]
265
- puts command
266
- end
267
-
268
- if option[:output]
269
- system(command)
270
- case option[:display]
271
- when String
272
- system([option[:display], output].join(" "))
273
- else
274
- if option[:display]
275
- system(["display", output].join(" "))
276
- end
277
- end
278
- else
279
- case option[:display]
280
- when String
281
- system(command + ["|", option[:display], "-"].join(" "))
282
- else
283
- if option[:display]
284
- system(command + ["|", "display -"].join(" "))
285
- end
286
- end
287
- end
288
-
289
- ensure
290
- if File.exist?(tempfile)
291
- File.unlink(tempfile)
292
- end
293
- end
294
-
295
- end
296
-
@@ -1,572 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/io/csv.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
- # CSV data reader/writer for CArray (in DSL approach)
14
- #
15
- # For reading (explicit form)
16
- #
17
- # csv = CA::CSVReader.new {
18
- # header # read a line as "names" header
19
- # header :units # read a line as "units" header
20
- # skip 1 # skip a line
21
- # body 10 # read values
22
- # process { |name, column| # post processing
23
- # case name # name : name of columns (string|integer)
24
- # when "Date" # column : column carray
25
- # column.map!{|x| Date.parse(x) }
26
- # else
27
- # column[] = column.double
28
- # end
29
- # }
30
- # }
31
- #
32
- # data1 = csv.read_file(file1)
33
- # data2 = csv.read_file(file2)
34
- # data3 = csv.read_file(file3)
35
- #
36
- # For reading (implicit form)
37
- #
38
- # data = CArray.load_csv(file) { ... definitions ... }
39
- # data = CArray.from_csv(io|string) { ... definitions ... }
40
- #
41
- # For writing (explict form)
42
- #
43
- # csv = CA::CSVWriter.new {
44
- # names ["Date", "a", "b", "c"] # set name of columns
45
- # process { |name, column| # pre processing
46
- # case name # name : name of column
47
- # when "Date" # column : column carray
48
- # column.map!{|x| x.to_s }
49
- # else
50
- # column.map!{|x| "%.2f" % x }
51
- # end
52
- # }
53
- # puts "sample CSV data" # print any string
54
- # header # write names in header
55
- # header ["","mm","cm","m"] # write units in header
56
- # write # write values
57
- # }
58
- #
59
- # data1.write_file(file1)
60
- # data2.write_file(file2)
61
- # data3.write_file(file3)
62
- #
63
- # For writing (implicit form)
64
- #
65
- # data.save_csv(file) { ... definitions ... }
66
- # data.to_csv([io|string]) { ... definitions ... }
67
- #
68
-
69
- require "stringio"
70
- require "strscan"
71
- require "carray/io/table"
72
-
73
- module CA
74
-
75
- class CSVReader # :nodoc:
76
-
77
- def initialize (sep=",", rs=$/, &block)
78
- @block = block
79
- @sep = sep
80
- @rs = rs
81
- end
82
-
83
- def read_io (io)
84
- return Processor.new(io, @sep, @rs, &@block).run
85
- end
86
-
87
- def read_string (string)
88
- return read_io(StringIO.new(string))
89
- end
90
-
91
- def read_file (filename)
92
- open(filename) { |io|
93
- return read_io(io)
94
- }
95
- end
96
-
97
- class Processor # :nodoc:
98
-
99
- def initialize (io, sep, rs=$/, &block)
100
- @io = io
101
- @sep = sep
102
- @rs = rs
103
- @sc = StringScanner.new("")
104
- @block = block || proc { body }
105
- @namelist = nil
106
- @names = nil
107
- @headerlist = []
108
- @header = {}
109
- @note = ""
110
- @table = nil
111
- @regexp_simple1 = /#{@sep}/
112
- @regexp_simple2 = / *#{@sep} */
113
- @regexp_pat1 = /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
114
- @regexp_pat2 = /\A"([^"]+)" *#{@sep} */
115
- @regexp_pat3 = /\A"((?:[^"]+|"")+)" *#{@sep} */
116
- @regexp_pat4 = /\A(?:""|) *#{@sep} */
117
- end
118
-
119
- def run
120
- case @block.arity
121
- when 1
122
- @block.call(self)
123
- when -1, 0
124
- instance_exec(&@block)
125
- else
126
- raise "invalid block paramter"
127
- end
128
- header = @header
129
- note = @note
130
- @table.instance_exec{
131
- @names = header["names"]
132
- @header = header
133
- @note = note
134
- }
135
- @table.extend(CA::TableMethods)
136
- @table.column_names = header["names"]
137
- class << @table
138
- attr_reader :note
139
- def header (name=nil)
140
- if name
141
- return @header[name.to_s]
142
- else
143
- return @header
144
- end
145
- end
146
- end
147
- return @table
148
- end
149
-
150
- def column_names (*namelist)
151
- if @header.has_key?("names")
152
- warn "override header['names']"
153
- end
154
- @names = namelist.map(&:to_s)
155
- @header["names"] = @names
156
- return namelist
157
- end
158
-
159
- def header (name = "names")
160
- name = name.to_s
161
- list = csv_feed()
162
- if name == "names"
163
- if @names
164
- raise "already 'names' defined"
165
- end
166
- @names = list
167
- end
168
- @header[name] = list
169
- @headerlist.push(name)
170
- return list
171
- end
172
-
173
- attr_reader :names
174
-
175
- def note (n=1)
176
- list = []
177
- n.times { list << @io.gets(@rs) }
178
- @note << (text = list.join)
179
- return text
180
- end
181
-
182
- def skip (n=1)
183
- n.times { @io.gets(@rs) }
184
- end
185
-
186
- def body (n=nil, cols=nil)
187
- unless n
188
- n = 0x80000000
189
- end
190
- data = []
191
- count = 0
192
-
193
- if cols
194
- @cols = cols
195
- elsif @names
196
- @cols = @names.size
197
- else
198
- list = csv_feed()
199
- if list.nil?
200
- @rows = 0
201
- @table = CArray.object(@rows, @cols)
202
- return
203
- end
204
- data.push(list)
205
- count += 1
206
- @cols = list.size
207
- end
208
-
209
- lsize = nil
210
- while count < n and list = csv_feed(@cols)
211
- lsize = list.size
212
- if lsize == @cols
213
- data.push(list)
214
- elsif lsize <= @cols
215
- record = Array.new(@cols, nil)
216
- record[0,lsize] = list
217
- data.push(record)
218
- else
219
- extra = Array.new(lsize - @cols, nil)
220
- data.each do |row|
221
- row.push(*extra)
222
- end
223
- data.push(list)
224
- @cols = lsize
225
- # raise "csv parse error : too large column number at line #{@io.lineno}"
226
- end
227
- count += 1
228
- end
229
-
230
- @rows = data.size
231
- @table = CArray.object(@rows, @cols){ data }
232
- @table[:eq,""] = nil
233
- end
234
-
235
- def select (*namelist)
236
- @namelist = namelist.empty? ? nil : namelist
237
- case @namelist
238
- when nil
239
- when Array
240
- index = (0...@cols).map.to_a
241
- index_list = @namelist.map{ |x|
242
- case x
243
- when Integer
244
- x
245
- when Range
246
- index[x]
247
- when String, Symbol
248
- if @names and i = @names.index(x.to_s)
249
- i
250
- else
251
- raise "invalid argument #{x}"
252
- end
253
- else
254
- raise "invalid argument"
255
- end
256
- }.flatten
257
- @table = @table[nil, CA_INT(index_list)].to_ca
258
- @header.keys.each do |k|
259
- @header[k] = @header[k].values_at(*index_list)
260
- end
261
- else
262
- raise
263
- end
264
- end
265
-
266
- def process
267
- if @namelist
268
- @namelist.each_with_index do |name, i|
269
- yield(name, @table[nil, i])
270
- end
271
- elsif @names
272
- @names.each_with_index do |name, i|
273
- yield(name, @table[nil, i])
274
- end
275
- else
276
- @table.dim1.times do |i|
277
- yield(i, @table[nil,i])
278
- end
279
- end
280
- end
281
-
282
- def convert (data_type, options={}, &block)
283
- if block_given?
284
- if data_type.is_a?(Class) and data_type < CA::Struct
285
- @table = @table[:i, nil].convert(data_type, &block)
286
- else
287
- @table = @table.convert(data_type, options, &block)
288
- end
289
- else
290
- if data_type.is_a?(Class) and data_type < CA::Struct
291
- @table = @table[:i,nil].convert(data_type) { |b|
292
- data_type.new(*b[0,nil])
293
- }
294
- else
295
- @table = @table.to_type(data_type, options)
296
- end
297
- end
298
- end
299
-
300
- private
301
-
302
- def csv_feed (cols=nil)
303
- if @io.eof?
304
- return nil
305
- end
306
- line = nil
307
- loop do
308
- if newline = @io.gets(@rs)
309
- if line
310
- line << newline
311
- else
312
- line = newline
313
- end
314
- count_quote = line.count('"')
315
- else
316
- line = ""
317
- count_quote = 0
318
- end
319
- if count_quote == 0
320
- line.chomp!
321
- if line.count(' ') == 0
322
- return line.split(@sep, -1) ### /#{@sep}/
323
- else
324
- return line.split(@regexp_simple2, -1) ### / *#{@sep} */
325
- end
326
- end
327
- if count_quote % 2 == 0
328
- line.chomp!
329
- return csv_split(line, cols)
330
- else
331
- if newline
332
- next
333
- else
334
- raise "csv parse error"
335
- end
336
- end
337
- end
338
- end
339
-
340
- def csv_split (text, cols=nil)
341
- if cols
342
- csv = Array.new(cols)
343
- else
344
- csv = []
345
- end
346
- text << @sep
347
- @sc.string = text
348
- i = 0
349
- begin
350
- case
351
- when @sc.scan(@regexp_pat1)
352
- ### /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
353
- csv[i] = @sc[1]
354
- when @sc.scan(@regexp_pat2)
355
- ### /\A"([^"]+)" *#{@sep} */
356
- csv[i] = @sc[1]
357
- when @sc.scan(@regexp_pat3)
358
- ### /\A"((?:[^"]+|"")+)" *#{@sep} */
359
- s = @sc[1]
360
- if s =~ /"/
361
- csv[i] = s.gsub(/""/, '"')
362
- else
363
- csv[i] = s
364
- end
365
- when @sc.scan(@regexp_pat4)
366
- ### /\A(?:""|) *#{@sep} */
367
- csv[i] = nil
368
- else
369
- raise "csv parse error"
370
- end
371
- i += 1
372
- end until @sc.eos?
373
- return csv
374
- end
375
-
376
- end
377
- end
378
- end
379
-
380
- module CA
381
-
382
- class CSVWriter # :nodoc:
383
-
384
- def initialize (sep=",", rs=$/, fill="", &block)
385
- @block = block
386
- @sep = sep
387
- @rs = rs
388
- @fill = fill
389
- end
390
-
391
- def write_io (table, io)
392
- return Processor.new(table, io, @sep, @rs, @fill, &@block).run
393
- end
394
-
395
- def write_string (table, string)
396
- write_io(table, StringIO.new(string))
397
- return string
398
- end
399
-
400
- def write_file (table, filename, mode="w")
401
- open(filename, mode) { |io|
402
- return write_io(table, io)
403
- }
404
- end
405
-
406
- class Processor # :nodoc:
407
-
408
- def initialize (table, io, sep, rs, fill, &block)
409
- @io = io
410
- @sep = sep
411
- @rs = rs
412
- @fill = fill
413
- @block = block || proc { body }
414
- if table.has_data_class?
415
- @names = table.members
416
- @table = CArray.merge(CA_OBJECT, table[nil].fields)
417
- else
418
- @names = table.instance_exec{ @names }
419
- if @names.nil?
420
- @names = table.instance_exec{ @column_names }
421
- end
422
- case
423
- when table.rank > 2
424
- @table = table.reshape(false,nil).object
425
- when table.rank == 1
426
- @table = table[:%,1].object ### convert to CA_OBJECT
427
- else
428
- @table = table.object ### convert to CA_OBJECT
429
- end
430
- end
431
- if @table.has_mask?
432
- @table.unmask(@fill)
433
- end
434
- @regexp_simple = /#{@sep}/o
435
- end
436
-
437
- def csv_quote (text)
438
- text = text.dup
439
- if text.gsub!(/"/, '""') or text =~ @regexp_simple ### /#{@sep}|"/
440
- text = '"' + text + '"'
441
- end
442
- return text
443
- end
444
-
445
- def run
446
- case @block.arity
447
- when 1
448
- @block.call(self)
449
- when -1, 0
450
- instance_exec(&@block)
451
- else
452
- raise "invalid block parameter"
453
- end
454
- end
455
-
456
- # set @names
457
- def names (list)
458
- @names = list
459
- end
460
-
461
- # puts header
462
- def header (list = @names)
463
- @io.write list.map{|s| csv_quote(s)}.join(@sep)
464
- @io.write(@rs)
465
- end
466
-
467
- # puts any strings
468
- def puts (*argv)
469
- @io.print(*argv)
470
- @io.write(@rs)
471
- end
472
-
473
- # write value
474
- # If option :strict is set, do csv_quote for string element
475
- def body (strict: true, format: nil)
476
- if strict
477
- case @table.data_type
478
- when CA_OBJECT
479
- table = @table.to_ca
480
- table[:is_kind_of, String].map! { |s| csv_quote(s) }
481
- when CA_FIXLEN
482
- table = @table.object
483
- table.map! { |s| csv_quote(s) }
484
- else
485
- table = @table.object
486
- end
487
- else
488
- table = @table
489
- end
490
- if format
491
- table.dim0.times do |i|
492
- @io.write Kernel::format(format,*table[i,nil].to_a)
493
- @io.write(@rs)
494
- end
495
- else
496
- table.dim0.times do |i|
497
- @io.write table[i,nil].to_a.join(@sep)
498
- @io.write(@rs)
499
- end
500
- end
501
- end
502
-
503
- # pre processing data
504
- def process (namelist = @names)
505
- if namelist
506
- namelist.each_with_index do |name, i|
507
- yield(name, @table[nil, i])
508
- end
509
- else
510
- @table.dim1.times do |i|
511
- yield(i, @table[nil,i])
512
- end
513
- end
514
- end
515
- end
516
- end
517
- end
518
-
519
- class CArray
520
-
521
- def self.load_csv (file, option={}, rs: $/, sep: ",", &block)
522
- option = {:sep=>sep, :rs=>rs}.update(option)
523
- reader = CA::CSVReader.new(option[:sep], option[:rs], &block)
524
- return reader.read_file(file)
525
- end
526
-
527
- def self.from_csv (io, option={}, rs: $/, sep: ",", &block)
528
- option = {:sep=>sep, :rs=>rs}.update(option)
529
- reader = CA::CSVReader.new(option[:sep], option[:rs], &block)
530
- case io
531
- when IO, StringIO
532
- return reader.read_io(io)
533
- when String
534
- return reader.read_string(io)
535
- else
536
- raise "invalid argument"
537
- end
538
- end
539
-
540
- def save_csv (file, option = {}, rs: $/, sep: ",", fill: "", mode: "w", &block)
541
- option = {:sep=>sep, :rs=>rs, :fill=>fill, :mode=>mode}.update(option)
542
- writer = CA::CSVWriter.new(option[:sep], option[:rs], option[:fill], &block)
543
- return writer.write_file(self, file, option[:mode])
544
- end
545
-
546
- def to_csv (io="", option ={}, rs: $/, sep: ",", fill: "", &block)
547
- option = {:sep=>sep, :rs=>rs, :fill=>fill}.update(option)
548
- writer = CA::CSVWriter.new(option[:sep], option[:rs], option[:fill], &block)
549
- case io
550
- when IO, StringIO
551
- return writer.write_io(self, io)
552
- when String
553
- return writer.write_string(self, io)
554
- end
555
- end
556
-
557
- def to_tabular (option = {})
558
- option = {:sep=>" ", :names=>nil}.update(option)
559
- if option[:names]
560
- names = option[:names]
561
- elsif self.respond_to?(:names)
562
- names = self.names
563
- end
564
- sep = option[:sep]
565
- data = self.to_ca.map! {|s| s.to_s }
566
- table = CArray.join([names.to_ca], [data])
567
- length = table.convert{|s| s.length}.max(0)
568
- table.map_with_index! {|s, idx| s.rjust(length[idx[1]]) }.to_csv.gsub(/,/,sep)
569
- end
570
-
571
- end
572
-