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_random_record(record_number) ⇒ 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_record ⇒ Object
- #ranges=(ranges) ⇒ Object
- #sequential_get_next_known_line_type ⇒ Object
- #set_fast ⇒ Object
- #set_random ⇒ Object
Constructor Details
#initialize(source, record_types, record_layouts, logical_first_column = 0, extra_columns = nil) ⇒ FLRFile
Returns a new instance of FLRFile.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/hflr/fl_record_file.rb', line 15 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.invert : :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.
13 14 15 |
# File 'lib/hflr/fl_record_file.rb', line 13 def line_number @line_number end |
#record_template ⇒ Object (readonly)
Returns the value of attribute record_template.
13 14 15 |
# File 'lib/hflr/fl_record_file.rb', line 13 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
212 213 214 215 216 217 218 219 220 |
# File 'lib/hflr/fl_record_file.rb', line 212 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.
197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/hflr/fl_record_file.rb', line 197 def <<(record) if record.is_a? Array record_type = @record_type_symbols == :none ? @record_template.keys.first : record.last @file.puts @record_template[record_type].build_line(record) else record_type = @record_type_symbols == :none ?@record_template.keys.first : record[:record_type] 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 @file.puts @record_template[record_type].build_line(record) end end |
#build_record(line) ⇒ Object
110 111 112 113 114 115 |
# File 'lib/hflr/fl_record_file.rb', line 110 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 return @record_template[record_type].build_record(line.chomp) end |
#close ⇒ Object
99 100 101 |
# File 'lib/hflr/fl_record_file.rb', line 99 def close @file.close end |
#each ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/hflr/fl_record_file.rb', line 181 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
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 164 165 |
# File 'lib/hflr/fl_record_file.rb', line 130 def fast_get_next_known_line_type unless @current_buffer.nil? && (@offsets.nil? || @offsets.empty?) 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 else nil end end |
#finished? ⇒ Boolean
91 92 93 94 95 96 97 |
# File 'lib/hflr/fl_record_file.rb', line 91 def finished? if @fast @offsets.empty? && @current_buffer.nil? else @file.eof? end end |
#get_next_known_line_type ⇒ Object
126 127 128 |
# File 'lib/hflr/fl_record_file.rb', line 126 def get_next_known_line_type @fast ? fast_get_next_known_line_type : sequential_get_next_known_line_type end |
#get_random_record(record_number) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/hflr/fl_record_file.rb', line 42 def get_random_record(record_number) return record_number if record_number.nil? offset = record_number * @width begin @file.pos = offset line = @file.read(@width) rescue Exception=>msg return nil end build_record(line) end |
#get_record_type(line) ⇒ Object
If multiple record types, extract it from the string, otherwise just return the type of this file
104 105 106 107 108 |
# File 'lib/hflr/fl_record_file.rb', line 104 def get_record_type(line) return nil if line.nil? return nil if line.strip.empty? @record_type_labels.is_a?(Hash) ? @record_type_labels[line[0..0]] : @record_type_labels end |
#in_range?(line_number) ⇒ Boolean
87 88 89 |
# File 'lib/hflr/fl_record_file.rb', line 87 def in_range?(line_number) @ranges ? !!(@ranges.detect{|r| r.member?(line_number)}) : true end |
#line_type(line) ⇒ Object
121 122 123 124 |
# File 'lib/hflr/fl_record_file.rb', line 121 def line_type(line) record_type = get_record_type(line) return record_type ? record_type : :unknown end |
#next_record ⇒ Object
117 118 119 |
# File 'lib/hflr/fl_record_file.rb', line 117 def next_record build_record(get_next_known_line_type) end |
#ranges=(ranges) ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/hflr/fl_record_file.rb', line 75 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
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/hflr/fl_record_file.rb', line 167 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
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/hflr/fl_record_file.rb', line 55 def set_fast if @random raise "Already set random access mode" end @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 |
#set_random ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/hflr/fl_record_file.rb', line 32 def set_random if @fast raise "Cannot set random access mode with fast mode already set." end @random = !@record_type_labels.is_a?(Hash) @random or raise "Cannot set random mode with more than one record type." @width = get_record_width_from_file end |