Class: LoiParser::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/loi_parser/reader.rb

Overview

Read about the Ruby’s String#unpack method: ruby-doc.org/3.0.4/String.html#method-i-unpack

Read about the Ruby’s IO#seek method: ruby-doc.org/3.0.4/IO.html#method-i-seek

Ruby Bitwise Operators medium.com/rubycademy/ruby-bitwise-operators-da57763fa368

Defined Under Namespace

Classes: InvalidLoiFile

Constant Summary collapse

HEADER_COLUMNS =
[
  { field: :length, length: 4 },
  { field: :application, length: 20 },
  { field: :version, length: 2 },
  { field: :date, length: 8 },
  { field: :date_range, length: 4 },
  { field: :list_format, length: 4 },
  { field: :bitmap_size, length: 8 }
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Reader

Returns a new instance of Reader.



29
30
31
32
33
34
35
36
# File 'lib/loi_parser/reader.rb', line 29

def initialize(path)
  @path = path

  open_file!

  @header = build_header
  @list_start_position = @file.pos
end

Instance Attribute Details

#headerObject (readonly)

Returns the value of attribute header.



17
18
19
# File 'lib/loi_parser/reader.rb', line 17

def header
  @header
end

#pathObject (readonly)

Returns the value of attribute path.



17
18
19
# File 'lib/loi_parser/reader.rb', line 17

def path
  @path
end

Instance Method Details

#in_opposition?(serial_number) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/loi_parser/reader.rb', line 38

def in_opposition?(serial_number)
  unless serial_number.is_a?(Integer)
    raise ArgumentError, 'serial_number must be an Integer'
  end

  # Reading the bitmap list
  position = serial_number / 8

  # When position is out of bitmap range, the serial number is in opposition
  return true if position > header[:bitmap_size]

  # Moves to the serial number position from the bitmap
  @file.seek(position, IO::SEEK_CUR)

  # Read the byte as binary
  byte = @file.read(1).unpack1('B*')

  # Checks for opposition
  opposition = serial_in_opposition_from?(serial_number, byte)

  # Moves back to the initial position
  @file.seek(@list_start_position, IO::SEEK_SET)

  opposition
end

#serials_in_oppositionObject



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/loi_parser/reader.rb', line 64

def serials_in_opposition
  # https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/
  @starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)

  serial_numbers = find_all_serial_numbers_in_opposition

  LoiParser.logger.info(
    "Gathered #{serial_numbers.size} serial number(s) " \
    "in opposition in #{elapsed_time_in_minutes}."
  )

  serial_numbers
end