mdarray-jcsv 0.6.3-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +23 -0
- data/README.md +2 -0
- data/Rakefile +46 -0
- data/config.rb +104 -0
- data/lib/constraints.rb +205 -0
- data/lib/date_filters.rb +252 -0
- data/lib/dimensions.rb +276 -0
- data/lib/filters.rb +332 -0
- data/lib/jcsv.rb +107 -0
- data/lib/list_reader.rb +200 -0
- data/lib/locale.rb +192 -0
- data/lib/map_reader.rb +192 -0
- data/lib/mdarray-jcsv.rb +24 -0
- data/lib/mdarray_reader.rb +110 -0
- data/lib/numeric_filters.rb +225 -0
- data/lib/reader.rb +547 -0
- data/lib/supercsv_interface.rb +231 -0
- data/test/test_complete.rb +37 -0
- data/test/test_critbit.rb +442 -0
- data/test/test_customer_list.rb +436 -0
- data/test/test_customer_map.rb +209 -0
- data/test/test_customer_nhlist.rb +161 -0
- data/test/test_deep_map.rb +264 -0
- data/test/test_del.rb +73 -0
- data/test/test_dimensions.rb +231 -0
- data/test/test_example.rb +79 -0
- data/test/test_filters.rb +374 -0
- data/test/test_list_dimensions.rb +110 -0
- data/test/test_mdarray.rb +227 -0
- data/test/test_missing_data.rb +57 -0
- data/vendor/commons-beanutils-1.8.3.jar +0 -0
- data/vendor/commons-lang3-3.1.jar +0 -0
- data/vendor/dozer-5.4.0.jar +0 -0
- data/vendor/jcl-over-slf4j-1.6.6.jar +0 -0
- data/vendor/joda-time-2.7.jar +0 -0
- data/vendor/slf4j-api-1.7.5.jar +0 -0
- data/vendor/snakeyaml-1.14.jar +0 -0
- data/vendor/super-csv-2.4.0.jar +0 -0
- data/vendor/super-csv-dozer-2.4.0.jar +0 -0
- data/vendor/super-csv-java8-2.4.0.jar +0 -0
- data/vendor/super-csv-joda-2.4.0.jar +0 -0
- data/version.rb +2 -0
- metadata +196 -0
data/lib/map_reader.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
##########################################################################################
|
4
|
+
# author Rodrigo Botafogo
|
5
|
+
#
|
6
|
+
# Copyright © 2015 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
|
7
|
+
# and distribute this software and its documentation, without fee and without a signed
|
8
|
+
# licensing agreement, is hereby granted, provided that the above copyright notice, this
|
9
|
+
# paragraph and the following two paragraphs appear in all copies, modifications, and
|
10
|
+
# distributions.
|
11
|
+
#
|
12
|
+
# IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
13
|
+
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
|
14
|
+
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
|
15
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
16
|
+
#
|
17
|
+
# RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
18
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
19
|
+
# SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
|
20
|
+
# RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
21
|
+
# OR MODIFICATIONS.
|
22
|
+
##########################################################################################
|
23
|
+
|
24
|
+
require 'critbit'
|
25
|
+
|
26
|
+
class Jcsv
|
27
|
+
|
28
|
+
#========================================================================================
|
29
|
+
#
|
30
|
+
#========================================================================================
|
31
|
+
|
32
|
+
class MapReader < Reader
|
33
|
+
include_package "java.io"
|
34
|
+
|
35
|
+
#---------------------------------------------------------------------------------------
|
36
|
+
#
|
37
|
+
#---------------------------------------------------------------------------------------
|
38
|
+
|
39
|
+
def initialize(*params)
|
40
|
+
super(*params)
|
41
|
+
@column_mapping.mapping = @headers if !@dimensions
|
42
|
+
@map_klass = (@format == :map)? Hash : Critbit
|
43
|
+
end
|
44
|
+
|
45
|
+
#---------------------------------------------------------------------------------------
|
46
|
+
# Maps columns to the given names. In map reader, there is no column reordering, as
|
47
|
+
# this does not really make any sense, since one gets to the data through the key and
|
48
|
+
# not through its position in the array. If there are dimensions set, then every
|
49
|
+
# dimension will map to true, in order for it to be properly processed by the parsing
|
50
|
+
# method. Other fields can still be mapped to false, so that they are not read if
|
51
|
+
# desired.
|
52
|
+
#---------------------------------------------------------------------------------------
|
53
|
+
|
54
|
+
def mapping=(column_mapping)
|
55
|
+
|
56
|
+
@column_mapping.mapping ||= Array.new
|
57
|
+
|
58
|
+
@headers.each_with_index do |h, i|
|
59
|
+
next if @dimensions && !@dimensions[h].nil?
|
60
|
+
name = column_mapping[h]
|
61
|
+
raise ArgumentError.new("'true' is not allowed as a mapping: #{column_mapping}") if
|
62
|
+
name == true
|
63
|
+
@column_mapping.mapping[i] = (name.nil?)? h : name
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
#---------------------------------------------------------------------------------------
|
69
|
+
# read the file.
|
70
|
+
#---------------------------------------------------------------------------------------
|
71
|
+
|
72
|
+
def read(&block)
|
73
|
+
|
74
|
+
# When no block given, chunks read are stored in an array and returned to the user.
|
75
|
+
if (!block_given?)
|
76
|
+
# if dimensions and chunk_size is 0, then do not wrap each row in an array, we
|
77
|
+
# can access the data directly by using the dimension key
|
78
|
+
if (@dimensions && @chunk_size == 0)
|
79
|
+
rows = @map_klass.new
|
80
|
+
parse_with_block do |line_no, row_no, chunk|
|
81
|
+
rows.merge!(chunk)
|
82
|
+
end
|
83
|
+
else
|
84
|
+
# chunk_size > 0, then each chunk should be a hash, and all chunks should
|
85
|
+
# be wrapped inside an array
|
86
|
+
rows = []
|
87
|
+
parse_with_block do |line_no, row_no, chunk|
|
88
|
+
rows << chunk
|
89
|
+
end
|
90
|
+
end
|
91
|
+
rows
|
92
|
+
else # block given
|
93
|
+
parse_with_block(&block)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#---------------------------------------------------------------------------------------
|
98
|
+
#
|
99
|
+
#---------------------------------------------------------------------------------------
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
#---------------------------------------------------------------------------------------
|
104
|
+
#
|
105
|
+
#---------------------------------------------------------------------------------------
|
106
|
+
|
107
|
+
def new_reader(preferences)
|
108
|
+
|
109
|
+
begin
|
110
|
+
raise MissingHeadersError.new("Reading file as map requires headers.") if
|
111
|
+
(!@headers && !@custom_headers)
|
112
|
+
@reader = CMR.new(FileReader.new(@filename), preferences, @dimensions,
|
113
|
+
@suppress_warnings)
|
114
|
+
rescue java.io.IOException => e
|
115
|
+
raise IOError.new(e.message)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
#---------------------------------------------------------------------------------------
|
121
|
+
#
|
122
|
+
#---------------------------------------------------------------------------------------
|
123
|
+
|
124
|
+
def format(chunk)
|
125
|
+
chunk
|
126
|
+
end
|
127
|
+
|
128
|
+
#---------------------------------------------------------------------------------------
|
129
|
+
# Maps columns to the given names. In map reader, there is no column reordering, as
|
130
|
+
# this does not really make any sense, since one gets to the data through the key and
|
131
|
+
# not through its position in the array. If there are dimensions set, then every
|
132
|
+
# dimension will map to true, in order for it to be properly processed by the parsing
|
133
|
+
# method. Other fields can still be mapped to false, so that they are not read if
|
134
|
+
# desired.
|
135
|
+
#---------------------------------------------------------------------------------------
|
136
|
+
|
137
|
+
def assign_mapping(column_mapping)
|
138
|
+
|
139
|
+
@column_mapping.mapping ||= Array.new
|
140
|
+
|
141
|
+
@headers.each_with_index do |h, i|
|
142
|
+
name = column_mapping[h]
|
143
|
+
@column_mapping.mapping[i] = (name.nil?)? h : name
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
#---------------------------------------------------------------------------------------
|
149
|
+
# A chunk is either one row of the file, or an array with rows. One row can be either
|
150
|
+
# a one dimensional array with all columns or a hash with all columns (excluding the
|
151
|
+
# dimensions).
|
152
|
+
#---------------------------------------------------------------------------------------
|
153
|
+
|
154
|
+
def read_chunk
|
155
|
+
|
156
|
+
if (@dimensions)
|
157
|
+
if (@chunk_size == 0)
|
158
|
+
row = @reader.read(@column_mapping, @filters)
|
159
|
+
return (row.nil?)? nil : { row.delete(:key).join(".") => row }
|
160
|
+
end
|
161
|
+
|
162
|
+
rows = {}
|
163
|
+
(1..@chunk_size).each do |i|
|
164
|
+
if ((row = @reader.read(@column_mapping, @filters)).nil?)
|
165
|
+
return (rows.size == 0)? nil : rows
|
166
|
+
else
|
167
|
+
if (@deep_map)
|
168
|
+
key = row.delete(:key)
|
169
|
+
key.reduce(rows) { |h,m| h[m] ||= {} }
|
170
|
+
last = key.pop
|
171
|
+
if (key.inject(rows, :fetch)[last] != {})
|
172
|
+
# p "overriding value for key: #{chunk[:key]} with #{chunk}"
|
173
|
+
raise DuplicateKeyError.new("Key #{row[:key]} not unique for this dataset. #{row}")
|
174
|
+
end
|
175
|
+
key.inject(rows, :fetch)[last] = row
|
176
|
+
else # not a deep map
|
177
|
+
key = row.delete(:key).join(".")
|
178
|
+
raise DuplicateKeyError.new("Key #{key} not unique for this dataset. #{row}") if
|
179
|
+
rows.has_key?(key)
|
180
|
+
rows.merge!({key => row})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
return rows
|
185
|
+
else # no dimensions
|
186
|
+
super
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
data/lib/mdarray-jcsv.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
##########################################################################################
|
4
|
+
# @author Rodrigo Botafogo
|
5
|
+
#
|
6
|
+
# Copyright © 2015 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
|
7
|
+
# and distribute this software and its documentation, without fee and without a signed
|
8
|
+
# licensing agreement, is hereby granted, provided that the above copyright notice, this
|
9
|
+
# paragraph and the following two paragraphs appear in all copies, modifications, and
|
10
|
+
# distributions.
|
11
|
+
#
|
12
|
+
# IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
13
|
+
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
|
14
|
+
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
|
15
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
16
|
+
#
|
17
|
+
# RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
18
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
19
|
+
# SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
|
20
|
+
# RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
21
|
+
# OR MODIFICATIONS.
|
22
|
+
##########################################################################################
|
23
|
+
|
24
|
+
require_relative 'jcsv'
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
##########################################################################################
|
4
|
+
# @author Rodrigo Botafogo
|
5
|
+
#
|
6
|
+
# Copyright © 2015 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
|
7
|
+
# and distribute this software and its documentation, without fee and without a signed
|
8
|
+
# licensing agreement, is hereby granted, provided that the above copyright notice, this
|
9
|
+
# paragraph and the following two paragraphs appear in all copies, modifications, and
|
10
|
+
# distributions.
|
11
|
+
#
|
12
|
+
# IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
13
|
+
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
|
14
|
+
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
|
15
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
16
|
+
#
|
17
|
+
# RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
18
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
19
|
+
# SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
|
20
|
+
# RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
21
|
+
# OR MODIFICATIONS.
|
22
|
+
##########################################################################################
|
23
|
+
|
24
|
+
require 'mdarray'
|
25
|
+
|
26
|
+
class Jcsv
|
27
|
+
|
28
|
+
#========================================================================================
|
29
|
+
#
|
30
|
+
#========================================================================================
|
31
|
+
|
32
|
+
class MDArrayReader < MapReader
|
33
|
+
include_package "java.io"
|
34
|
+
|
35
|
+
#---------------------------------------------------------------------------------------
|
36
|
+
#
|
37
|
+
#---------------------------------------------------------------------------------------
|
38
|
+
|
39
|
+
def initialize(*params)
|
40
|
+
|
41
|
+
filter = nil
|
42
|
+
|
43
|
+
@dtype = params[1].delete(:dtype)
|
44
|
+
|
45
|
+
case @dtype
|
46
|
+
when :byte, :short, :int
|
47
|
+
filter = Jcsv.int
|
48
|
+
when :long
|
49
|
+
filter = Jcsv.long
|
50
|
+
when :float, :double
|
51
|
+
filter = Jcsv.double
|
52
|
+
else
|
53
|
+
raise "Cannot create MDArray of dtype '#{@dtype}'"
|
54
|
+
end
|
55
|
+
|
56
|
+
params[1][:default_filter] = filter
|
57
|
+
super(*params)
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
#---------------------------------------------------------------------------------------
|
62
|
+
#
|
63
|
+
#---------------------------------------------------------------------------------------
|
64
|
+
|
65
|
+
def read
|
66
|
+
to_mdarray(@dtype, super)
|
67
|
+
end
|
68
|
+
|
69
|
+
#---------------------------------------------------------------------------------------
|
70
|
+
# Converts the data to an MDArray
|
71
|
+
#---------------------------------------------------------------------------------------
|
72
|
+
|
73
|
+
def to_mdarray(dtype, storage)
|
74
|
+
|
75
|
+
raise "Cannot convert deep map into MDArray" if (@deep_map == true)
|
76
|
+
|
77
|
+
prod = nil
|
78
|
+
shape = []
|
79
|
+
vector = []
|
80
|
+
|
81
|
+
columns = @column_mapping.mapping - [true, false, nil]
|
82
|
+
header_size = columns.size
|
83
|
+
|
84
|
+
if (@dimensions.nil?)
|
85
|
+
shape = [storage.size, header_size]
|
86
|
+
storage.each do |line|
|
87
|
+
vector.concat(line.values)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
@dimensions.dimensions_names.each do |name|
|
91
|
+
keys = @dimensions[name].labels.keys
|
92
|
+
shape << keys.size
|
93
|
+
prod = (prod.nil?)? keys : prod.product(keys)
|
94
|
+
end
|
95
|
+
|
96
|
+
shape << header_size
|
97
|
+
|
98
|
+
prod.each do |k|
|
99
|
+
row = (@dimensions.dimensions_names.size > 1)? storage[k.flatten.join(".")] : storage[k]
|
100
|
+
vector.concat(((row.nil?)? ([Float::NAN] * header_size) : row.values))
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
array = MDArray.build(@dtype, shape, vector)
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
##########################################################################################
|
4
|
+
# @author Rodrigo Botafogo
|
5
|
+
#
|
6
|
+
# Copyright © 2015 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
|
7
|
+
# and distribute this software and its documentation, without fee and without a signed
|
8
|
+
# licensing agreement, is hereby granted, provided that the above copyright notice, this
|
9
|
+
# paragraph and the following two paragraphs appear in all copies, modifications, and
|
10
|
+
# distributions.
|
11
|
+
#
|
12
|
+
# IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
13
|
+
# INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
|
14
|
+
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
|
15
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
16
|
+
#
|
17
|
+
# RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
18
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
19
|
+
# SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
|
20
|
+
# RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
21
|
+
# OR MODIFICATIONS.
|
22
|
+
##########################################################################################
|
23
|
+
|
24
|
+
require 'bigdecimal'
|
25
|
+
require_relative 'locale'
|
26
|
+
|
27
|
+
class Jcsv
|
28
|
+
# include_package "org.supercsv.cellprocessor"
|
29
|
+
# include_package "org.supercsv.cellprocessor.constraint"
|
30
|
+
|
31
|
+
#========================================================================================
|
32
|
+
#
|
33
|
+
#========================================================================================
|
34
|
+
|
35
|
+
class RBParseInt < org.supercsv.cellprocessor.ParseInt
|
36
|
+
include NextFilter
|
37
|
+
|
38
|
+
def execute(value, context)
|
39
|
+
begin
|
40
|
+
exec_next(super(value, context), context)
|
41
|
+
rescue org.supercsv.exception.SuperCsvCellProcessorException => e
|
42
|
+
raise FilterError.new("#{e.message} in #{context}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
#========================================================================================
|
49
|
+
#
|
50
|
+
#========================================================================================
|
51
|
+
|
52
|
+
class RBParseLong < org.supercsv.cellprocessor.ParseLong
|
53
|
+
include NextFilter
|
54
|
+
|
55
|
+
def execute(value, context)
|
56
|
+
begin
|
57
|
+
exec_next(super(value, context), context)
|
58
|
+
rescue org.supercsv.exception.SuperCsvCellProcessorException => e
|
59
|
+
raise FilterError, "#{e.message} in #{context}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
#========================================================================================
|
66
|
+
#
|
67
|
+
#========================================================================================
|
68
|
+
|
69
|
+
class RBParseDouble < org.supercsv.cellprocessor.ParseDouble
|
70
|
+
include NextFilter
|
71
|
+
|
72
|
+
def execute(value, context)
|
73
|
+
begin
|
74
|
+
exec_next(super(value, context), context)
|
75
|
+
rescue org.supercsv.exception.SuperCsvCellProcessorException => e
|
76
|
+
raise FilterError, "#{e.message} in #{context}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
#========================================================================================
|
83
|
+
#
|
84
|
+
#========================================================================================
|
85
|
+
|
86
|
+
class RBParseFloat < Filter
|
87
|
+
|
88
|
+
attr_reader :locale
|
89
|
+
attr_reader :dfs
|
90
|
+
|
91
|
+
def initialize(locale)
|
92
|
+
@locale = locale
|
93
|
+
@dfs = DFSymbols.new(locale)
|
94
|
+
@grouping_separator = @dfs.grouping_separator
|
95
|
+
@decimal_separator = @dfs.decimal_separator
|
96
|
+
super()
|
97
|
+
end
|
98
|
+
|
99
|
+
def execute(value, context)
|
100
|
+
validateInputNotNull(value, context)
|
101
|
+
value = value.gsub(@grouping_separator.chr, "").
|
102
|
+
gsub(@decimal_separator.chr, ".").to_f
|
103
|
+
exec_next(value, context)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
#========================================================================================
|
109
|
+
#
|
110
|
+
#========================================================================================
|
111
|
+
|
112
|
+
class RBParseBignum < Filter
|
113
|
+
|
114
|
+
def execute(value, context)
|
115
|
+
validateInputNotNull(value, context)
|
116
|
+
exec_next(value.to_i, context)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
#========================================================================================
|
122
|
+
#
|
123
|
+
#========================================================================================
|
124
|
+
|
125
|
+
class RBParseComplex < Filter
|
126
|
+
|
127
|
+
def execute(value, context)
|
128
|
+
validateInputNotNull(value, context)
|
129
|
+
exec_next(value.to_c, context)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
#========================================================================================
|
135
|
+
#
|
136
|
+
#========================================================================================
|
137
|
+
|
138
|
+
class RBParseRational < Filter
|
139
|
+
|
140
|
+
def execute(value, context)
|
141
|
+
validateInputNotNull(value, context)
|
142
|
+
exec_next(value.to_r, context)
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
#========================================================================================
|
148
|
+
#
|
149
|
+
#========================================================================================
|
150
|
+
|
151
|
+
class RBParseBigDecimal < Filter
|
152
|
+
|
153
|
+
attr_reader :locale
|
154
|
+
attr_reader :dfs
|
155
|
+
|
156
|
+
def initialize(locale)
|
157
|
+
@locale = locale
|
158
|
+
@dfs = DFSymbols.new(locale)
|
159
|
+
@grouping_separator = @dfs.grouping_separator
|
160
|
+
@decimal_separator = @dfs.decimal_separator
|
161
|
+
super()
|
162
|
+
end
|
163
|
+
|
164
|
+
def execute(value, context)
|
165
|
+
validateInputNotNull(value, context)
|
166
|
+
# raise "BigDecimal expects a String as input not #{value}" if !(value.is_a? String)
|
167
|
+
bd = BigDecimal.new(value.gsub(@grouping_separator.chr, "").
|
168
|
+
gsub(@decimal_separator.chr, "."))
|
169
|
+
exec_next(bd, context)
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
#========================================================================================
|
175
|
+
#
|
176
|
+
#========================================================================================
|
177
|
+
|
178
|
+
def self.int
|
179
|
+
RBParseInt.new
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.long
|
183
|
+
RBParseLong.new
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.double
|
187
|
+
RBParseDouble.new
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.fixnum
|
191
|
+
RBParseBignum.new
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.float(locale = Locale.default)
|
195
|
+
RBParseFloat.new(locale)
|
196
|
+
end
|
197
|
+
|
198
|
+
def self.complex
|
199
|
+
RBParseComplex.new
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.rational
|
203
|
+
RBParseRational.new
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.bignum
|
207
|
+
RBParseBignum.new
|
208
|
+
end
|
209
|
+
|
210
|
+
#---------------------------------------------------------------------------------------
|
211
|
+
# Convert a String to a BigDecimal. It uses the String constructor of BigDecimal
|
212
|
+
# (new BigDecimal("0.1")) as it yields predictable results (see BigDecimal).
|
213
|
+
# If the data uses a character other than "." as a decimal separator (Germany uses ","
|
214
|
+
# for example), then use the constructor that accepts a DecimalFormatSymbols object, as
|
215
|
+
# it will convert the character to a "." before creating the BigDecimal. Likewise if the
|
216
|
+
# data contains a grouping separator (Germany uses "." for example) then supplying a
|
217
|
+
# DecimalFormatSymbols object will allow grouping separators to be removed before
|
218
|
+
# parsing.
|
219
|
+
#---------------------------------------------------------------------------------------
|
220
|
+
|
221
|
+
def self.big_decimal(locale = Locale.default)
|
222
|
+
Jcsv::RBParseBigDecimal.new(locale)
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|