#!/usr/bin/env ruby
# Unit tests for BinAnalysis::Decode::Num

require 'test/unit'

require "bin-analysis/decode/num"

class TC_DocMgrTest < Test::Unit::TestCase

  def get_data_for_params( arr, signed, endian, offset )
    arr.select { |h| h[:signed] == signed && h[:endian] == endian &&
                     h[:offset] == offset }.first[:data]
  end

  # 1-byte (char)
  def test_byte
    arr = [0,1,2,3,4,5,126,127,128,129,251,252,252,254,255]
    buf = arr.pack 'C*'
    rv = BinAnalysis::Decode::Num.every_byte(buf).first[:data]
    assert_equal(arr, rv)

    arr = [-128, -127,-126,-125,-5,-4,-3,-2,-1,0,1,2,3,4,5,126,127]
    buf = arr.pack 'c*'
    rv = BinAnalysis::Decode::Num.every_byte(buf).last[:data]
    assert_equal(arr, rv)
  end

  # 2-byte (short)
  def test_hword
    # unsigned little endian
    arr = [0,1,2,3,4,5,32766,32767,32768,32769,65533,65534,65535]
    buf = arr.pack 'S<*'
    rv = BinAnalysis::Decode::Num.every_two_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, false, :little, 0) )
    arr1 = [256,512,768,1024,1280,65024,65407,127,384,64896,65279,65535] 
    assert_equal(arr1, get_data_for_params(rv, false, :little, 1) )

    # unsigned big endian
    buf = arr.pack 'S>*'
    rv = BinAnalysis::Decode::Num.every_two_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, false, :big, 0) )
    arr1 = [0,256,512,768,1024,1407,65151,65408,128,511,65023,65279]
    assert_equal(arr1, get_data_for_params(rv, false, :big, 1) )

    # signed little endian
    arr = [-32768,-32767,-32766,0,1,2,3,4,5,32765,32766,32767]
    buf = arr.pack 's<*'
    rv = BinAnalysis::Decode::Num.every_two_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, true, :little, 0) )
    arr1 = [384, 640, 128, 256, 512, 768, 1024, 1280, -768, -385, -129]
    assert_equal(arr1, get_data_for_params(rv, true, :little, 1) )

    # signed big endian
    buf = arr.pack 's>*'
    rv = BinAnalysis::Decode::Num.every_two_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, true, :big, 0) )
    arr1 = [128, 384, 512, 0, 256, 512, 768, 1024, 1407, -641, -385]
    assert_equal(arr1, get_data_for_params(rv, true, :big, 1) )
  end

  # 4-byte (int)
  def test_word
    # unsigned little endian
    arr = [0,1,2,3,4,5,2147483647,2147483648,2147483649,4294967294,4294967295]
    buf = arr.pack 'L<*'
    rv = BinAnalysis::Decode::Num.every_four_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, false, :little, 0) )
    arr1 = [16777216, 33554432, 50331648, 67108864, 83886080, 4278190080, 8388607, 25165824, 4269801472, 4294967295]
    assert_equal(arr1, get_data_for_params(rv, false, :little, 1) )
    arr1 = [65536, 131072, 196608, 262144, 327680, 4294901760, 32767, 98304, 4294868992, 4294967295]
    assert_equal(arr1, get_data_for_params(rv, false, :little, 2) )
    arr1 = [256, 512, 768, 1024, 1280, 4294967040, 127, 384, 4294966912, 4294967295]
    assert_equal(arr1, get_data_for_params(rv, false, :little, 3) )

    # unsigned big endian
    buf = arr.pack 'L>*'
    rv = BinAnalysis::Decode::Num.every_four_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, false, :big, 0) )
    arr1 = [0, 256, 512, 768, 1024, 1407, 4294967168, 128, 511, 4294967039]
    assert_equal(arr1, get_data_for_params(rv, false, :big, 1) )
    arr1 = [0, 65536, 131072, 196608, 262144, 360447, 4294934528, 32768, 131071, 4294901759]
    assert_equal(arr1, get_data_for_params(rv, false, :big, 2) )
    arr1 = [0, 16777216, 33554432, 50331648, 67108864, 92274687, 4286578688, 8388608, 33554431, 4278190079]
    assert_equal(arr1, get_data_for_params(rv, false, :big, 3) )

    # signed little endian
    arr = [-2147483648,-2147483647,-2,-1,0,1,2,3,4,5,2147483646,2147483647]
    buf = arr.pack 'l<*'
    rv = BinAnalysis::Decode::Num.every_four_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, true, :little, 0) )
    arr1 = [25165824, -25165824, -1, 16777215, 16777216, 33554432, 50331648, 67108864, 83886080, -33554432, -8388609]
    assert_equal(arr1, get_data_for_params(rv, true, :little, 1) )
    arr1 = [98304, -98304, -1, 65535, 65536, 131072, 196608, 262144, 327680, -131072, -32769]
    assert_equal(arr1, get_data_for_params(rv, true, :little, 2) )
    arr1 = [384, -384, -1, 255, 256, 512, 768, 1024, 1280, -512, -129]
    assert_equal(arr1, get_data_for_params(rv, true, :little, 3) )

    # signed big endian
    buf = arr.pack 'l>*'
    rv = BinAnalysis::Decode::Num.every_four_bytes(buf)
    assert_equal(arr, get_data_for_params(rv, true, :big, 0) )
    arr1 = [128, 511, -257, -256, 0, 256, 512, 768, 1024, 1407, -385]
    assert_equal(arr1, get_data_for_params(rv, true, :big, 1) )
    arr1 = [32768, 131071, -65537, -65536, 0, 65536, 131072, 196608, 262144, 360447, -98305]
    assert_equal(arr1, get_data_for_params(rv, true, :big, 2) )
    arr1 = [8388608, 33554431, -16777217, -16777216, 0, 16777216, 33554432, 50331648, 67108864, 92274687, -25165825]
    assert_equal(arr1, get_data_for_params(rv, true, :big, 3) )
  end

  def test_dword
  end

  def test_float
  end
end
