Class: FLRFile
- Inherits:
-
Object
- Object
- FLRFile
- Includes:
- Enumerable
- Defined in:
- lib/hflr/fl_record_file.rb
Instance Attribute Summary collapse
-
#line_number ⇒ Object
readonly
Returns the value of attribute line_number.
-
#record_template ⇒ Object
readonly
Returns the value of attribute record_template.
Class Method Summary collapse
-
.open(path, mode, record_types, record_layouts, logical_first_column = 0) ⇒ Object
Use when creating a new HFLR file.
Instance Method Summary collapse
-
#<<(record) ⇒ Object
This will take a Hash or Struct orArray; if an Array the record type must be the last element when the record layout has more than one record type.
- #build_record(line) ⇒ Object
- #close ⇒ Object
- #each ⇒ Object
- #fast_get_next_known_line_type ⇒ Object
- #finished? ⇒ Boolean
- #get_next_known_line_type ⇒ Object
- #get_next_line ⇒ Object
-
#get_record_type(line) ⇒ Object
If multiple record types, extract it from the string, otherwise just return the type of this file.
- #in_range?(line_number) ⇒ Boolean
-
#initialize(source, record_types, record_layouts, logical_first_column = 0, extra_columns = nil) ⇒ FLRFile
constructor
A new instance of FLRFile.
- #line_type(line) ⇒ Object
- #next ⇒ Object
- #next_record ⇒ Object
- #ranges=(ranges) ⇒ Object
- #sequential_get_next_known_line_type ⇒ Object
- #set_fast ⇒ Object
Constructor Details
#initialize(source, record_types, record_layouts, logical_first_column = 0, extra_columns = nil) ⇒ FLRFile
Returns a new instance of FLRFile.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/hflr/fl_record_file.rb', line 7 def initialize(source, record_types, record_layouts, logical_first_column=0, extra_columns = nil) # Allow record layouts like # {:type1=>[:var1=>1..5,:var2=>7..8],:type2=>[:var1=>1..1,:var2=>3..4]} if record_layouts.values.first.is_a? Hash record_layouts = create_layouts(record_layouts) end @line_number = 0 @file = source @record_type_labels = record_types @record_type_symbols = record_types.is_a?(Hash) ? record_types : :none if extra_columns then @record_template = HFLR::RecordTemplate.create(record_layouts, @record_type_symbols, logical_first_column, extra_columns) else @record_template = HFLR::RecordTemplate.create(record_layouts, @record_type_symbols, logical_first_column) end end |
Instance Attribute Details
#line_number ⇒ Object (readonly)
Returns the value of attribute line_number.
5 6 7 |
# File 'lib/hflr/fl_record_file.rb', line 5 def line_number @line_number end |
#record_template ⇒ Object (readonly)
Returns the value of attribute record_template.
5 6 7 |
# File 'lib/hflr/fl_record_file.rb', line 5 def record_template @record_template end |
Class Method Details
.open(path, mode, record_types, record_layouts, logical_first_column = 0) ⇒ Object
Use when creating a new HFLR file
214 215 216 217 218 219 220 221 222 |
# File 'lib/hflr/fl_record_file.rb', line 214 def self.open(path, mode, record_types, record_layouts, logical_first_column=0) file = File.open(path, mode) begin hflr_file = new(file, record_types, record_layouts, logical_first_column) yield hflr_file ensure file.close end end |
Instance Method Details
#<<(record) ⇒ Object
This will take a Hash or Struct orArray; if an Array the record type must be the last element when the record layout has more than one record type.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/hflr/fl_record_file.rb', line 194 def <<(record) record_type = if record.is_a? Array @record_type_symbols == :none ? @record_template.keys.first : record.last else if @record_template[record[:record_type]] == nil then raise "Record type problem in output: #{record[:record_type].to_s} type on record, #{@record_template.keys.join(",")} types of templates" end @record_type_symbols == :none ? @record_template.keys.first : record[:record_type] end line = @record_template[record_type].build_line(record) if @cr_before_line line = "\n" + line else @cr_before_line = true end @file.write(line) end |
#build_record(line) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/hflr/fl_record_file.rb', line 99 def build_record(line) return nil if line.nil? record_type = line_type(line) raise "Unknown record type at line #{@line_number.to_s}" if record_type == :unknown @record_template[record_type].build_record(line.chomp) end |
#close ⇒ Object
68 69 70 |
# File 'lib/hflr/fl_record_file.rb', line 68 def close @file.close end |
#each ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/hflr/fl_record_file.rb', line 178 def each @line_number = 1 if @fast yield(next_record) until finished? else @file.each_line do |line| unless line_type(line) == :unknown || !in_range?(@line_number) data = build_record(line) yield data end end end end |
#fast_get_next_known_line_type ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/hflr/fl_record_file.rb', line 129 def fast_get_next_known_line_type if @current_buffer.nil? && (@offsets.nil? || @offsets.empty?) nil else if @current_buffer.nil? chunk = @offsets.shift @file.pos = chunk.pos @current_buffer=@file.read(chunk.width) record= @current_buffer.slice(@position, @width) @position += @width if @position >= @current_buffer.size @current_buffer = nil @position=0 end return record else record= @current_buffer.slice(@position, @width) @position += @width if @position>=@current_buffer.size @position=0 @current_buffer=nil end return record end end end |
#finished? ⇒ Boolean
60 61 62 63 64 65 66 |
# File 'lib/hflr/fl_record_file.rb', line 60 def finished? if @fast @offsets.empty? && @current_buffer.nil? else @file.eof? end end |
#get_next_known_line_type ⇒ Object
115 116 117 |
# File 'lib/hflr/fl_record_file.rb', line 115 def get_next_known_line_type @fast ? fast_get_next_known_line_type : sequential_get_next_known_line_type end |
#get_next_line ⇒ Object
119 120 121 122 123 |
# File 'lib/hflr/fl_record_file.rb', line 119 def get_next_line line = @file.gets @line_number+=1 line end |
#get_record_type(line) ⇒ Object
If multiple record types, extract it from the string, otherwise just return the type of this file
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/hflr/fl_record_file.rb', line 73 def get_record_type(line) return nil if line.nil? return nil if line.strip.empty? if @record_type_labels.is_a?(Hash) matching_pair = @record_type_labels.find do |_, value| discriminator = value[:discriminator] case discriminator when String position = value[:position] - 1 line[position..-1].start_with?(discriminator) when Regexp line =~ discriminator else nil end end if matching_pair matching_pair[0] else nil end else @record_type_labels end end |
#in_range?(line_number) ⇒ Boolean
56 57 58 |
# File 'lib/hflr/fl_record_file.rb', line 56 def in_range?(line_number) @ranges ? !!(@ranges.detect { |r| r.member?(line_number) }) : true end |
#line_type(line) ⇒ Object
110 111 112 113 |
# File 'lib/hflr/fl_record_file.rb', line 110 def line_type(line) record_type = get_record_type(line) record_type ? record_type : :unknown end |
#next ⇒ Object
125 126 127 |
# File 'lib/hflr/fl_record_file.rb', line 125 def next build_record(get_next_line) end |
#next_record ⇒ Object
106 107 108 |
# File 'lib/hflr/fl_record_file.rb', line 106 def next_record build_record(get_next_known_line_type) end |
#ranges=(ranges) ⇒ Object
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/hflr/fl_record_file.rb', line 44 def ranges=(ranges) @fast or raise "Cannot read selected ranges because input file has multiple record types #{@record_type_labels.to_s}" unless ranges.first.is_a?(Range) raise "You specified a #{ranges.first.class.to_s} instead of a range in the list of ranges. Use (a..b) to specify a range." end @offsets =offsets_to_read(ranges, @width) @ranges = ranges end |
#sequential_get_next_known_line_type ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/hflr/fl_record_file.rb', line 165 def sequential_get_next_known_line_type line = @file.gets @line_number+=1 record_type = line_type(line) while !finished? && (!in_range?(@line_number) || record_type == :unknown) line = @file.gets @line_number+=1 record_type = line_type(line) end record_type == :unknown ? nil : line end |
#set_fast ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/hflr/fl_record_file.rb', line 25 def set_fast @fast = !@record_type_labels.is_a?(Hash) unless @fast raise "Cannot set fast mode with more than one record type." end if @fast @width = get_record_width_from_file records_to_take = 100000000 / @width @buffer_size = @width * records_to_take @position=0 @current_buffer=nil end end |