Class: ISO8583::Field

Inherits:
Object
  • Object
show all
Defined in:
lib/iso8583/field.rb

Direct Known Subclasses

BCDField

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#bmpObject

Returns the value of attribute bmp.



14
15
16
# File 'lib/iso8583/field.rb', line 14

def bmp
  @bmp
end

#codecObject

Returns the value of attribute codec.



9
10
11
# File 'lib/iso8583/field.rb', line 9

def codec
  @codec
end

#lengthObject

may either be some other Field in which the length is encoded or a Fixnum for fixed length fields. Length should always be the length of the encoded value. A 6 digit BCD field will require a length 3, as will a 5 digit BCD field. The subclass BCDField handles this to keep things consistant.



8
9
10
# File 'lib/iso8583/field.rb', line 8

def length
  @length
end

#maxObject

Returns the value of attribute max.



11
12
13
# File 'lib/iso8583/field.rb', line 11

def max
  @max
end

#nameObject



16
17
18
# File 'lib/iso8583/field.rb', line 16

def name
  "BMP #{bmp}: #{@name}"
end

#paddingObject

Returns the value of attribute padding.



10
11
12
# File 'lib/iso8583/field.rb', line 10

def padding
  @padding
end

Instance Method Details

#encode(value) ⇒ Object

Encoding needs to consider length representation, the actual encoding (such as charset or BCD) and padding. The order may be important! This impl calls codec.encode and then pads, in case you need the other special treatment, you may need to override this method alltogether. In other cases, the padding has to be implemented by the codec, such as BCD with an odd number of nibbles.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/iso8583/field.rb', line 54

def encode(value)
  begin
    encoded_value = codec.encode(value) 
  rescue ISO8583Exception
    raise ISO8583Exception.new($!.message+" (#{name})")
  end

  if padding
    if padding.arity == 1
      encoded_value = padding.call(encoded_value)
    elsif padding.arity == 2
      encoded_value = padding.call(encoded_value, length)
    end
  end

  len_str = case length
            when Fixnum
              raise ISO8583Exception.new("Too long: #{value} (#{name})! length=#{length}")  if encoded_value.length > length
              raise ISO8583Exception.new("Too short: #{value} (#{name})! length=#{length}") if encoded_value.length < length
              "" 
            when Field
              raise ISO8583Exception.new("Max lenth exceeded: #{value}, max: #{max}") if max && encoded_value.length > max
              length.encode(encoded_value.length)
            else
              raise ISO8583Exception.new("Invalid length (#{length}) for '#{name}' field")
            end

  len_str + encoded_value
end

#parse(raw) ⇒ Object



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
# File 'lib/iso8583/field.rb', line 20

def parse(raw)
  len, raw = case length
             when Fixnum
               [length, raw]
             when Field
               length.parse(raw)
             else
               raise ISO8583Exception.new("Cannot determine the length of '#{name}' field")
             end

  raw_value = raw[0,len]
  
  # make sure we have enough data ...
  if raw_value.length != len
    mes = "Field has incorrect length! field: #{raw_value} len/expected: #{raw_value.length}/#{len}"
    raise ISO8583ParseException.new(mes)
  end

  rest = raw[len, raw.length]
  begin
    real_value = codec.decode(raw_value)
  rescue
    raise ISO8583ParseException.new($!.message+" (#{name})")
  end

  [ real_value, rest ]
end