Class: Parser::BinaryProtocol

Inherits:
Object
  • Object
show all
Defined in:
lib/proto/MPS7/parser.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ BinaryProtocol

Returns a new instance of BinaryProtocol.



7
8
9
# File 'lib/proto/MPS7/parser.rb', line 7

def initialize(argv)
  @binary_file = argv[0]
end

Instance Attribute Details

#binary_fileObject

Returns the value of attribute binary_file.



5
6
7
# File 'lib/proto/MPS7/parser.rb', line 5

def binary_file
  @binary_file
end

Class Method Details

.answers(calculations) ⇒ Object



126
127
128
129
130
131
132
133
134
# File 'lib/proto/MPS7/parser.rb', line 126

def self.answers(calculations)
  puts <<~CALCS.strip
    $#{self.monetize(calculations[:debit])} is the total amount in dollars of debits,
    $#{self.monetize(calculations[:credit])} is the total amount of dollars of credits,
    #{calculations[:started_count]} autopays were started,
    #{calculations[:ended_count]} autopays were ended,
    user ID 2456938384156277127 has a balance of $#{self.monetize(calculations['2456938384156277127'])}.
    CALCS
end

.asciiObject



11
12
13
14
# File 'lib/proto/MPS7/parser.rb', line 11

def self.ascii
  # the artii gem creates ascii text
  `artii proto-MPS7 Parser`
end

.monetize(money) ⇒ Object



122
123
124
# File 'lib/proto/MPS7/parser.rb', line 122

def self.monetize(money)
  '%.2f' % money
end

Instance Method Details

#binary_data_present?(data, index) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/proto/MPS7/parser.rb', line 78

def binary_data_present?(data, index)
  data[index].present?
end

#credit?(data, index) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/proto/MPS7/parser.rb', line 86

def credit?(data, index)
  data[index].unpack("C")[0] == 1
end

#debit?(data, index) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/proto/MPS7/parser.rb', line 82

def debit?(data, index)
  data[index].unpack("C")[0] == 0
end

#end_autopay?(data, index) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/proto/MPS7/parser.rb', line 94

def end_autopay?(data, index)
  data[index].unpack("C")[0] == 3
end

#for_user_id?(record, id) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/proto/MPS7/parser.rb', line 98

def for_user_id?(record, id)
  record[2] == id
end

#parseObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/proto/MPS7/parser.rb', line 16

def parse
  begin
    contents = File.open("#{binary_file}", 'rb') { |f| f.read }
  rescue Errno::ENOENT => e
    STDERR.puts "No binary file given as an argument. Please include binary file to continue."
    exit
  end
  header = contents.unpack("a4CL>")
  # header = ["MPS7", 1, 1191182336]

  index = 0
  calculations = { :debit => BigDecimal.new(0),
                   :credit => BigDecimal.new(0),
                   :started_count => 0,
                   :ended_count => 0,
                   '2456938384156277127' => BigDecimal.new(0) }

  data = contents.bytes.slice!(9..-1).pack("C*")

  while binary_data_present?(data, index)
    # debit
    if debit?(data, index)
      record = unpack_four_fields(data, index)
      # total amount in dollars of debits
      total_dollars(calculations, :debit, record)
      # for user ID 2456938384156277127,
      if for_user_id?(record, 2456938384156277127)
        # sum the dollars of debits from the user's total balance
        user_balance(calculations, 'sum', record)
      end
      index += 21
    # credit
    elsif credit?(data, index)
      record = unpack_four_fields(data, index)
      # total amount in dollars of credits
      total_dollars(calculations, :credit, record)
      # for user ID 2456938384156277127,
      if for_user_id?(record, 2456938384156277127)
        # subtract the dollars of credits from the user's total balance
        user_balance(calculations, 'difference', record)
      end
      index += 21
    # StartAutopay
    elsif start_autopay?(data, index)
      unpack_three_fields(data, index)
      # increase the total count of how many times Autopay has been started
      calculations[:started_count] += 1
      index += 13
    # EndAutopay
    elsif end_autopay?(data, index)
      unpack_three_fields(data, index)
      # increase the total count of how many times Autopay has been ended
      calculations[:ended_count] += 1
      index += 13
    else
      STDERR.puts "Binary does not follow custom protocol."
      exit
    end
  end
  calculations
end

#start_autopay?(data, index) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/proto/MPS7/parser.rb', line 90

def start_autopay?(data, index)
  data[index].unpack("C")[0] == 2
end

#total_dollars(calculations, account, record) ⇒ Object



110
111
112
# File 'lib/proto/MPS7/parser.rb', line 110

def total_dollars(calculations, , record)
  calculations[] += record[3].to_d
end

#unpack_four_fields(data, index) ⇒ Object



102
103
104
# File 'lib/proto/MPS7/parser.rb', line 102

def unpack_four_fields(data, index)
  data[index..index + 21].unpack("CL>Q>G")
end

#unpack_three_fields(data, index) ⇒ Object



106
107
108
# File 'lib/proto/MPS7/parser.rb', line 106

def unpack_three_fields(data, index)
  data[index..index + 13].unpack("CL>Q>")
end

#user_balance(calculations, operator, record) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/proto/MPS7/parser.rb', line 114

def user_balance(calculations, operator, record)
  if operator == 'sum'
    calculations['2456938384156277127'] += record[3].to_d
  elsif operator == 'difference'
    calculations['2456938384156277127'] -= record[3].to_d
  end
end