da_funk 3.30.0 → 3.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +10 -1
- data/Gemfile.lock +12 -2
- data/README.md +0 -0
- data/README_GUIDE.md +0 -0
- data/RELEASE_NOTES.md +27 -0
- data/Rakefile +14 -0
- data/guides/sample_input_output.rb +0 -0
- data/guides/sample_message_iso8583.rb +0 -0
- data/guides/sample_network_gprs.rb +0 -0
- data/guides/sample_read_magnect_card.rb +0 -0
- data/guides/sample_socket.rb +0 -0
- data/guides/sample_transaction.rb +0 -0
- data/guides/sample_transaction_download_application.rb +0 -0
- data/guides/sample_transaction_download_file.rb +0 -0
- data/guides/sample_transaction_download_parameter_file.rb +0 -0
- data/lib/da_funk/connection_management.rb +25 -10
- data/lib/da_funk/event_handler.rb +1 -1
- data/lib/da_funk/helper.rb +55 -16
- data/lib/da_funk/helper/status_bar.rb +158 -105
- data/lib/da_funk/params_dat.rb +65 -25
- data/lib/da_funk/rake_task.rb +13 -6
- data/lib/da_funk/transaction/download.rb +0 -0
- data/lib/da_funk/transaction/iso.rb +0 -0
- data/lib/da_funk/version.rb +1 -1
- data/lib/device.rb +0 -0
- data/lib/device/crypto.rb +0 -0
- data/lib/device/display.rb +2 -1
- data/lib/device/io.rb +53 -0
- data/lib/device/network.rb +19 -33
- data/lib/device/printer.rb +0 -0
- data/lib/device/setting.rb +0 -0
- data/lib/device/system.rb +9 -0
- data/lib/device/version.rb +0 -0
- data/lib/device/virtual_keyboard.rb +81 -34
- data/lib/file_db.rb +0 -0
- data/lib/iso8583/bitmap.rb +94 -54
- data/lib/iso8583/codec.rb +3 -3
- data/lib/iso8583/field.rb +38 -3
- data/lib/iso8583/fields.rb +3 -1
- data/lib/iso8583/message.rb +25 -12
- data/lib/iso8583/util.rb +1 -1
- data/test/iso8583/bitmap_test.rb +277 -0
- data/test/iso8583/message_test.rb +111 -0
- data/test/iso8583/minitest_helper.rb +11 -0
- metadata +12 -6
data/lib/file_db.rb
CHANGED
File without changes
|
data/lib/iso8583/bitmap.rb
CHANGED
@@ -14,16 +14,51 @@ module ISO8583
|
|
14
14
|
# transparently by the Message class.
|
15
15
|
class Bitmap
|
16
16
|
include DaFunk::Helper
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# Parse the bytes in string and return the Bitmap and bytes remaining in `str`
|
20
|
+
# after the bitmap is taken away.
|
21
|
+
def parse(str, hex_bitmap = false, bitmap_size = 64)
|
22
|
+
bmp = Bitmap.new(str, hex_bitmap, bitmap_size)
|
23
|
+
|
24
|
+
rest = if bmp.hex_bitmap?
|
25
|
+
str[bmp.size_in_bytes_hex, str.length]
|
26
|
+
else
|
27
|
+
str[bmp.size_in_bytes, str.length]
|
28
|
+
end
|
29
|
+
|
30
|
+
[ bmp, rest ]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# bitmap_size defines the size in bits of bitmap. It has to be multiple of 8 (a byte of 8 bits)
|
35
|
+
attr_reader :bitmap_size
|
36
|
+
|
37
|
+
# additional_bitmap defines if the bit 1 (left to right) indicates the presence of another
|
38
|
+
# bitmap just after the current one
|
39
|
+
attr_reader :additional_bitmap
|
40
|
+
|
41
|
+
attr_reader :bitmaps
|
42
|
+
|
17
43
|
# create a new Bitmap object. In case an iso message
|
18
44
|
# is passed in, that messages bitmap will be parsed. If
|
19
45
|
# not, this initializes and empty bitmap.
|
20
|
-
def initialize(message = nil, hex_bitmap=false)
|
21
|
-
|
22
|
-
|
46
|
+
def initialize(message = nil, hex_bitmap=false, bitmap_size = 64, additional_bitmap = true)
|
47
|
+
raise ISO8583Exception.new "wrong bitmap_size: #{bitmap_size}" if bitmap_size % 8 != 0
|
48
|
+
|
49
|
+
@bitmap_size = bitmap_size
|
50
|
+
@bmp = Array.new(bitmap_size, false)
|
51
|
+
@hex_bitmap = hex_bitmap
|
52
|
+
@additional_bitmap = additional_bitmap
|
53
|
+
@bitmaps = 1
|
23
54
|
|
24
55
|
message ? initialize_from_message(message) : nil
|
25
56
|
end
|
26
57
|
|
58
|
+
def additional_bitmap?
|
59
|
+
!!@additional_bitmap
|
60
|
+
end
|
61
|
+
|
27
62
|
def hex_bitmap?
|
28
63
|
!!@hex_bitmap
|
29
64
|
end
|
@@ -38,22 +73,40 @@ module ISO8583
|
|
38
73
|
@bmp[i-1]
|
39
74
|
end
|
40
75
|
|
41
|
-
# Set the bit to the indicated value. Only `true` sets the
|
42
|
-
# bit, any other value unsets it.
|
43
|
-
def []=(i, value)
|
44
|
-
if i > 128
|
45
|
-
raise ISO8583Exception.new("Bits > 128 are not permitted.")
|
46
|
-
elsif i < 2
|
47
|
-
raise ISO8583Exception.new("Bits < 2 are not permitted (continutation bit is set automatically)")
|
48
|
-
end
|
49
|
-
@bmp[i-1] = (value == true)
|
50
|
-
end
|
51
|
-
|
52
76
|
# Sets bit #i
|
53
77
|
def set(i)
|
78
|
+
if additional_bitmap?
|
79
|
+
raise ISO8583Exception, "field #{i} shouldn't be set (continuation bit is set automatically)" if i % bitmap_size == 1
|
80
|
+
end
|
81
|
+
|
82
|
+
if i > bitmap_size
|
83
|
+
raise ISO8583Exception, "can't set field #{i}, bitmap_size == #{bitmap_size}" unless additional_bitmap?
|
84
|
+
|
85
|
+
quo = i / bitmap_size
|
86
|
+
rem = i % bitmap_size
|
87
|
+
@bitmaps = rem > 0 ? quo + 1 : quo
|
88
|
+
new_bmp = Array.new(@bitmaps * bitmap_size, false)
|
89
|
+
@bmp.each_with_index { |v, idx| new_bmp[idx] = v }
|
90
|
+
0.upto(@bitmaps - 2) do |pos|
|
91
|
+
new_bmp[pos * bitmap_size] = true
|
92
|
+
end
|
93
|
+
@bmp = new_bmp
|
94
|
+
end
|
54
95
|
self[i] = true
|
55
96
|
end
|
56
97
|
|
98
|
+
def size_in_bits
|
99
|
+
bitmaps * bitmap_size
|
100
|
+
end
|
101
|
+
|
102
|
+
def size_in_bytes
|
103
|
+
size_in_bits / 8
|
104
|
+
end
|
105
|
+
|
106
|
+
def size_in_bytes_hex
|
107
|
+
size_in_bytes * 2
|
108
|
+
end
|
109
|
+
|
57
110
|
# Unsets bit #i
|
58
111
|
def unset(i)
|
59
112
|
self[i] = false
|
@@ -64,13 +117,13 @@ module ISO8583
|
|
64
117
|
if RUBY_ENGINE == 'mruby'
|
65
118
|
# Convert binary to hex, by slicing the binary in 4 bytes chuncks
|
66
119
|
bitmap_hex = ""
|
67
|
-
str = ""
|
120
|
+
str = String.new("", encoding: 'ASCII-8BIT')
|
68
121
|
self.to_s.chars.reverse.each_with_index do |ch, i|
|
69
122
|
str << ch
|
70
123
|
next if i == 0
|
71
124
|
if (i+1) % 4 == 0
|
72
125
|
bitmap_hex << str.reverse.to_i(2).to_s(16)
|
73
|
-
str = ""
|
126
|
+
str = String.new("", encoding: 'ASCII-8BIT')
|
74
127
|
end
|
75
128
|
end
|
76
129
|
unless str.empty?
|
@@ -78,29 +131,20 @@ module ISO8583
|
|
78
131
|
end
|
79
132
|
bitmap_hex.reverse.upcase
|
80
133
|
else
|
81
|
-
[to_s].pack("B*")
|
134
|
+
[to_s].pack("B*")
|
82
135
|
end
|
83
136
|
end
|
84
137
|
alias_method :to_b, :to_bytes
|
85
138
|
|
86
139
|
def to_hex
|
87
|
-
|
88
|
-
if value.respond_to? :force_encoding
|
89
|
-
value.force_encoding('UTF-8')
|
90
|
-
else
|
91
|
-
value
|
92
|
-
end
|
140
|
+
self.to_s.to_i(2).to_s(16).upcase.ljust(size_in_bytes_hex, '0')
|
93
141
|
end
|
94
142
|
|
95
143
|
# Generate a String representation of this bitmap in the form:
|
96
144
|
# 01001100110000011010110110010100100110011000001101011011001010
|
97
145
|
def to_s
|
98
|
-
|
99
|
-
|
100
|
-
high, @bmp[0] = ret ? [128, true] : [64, false]
|
101
|
-
|
102
|
-
str = ""
|
103
|
-
1.upto(high) do|i|
|
146
|
+
str = String.new("", encoding: "ASCII-8BIT")
|
147
|
+
1.upto(size_in_bits) do |i|
|
104
148
|
str << (self[i] ? '1' : '0')
|
105
149
|
end
|
106
150
|
|
@@ -110,6 +154,12 @@ module ISO8583
|
|
110
154
|
|
111
155
|
private
|
112
156
|
|
157
|
+
# Set the bit to the indicated value. Only `true` sets the
|
158
|
+
# bit, any other value unsets it.
|
159
|
+
def []=(i, value)
|
160
|
+
@bmp[i-1] = (value == true)
|
161
|
+
end
|
162
|
+
|
113
163
|
def convert_hex_to_binary(str)
|
114
164
|
str.chars.reverse.inject("") do |string, ch|
|
115
165
|
string + ch.to_i(16).to_s(2).rjust(4, "0").reverse
|
@@ -118,40 +168,30 @@ module ISO8583
|
|
118
168
|
|
119
169
|
def initialize_from_message(message)
|
120
170
|
bmp = if hex_bitmap?
|
121
|
-
|
171
|
+
slice_range = (bitmap_size * 2) / 8 - 1
|
172
|
+
rjust(convert_hex_to_binary(message[0..slice_range]), bitmap_size, '0')
|
122
173
|
else
|
123
|
-
message.unpack("
|
174
|
+
message.unpack("B#{bitmap_size}")[0]
|
124
175
|
end
|
125
176
|
|
126
|
-
if
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
177
|
+
if additional_bitmap?
|
178
|
+
has_next_bitmap = bmp[0] == "1"
|
179
|
+
while has_next_bitmap
|
180
|
+
@bitmaps += 1
|
181
|
+
bmp = if hex_bitmap?
|
182
|
+
slice_range = (bitmap_size * bitmaps * 2) / 8 - 1
|
183
|
+
rjust(convert_hex_to_binary(message[0..slice_range]), bitmap_size * bitmaps, '0')
|
184
|
+
else
|
185
|
+
message.unpack("B#{bitmap_size * bitmaps}")[0]
|
186
|
+
end
|
187
|
+
has_next_bitmap = bmp[bitmap_size * (bitmaps - 1)] == "1"
|
188
|
+
end
|
132
189
|
end
|
133
190
|
|
134
191
|
0.upto(bmp.length-1) do |i|
|
135
192
|
@bmp[i] = (bmp[i,1] == "1")
|
136
193
|
end
|
137
194
|
end
|
138
|
-
|
139
|
-
class << self
|
140
|
-
# Parse the bytes in string and return the Bitmap and bytes remaining in `str`
|
141
|
-
# after the bitmap is taken away.
|
142
|
-
def parse(str, hex_bitmap = false)
|
143
|
-
bmp = Bitmap.new(str, hex_bitmap)
|
144
|
-
|
145
|
-
rest = if bmp.hex_bitmap?
|
146
|
-
bmp[1] ? str[32, str.length] : str[16, str.length]
|
147
|
-
else
|
148
|
-
bmp[1] ? str[16, str.length] : str[8, str.length]
|
149
|
-
end
|
150
|
-
|
151
|
-
[ bmp, rest ]
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
195
|
end
|
156
196
|
end
|
157
197
|
|
data/lib/iso8583/codec.rb
CHANGED
@@ -106,11 +106,11 @@ module ISO8583
|
|
106
106
|
Packed_Number.encoder = lambda { |val|
|
107
107
|
val = val.to_s
|
108
108
|
val = val.length % 2 == 0 ? val : "0"+val
|
109
|
-
raise ISO8583Exception.new("Invalid value: #{val} must be numeric!") unless val =~ /^[0-
|
110
|
-
[val].pack("H*")
|
109
|
+
raise ISO8583Exception.new("Invalid value: #{val} must be numeric!") unless val =~ /^[0-9A-Fa-f]*$/
|
110
|
+
String.new([val].pack("H*"), encoding: "ASCII-8BIT")
|
111
111
|
}
|
112
112
|
Packed_Number.decoder = lambda{|encoded|
|
113
|
-
|
113
|
+
encoded.unpack("H*")[0].to_i
|
114
114
|
}
|
115
115
|
|
116
116
|
A_Codec = Codec.new
|
data/lib/iso8583/field.rb
CHANGED
@@ -72,7 +72,7 @@ module ISO8583
|
|
72
72
|
when Integer
|
73
73
|
raise ISO8583Exception.new("Too long: #{value} (#{name})! length=#{length}") if encoded_value.length > length
|
74
74
|
raise ISO8583Exception.new("Too short: #{value} (#{name})! length=#{length}") if encoded_value.length < length
|
75
|
-
""
|
75
|
+
String.new("", encoding: 'ASCII-8BIT')
|
76
76
|
when Field
|
77
77
|
raise ISO8583Exception.new("Max lenth exceeded: #{value}, max: #{max}") if max && encoded_value.length > max
|
78
78
|
length.encode(encoded_value.length)
|
@@ -85,11 +85,46 @@ module ISO8583
|
|
85
85
|
end
|
86
86
|
|
87
87
|
class BCDField < Field
|
88
|
+
attr_accessor :data_length
|
89
|
+
attr_accessor :byte_length
|
88
90
|
# This corrects the length for BCD fields, as their encoded length is half (+ parity) of the
|
89
91
|
# content length. E.g. 123 (length = 3) encodes to "\x01\x23" (length 2)
|
90
92
|
def length
|
91
|
-
|
92
|
-
|
93
|
+
@byte_length
|
94
|
+
end
|
95
|
+
|
96
|
+
def encode(value)
|
97
|
+
begin
|
98
|
+
encoded_value = codec.encode(value)
|
99
|
+
@data_length = value.size
|
100
|
+
@byte_length = encoded_value.bytes.size
|
101
|
+
rescue ISO8583Exception => e
|
102
|
+
ContextLog.exception(e, e.backtrace, "#{e.message} (#{name})") if Object.const_defined?(:ContextLog)
|
103
|
+
raise ISO8583Exception.new(e.message+" (#{name})")
|
104
|
+
end
|
105
|
+
|
106
|
+
if padding
|
107
|
+
if padding.arity == 1
|
108
|
+
encoded_value = padding.call(encoded_value)
|
109
|
+
elsif padding.arity == 2
|
110
|
+
encoded_value = padding.call(encoded_value, length)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
len_str = case length
|
115
|
+
when Integer
|
116
|
+
raise ISO8583Exception.new("Too long: #{value} (#{name})! length=#{length}") if encoded_value.length > length
|
117
|
+
raise ISO8583Exception.new("Too short: #{value} (#{name})! length=#{length}") if encoded_value.length < length
|
118
|
+
String.new("", encoding: 'ASCII-8BIT')
|
119
|
+
when Field
|
120
|
+
raise ISO8583Exception.new("Max length exceeded: #{value}, max: #{max}") if max && @byte_length > max
|
121
|
+
length.encode(@data_length)
|
122
|
+
else
|
123
|
+
raise ISO8583Exception.new("Invalid length (#{length}) for '#{name}' field")
|
124
|
+
end
|
125
|
+
|
126
|
+
len_str + encoded_value
|
127
|
+
|
93
128
|
end
|
94
129
|
end
|
95
130
|
|
data/lib/iso8583/fields.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
# this distribution
|
5
5
|
#++
|
6
6
|
|
7
|
+
require_relative '../da_funk/helper'
|
8
|
+
|
7
9
|
module ISO8583
|
8
10
|
include DaFunk::Helper
|
9
11
|
|
@@ -16,7 +18,7 @@ module ISO8583
|
|
16
18
|
# The following fields are available:
|
17
19
|
#
|
18
20
|
# [+LL+] special form to de/encode variable length indicators, two bytes ASCII numerals
|
19
|
-
# [+LLL+] special form to de/encode variable length indicators,
|
21
|
+
# [+LLL+] special form to de/encode variable length indicators, three bytes ASCII numerals
|
20
22
|
# [+LL_BCD+] special form to de/encode variable length indicators, two BCD digits
|
21
23
|
# [+LLVAR_N+] two byte variable length ASCII numeral, payload ASCII numerals
|
22
24
|
# [+LLLVAR_N+] three byte variable length ASCII numeral, payload ASCII numerals
|
data/lib/iso8583/message.rb
CHANGED
@@ -117,9 +117,16 @@ module ISO8583
|
|
117
117
|
# ISO8583 allows hex or binary bitmap, so it should be configurable
|
118
118
|
attr_reader :use_hex_bitmap
|
119
119
|
|
120
|
+
# ignore_mti allow use of Message without mti. Useful for fields with variable subfields
|
121
|
+
attr_reader :ignore_mti
|
122
|
+
|
123
|
+
# bitmap_size define the size of bitmap to be used, in number of bits.
|
124
|
+
# It should be a multiple of 8 (a byte of 8 bits)
|
125
|
+
attr_reader :bitmap_size
|
126
|
+
|
120
127
|
# Instantiate a new instance of this type of Message
|
121
128
|
# optionally specifying an mti.
|
122
|
-
def initialize(mti = nil, use_hex_bitmap = false)
|
129
|
+
def initialize(mti = nil, use_hex_bitmap = false, ignore_mti = false, bitmap_size = 64)
|
123
130
|
# values is an internal field used to collect all the
|
124
131
|
# bmp number | bmp name | field en/decoders | values
|
125
132
|
# which are set in this message.
|
@@ -127,7 +134,8 @@ module ISO8583
|
|
127
134
|
|
128
135
|
self.mti = mti if mti
|
129
136
|
@use_hex_bitmap = use_hex_bitmap
|
130
|
-
|
137
|
+
@ignore_mti = ignore_mti
|
138
|
+
@bitmap_size = bitmap_size
|
131
139
|
end
|
132
140
|
|
133
141
|
# Set the mti of the Message using either the actual value
|
@@ -143,7 +151,9 @@ module ISO8583
|
|
143
151
|
# mes = MyMessage.new
|
144
152
|
# mes.mti = 1100 # or mes.mti = "Authorization Request Acquirer Gateway"
|
145
153
|
def mti=(value)
|
146
|
-
|
154
|
+
raise ISO8583Exception.new "can't set MTI when `ignore_mti` is set" if ignore_mti
|
155
|
+
|
156
|
+
num, _ = _get_mti_definition(value)
|
147
157
|
@mti = num
|
148
158
|
end
|
149
159
|
|
@@ -180,9 +190,12 @@ module ISO8583
|
|
180
190
|
|
181
191
|
# Retrieve the byte representation of the bitmap.
|
182
192
|
def to_b
|
183
|
-
raise ISO8583Exception.new "no MTI set!"
|
184
|
-
|
185
|
-
|
193
|
+
raise ISO8583Exception.new "no MTI set!" if !(ignore_mti || mti)
|
194
|
+
|
195
|
+
return _body.join if ignore_mti
|
196
|
+
|
197
|
+
mti_enc = self.class._mti_format.encode(mti)
|
198
|
+
mti_enc << _body.join
|
186
199
|
end
|
187
200
|
|
188
201
|
# Returns a nicely formatted representation of this
|
@@ -209,12 +222,12 @@ module ISO8583
|
|
209
222
|
# Returns an array of two byte arrays:
|
210
223
|
# [bitmap_bytes, message_bytes]
|
211
224
|
def _body
|
212
|
-
bitmap = Bitmap.new
|
213
|
-
message = ""
|
225
|
+
bitmap = Bitmap.new(nil, use_hex_bitmap, bitmap_size)
|
226
|
+
message = String.new("", encoding: 'ASCII-8BIT')
|
214
227
|
@values.keys.sort.each do |bmp_num|
|
215
228
|
bitmap.set(bmp_num)
|
216
229
|
enc_value = @values[bmp_num].encode
|
217
|
-
message << enc_value
|
230
|
+
message << enc_value
|
218
231
|
end
|
219
232
|
|
220
233
|
if use_hex_bitmap
|
@@ -356,12 +369,12 @@ module ISO8583
|
|
356
369
|
end
|
357
370
|
|
358
371
|
# Parse the bytes `str` returning a message of the defined type.
|
359
|
-
def parse(str, use_hex_bitmap = false)
|
360
|
-
message = self.new(nil, use_hex_bitmap)
|
372
|
+
def parse(str, use_hex_bitmap = false, bitmap_size = 64)
|
373
|
+
message = self.new(nil, use_hex_bitmap, false, bitmap_size)
|
361
374
|
|
362
375
|
message.mti, rest = _mti_format.parse(str)
|
363
376
|
|
364
|
-
bmp, rest = Bitmap.parse(rest, use_hex_bitmap)
|
377
|
+
bmp, rest = Bitmap.parse(rest, use_hex_bitmap, bitmap_size)
|
365
378
|
|
366
379
|
bmp.each {|bit|
|
367
380
|
bmp_def = _definitions[bit]
|
data/lib/iso8583/util.rb
CHANGED
@@ -0,0 +1,277 @@
|
|
1
|
+
require_relative 'minitest_helper'
|
2
|
+
|
3
|
+
module ISO8583
|
4
|
+
class TestBitmap < Minitest::Test
|
5
|
+
def test_parse_with_hex_bitmap_without_additional_bitmap
|
6
|
+
message = "7020000000008000165432123456789876000000000000001500986"
|
7
|
+
hex_bitmap = true
|
8
|
+
bitmap_size = 64
|
9
|
+
|
10
|
+
bitmap, _ = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
11
|
+
|
12
|
+
expect = "7020000000008000"
|
13
|
+
assert_equal(expect, bitmap.to_hex)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_parse_with_bin_bitmap_without_additional_bitmap
|
17
|
+
message = String.new("\x70\x20\x00\x00\x00\x00\x80\x00165432123456789876000000000000001500986", encoding: "ASCII-8BIT")
|
18
|
+
hex_bitmap = false
|
19
|
+
bitmap_size = 64
|
20
|
+
|
21
|
+
bitmap, _ = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
22
|
+
|
23
|
+
expect = String.new("\x70\x20\x00\x00\x00\x00\x80\x00", encoding: "ASCII-8BIT")
|
24
|
+
assert_equal(expect, bitmap.to_bytes)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_parse_with_hex_bitmap_having_one_additional_bitmap
|
28
|
+
message = "F02000000000800000000000000000021654321234567898760000000000000015009860a53ec23-8f0b-4328-a51f-b9202dad7b8b"
|
29
|
+
hex_bitmap = true
|
30
|
+
bitmap_size = 64
|
31
|
+
|
32
|
+
bitmap, _ = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
33
|
+
|
34
|
+
expect = "F0200000000080000000000000000002"
|
35
|
+
assert_equal(expect, bitmap.to_hex)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_parse_with_bin_bitmap_having_one_additional_bitmap
|
39
|
+
message = String.new("\xF0\x20\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x021654321234567898760000000000000015009860a53ec23-8f0b-4328-a51f-b9202dad7b8b", encoding: 'ASCII-8BIT')
|
40
|
+
hex_bitmap = false
|
41
|
+
bitmap_size = 64
|
42
|
+
|
43
|
+
bitmap, _ = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
44
|
+
|
45
|
+
expect = String.new("\xF0\x20\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x02", encoding: "ASCII-8BIT")
|
46
|
+
assert_equal(expect, bitmap.to_bytes)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_parse_with_hex_bitmap_having_more_additionals_bitmap
|
50
|
+
message = "808002blablabla"
|
51
|
+
hex_bitmap = true
|
52
|
+
bitmap_size = 8
|
53
|
+
|
54
|
+
bitmap, _ = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
55
|
+
|
56
|
+
expect = "808002"
|
57
|
+
assert_equal(expect, bitmap.to_hex)
|
58
|
+
assert_equal(true, bitmap[23])
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_parse_returning_remainder_of_message_small_bitmap_size
|
62
|
+
message = "40blablabla"
|
63
|
+
hex_bitmap = true
|
64
|
+
bitmap_size = 8
|
65
|
+
|
66
|
+
_, rest = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
67
|
+
|
68
|
+
expect = "blablabla"
|
69
|
+
assert_equal(expect, rest)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_parse_returning_remainder_of_message_usual_bitmap_size
|
73
|
+
message = "4000000000000000foobarbaz"
|
74
|
+
hex_bitmap = true
|
75
|
+
bitmap_size = 64
|
76
|
+
|
77
|
+
_, rest = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
78
|
+
|
79
|
+
expect = "foobarbaz"
|
80
|
+
assert_equal(expect, rest)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_parse_returning_remainder_of_message_big_bitmap_size
|
84
|
+
message = "40000000000000000000000000000000bazbarfoo"
|
85
|
+
hex_bitmap = true
|
86
|
+
bitmap_size = 128
|
87
|
+
|
88
|
+
_, rest = Bitmap.parse(message, hex_bitmap, bitmap_size)
|
89
|
+
|
90
|
+
expect = "bazbarfoo"
|
91
|
+
assert_equal(expect, rest)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_raises_on_wrong_bitmap_size
|
95
|
+
e = assert_raises { Bitmap.new(nil, false, 1) }
|
96
|
+
assert_equal(ISO8583Exception, e.class)
|
97
|
+
assert_equal('wrong bitmap_size: 1', e.message)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_set_and_get_value
|
101
|
+
bitmap = Bitmap.new(nil, false, 8)
|
102
|
+
bitmap.set(2)
|
103
|
+
assert_equal(true, bitmap[2])
|
104
|
+
assert_equal(false, bitmap[1])
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_avoid_set_bit_greater_than_size
|
108
|
+
bitmap = Bitmap.new(nil, false, 8, false)
|
109
|
+
e = assert_raises { bitmap.set(9) }
|
110
|
+
assert_equal(ISO8583Exception, e.class)
|
111
|
+
assert_equal("can't set field 9, bitmap_size == 8", e.message)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_allow_set_bit_1_when_no_has_additional_bitmap
|
115
|
+
bitmap = Bitmap.new(nil, false, 8, false)
|
116
|
+
bitmap.set(1)
|
117
|
+
assert_equal(true, bitmap[1])
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_avoid_set_bit_1_when_has_additional_bitmap
|
121
|
+
bitmap = Bitmap.new(nil, false, 8, true)
|
122
|
+
e = assert_raises { bitmap.set(1) }
|
123
|
+
assert_equal(ISO8583Exception, e.class)
|
124
|
+
assert_equal("field 1 shouldn't be set (continuation bit is set automatically)", e.message)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_set_continuation_bit
|
128
|
+
bitmap = Bitmap.new(nil, false, 8, true)
|
129
|
+
bitmap.set(20)
|
130
|
+
assert_equal(true, bitmap[1])
|
131
|
+
assert_equal(true, bitmap[9])
|
132
|
+
assert_equal(false, bitmap[17])
|
133
|
+
assert_equal(true, bitmap[20])
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_set_continuation_bit_with_bitmap_size_of_64
|
137
|
+
bitmap = Bitmap.new(nil, false, 64, true)
|
138
|
+
bitmap.set(180)
|
139
|
+
assert_equal(true, bitmap[1])
|
140
|
+
assert_equal(true, bitmap[65])
|
141
|
+
assert_equal(false, bitmap[129])
|
142
|
+
assert_equal(true, bitmap[180])
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_unset_field
|
146
|
+
bitmap = Bitmap.new(nil, false, 8, false)
|
147
|
+
assert_equal(false, bitmap[1])
|
148
|
+
bitmap.set(1)
|
149
|
+
assert_equal(true, bitmap[1])
|
150
|
+
bitmap.unset(1)
|
151
|
+
assert_equal(false, bitmap[1])
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_to_s_bitmap_size_8_bits
|
155
|
+
bitmap = Bitmap.new(nil, false, 8, false)
|
156
|
+
bitmap.set(2)
|
157
|
+
bitmap.set(7)
|
158
|
+
|
159
|
+
assert_equal('01000010', bitmap.to_s)
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_to_s_bitmap_size_8_bits_having_additional_bitmap
|
163
|
+
bitmap = Bitmap.new(nil, false, 8, true)
|
164
|
+
bitmap.set(2)
|
165
|
+
bitmap.set(10)
|
166
|
+
|
167
|
+
assert_equal('1100000001000000', bitmap.to_s)
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_to_s_bitmap_size_64_bits
|
171
|
+
bitmap = Bitmap.new(nil, false, 64, true)
|
172
|
+
bitmap.set(2)
|
173
|
+
bitmap.set(3)
|
174
|
+
bitmap.set(7)
|
175
|
+
bitmap.set(11)
|
176
|
+
bitmap.set(39)
|
177
|
+
|
178
|
+
assert_equal('0110001000100000000000000000000000000010000000000000000000000000', bitmap.to_s)
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_to_s_bitmap_size_64_bits_having_additional_bitmap
|
182
|
+
bitmap = Bitmap.new(nil, false, 64, true)
|
183
|
+
bitmap.set(2)
|
184
|
+
bitmap.set(3)
|
185
|
+
bitmap.set(7)
|
186
|
+
bitmap.set(11)
|
187
|
+
bitmap.set(39)
|
188
|
+
bitmap.set(127)
|
189
|
+
|
190
|
+
assert_equal('11100010001000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000010', bitmap.to_s)
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_to_hex_without_fields
|
194
|
+
bitmap = Bitmap.new(nil, true, 8, true)
|
195
|
+
|
196
|
+
expected = "00"
|
197
|
+
assert_equal(expected, bitmap.to_hex)
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_to_hex_with_many_fields
|
201
|
+
bitmap = Bitmap.new(nil, true, 64, true)
|
202
|
+
bitmap.set(2)
|
203
|
+
bitmap.set(3)
|
204
|
+
bitmap.set(4)
|
205
|
+
bitmap.set(5)
|
206
|
+
bitmap.set(6)
|
207
|
+
bitmap.set(7)
|
208
|
+
bitmap.set(8)
|
209
|
+
bitmap.set(66)
|
210
|
+
|
211
|
+
expected = "FF000000000000004000000000000000"
|
212
|
+
|
213
|
+
assert_equal(expected, bitmap.to_hex)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_to_b_bitmap_size_8
|
217
|
+
bitmap = Bitmap.new(nil, false, 8, false)
|
218
|
+
bitmap.set(2)
|
219
|
+
bitmap.set(3)
|
220
|
+
bitmap.set(4)
|
221
|
+
bitmap.set(5)
|
222
|
+
bitmap.set(6)
|
223
|
+
bitmap.set(7)
|
224
|
+
|
225
|
+
expected = String.new("\x7E", encoding: 'ASCII-8BIT')
|
226
|
+
|
227
|
+
assert_equal(expected, bitmap.to_b)
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_to_b_bitmap_size_8_having_additional_bitmap
|
231
|
+
bitmap = Bitmap.new(nil, false, 8, true)
|
232
|
+
bitmap.set(2)
|
233
|
+
bitmap.set(3)
|
234
|
+
bitmap.set(4)
|
235
|
+
bitmap.set(5)
|
236
|
+
bitmap.set(6)
|
237
|
+
bitmap.set(7)
|
238
|
+
bitmap.set(11)
|
239
|
+
|
240
|
+
expected = String.new("\xFE\x20", encoding: 'ASCII-8BIT')
|
241
|
+
|
242
|
+
assert_equal(expected, bitmap.to_b)
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_to_b_bitmap_size_64
|
246
|
+
bitmap = Bitmap.new(nil, false, 64, false)
|
247
|
+
bitmap.set(2)
|
248
|
+
bitmap.set(3)
|
249
|
+
bitmap.set(4)
|
250
|
+
bitmap.set(5)
|
251
|
+
bitmap.set(6)
|
252
|
+
bitmap.set(7)
|
253
|
+
bitmap.set(8)
|
254
|
+
bitmap.set(64)
|
255
|
+
|
256
|
+
expected = String.new("\x7F\x00\x00\x00\x00\x00\x00\x01", encoding: 'ASCII-8BIT')
|
257
|
+
|
258
|
+
assert_equal(expected, bitmap.to_b)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_to_b_bitmap_size_64_having_additional_bitmap
|
262
|
+
bitmap = Bitmap.new(nil, false, 64, true)
|
263
|
+
bitmap.set(2)
|
264
|
+
bitmap.set(3)
|
265
|
+
bitmap.set(4)
|
266
|
+
bitmap.set(5)
|
267
|
+
bitmap.set(6)
|
268
|
+
bitmap.set(7)
|
269
|
+
bitmap.set(8)
|
270
|
+
bitmap.set(66)
|
271
|
+
|
272
|
+
expected = String.new("\xFF\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00", encoding: 'ASCII-8BIT')
|
273
|
+
|
274
|
+
assert_equal(expected, bitmap.to_b)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|