Skip to content

Commit

Permalink
MIN/MAX support all bit sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
jmthomas committed May 4, 2016
1 parent abc88c7 commit c393f15
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 9 deletions.
51 changes: 47 additions & 4 deletions lib/cosmos/packets/parsers/packet_item_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,18 @@ def get_range

index = append? ? 3 : 4
min = @parser.parameters[index].convert_to_value
min = "MIN_#{get_data_type}#{get_bit_size}" if min == 'MIN'
min = ConfigParser.handle_defined_constants(min)
if min == 'MIN'
min = calculate_range_value(:min)
else
min = ConfigParser.handle_defined_constants(min)
end
max = @parser.parameters[index+1].convert_to_value
max = "MAX_#{get_data_type}#{get_bit_size}" if max == 'MAX'
ConfigParser.handle_defined_constants(min)..ConfigParser.handle_defined_constants(max)
if max == 'MAX'
max = calculate_range_value(:max)
else
max = ConfigParser.handle_defined_constants(max)
end
min..max
end

def get_default
Expand Down Expand Up @@ -216,5 +223,41 @@ def id_usage
end
end

private

def calculate_range_value(type)
data_type = get_data_type()
bit_size = get_bit_size()
value = 0 # Default for UINT minimum

case data_type
when :INT
if type == :min
value = -2**(bit_size-1)
else # :max
value = 2**(bit_size-1) - 1
end
when :UINT
# Default is 0 for :min
if type == :max
value = 2**bit_size - 1
end
when :FLOAT
case bit_size
when 32
value = 3.402823e38
value *= -1 if type == :min
when 64
value = Float::MAX
value *= -1 if type == :min
else
raise @parser.error("Invalid bit size #{bit_size} for FLOAT type.", @usage)
end
else
raise @parser.error("Invalid data type #{data_type} when calculating range.", @usage)
end
value
end

end
end # module Cosmos
39 changes: 34 additions & 5 deletions spec/packets/parsers/packet_item_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,19 +209,48 @@ module Cosmos

it "automatically sets range using MIN MAX range contants" do
%w(UINT INT FLOAT).each do |type|
[8,16,32,64].each do |size|
next if type == 'FLOAT' && size < 32
(1..64).each do |size|
next if type == 'FLOAT' && (size != 32 || size != 64)
tf = Tempfile.new('unittest')
tf.puts 'COMMAND tgt1 pkt1 LITTLE_ENDIAN "Description"'
tf.puts 'COMMAND tgt1 pkt1 BIG_ENDIAN "Description"'
tf.puts " PARAMETER ITEM 0 #{size} #{type} MIN MAX 0 \"Description\""
tf.close
@pc.process_file(tf.path, "TGT1")
item = @pc.commands["TGT1"]["PKT1"].get_item("ITEM")
expect(item.range.min).to eq ConfigParser.handle_defined_constants("MIN_#{type}#{size}")
expect(item.range.max).to eq ConfigParser.handle_defined_constants("MAX_#{type}#{size}")
case type
when 'UINT'
min = 0
max = 2**size - 1
when 'INT'
min = -2**(size-1)
max = 2**(size-1) - 1
when 'FLOAT'
if size == 32
min = -3.402823e38
max = 3.402823e38
else
min = -Float::MAX
max = Float::MAX
end
end
expect(item.range.min).to eq min
expect(item.range.max).to eq max
tf.unlink
end
end

# Run special test for NEG_INFINITY and POS_INFINITY
[32, 64].each do |size|
tf = Tempfile.new('unittest')
tf.puts 'COMMAND tgt1 pkt1 BIG_ENDIAN "Description"'
tf.puts " PARAMETER ITEM 0 #{size} FLOAT NEG_INFINITY POS_INFINITY 0 \"Description\""
tf.close
@pc.process_file(tf.path, "TGT1")
item = @pc.commands["TGT1"]["PKT1"].get_item("ITEM")
expect(item.range.min).to eq -Float::INFINITY
expect(item.range.max).to eq Float::INFINITY
tf.unlink
end
end

it "supports arbitrary range, default and endianness per item" do
Expand Down

0 comments on commit c393f15

Please sign in to comment.