scalar_codec.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <gtest/gtest.h>
  5. #include <limits>
  6. #include <uavcan/marshal/scalar_codec.hpp>
  7. #include <uavcan/transport/transfer_buffer.hpp>
  8. TEST(ScalarCodec, Basic)
  9. {
  10. uavcan::StaticTransferBuffer<38> buf;
  11. uavcan::BitStream bs_wr(buf);
  12. uavcan::ScalarCodec sc_wr(bs_wr);
  13. {
  14. uint64_t u64 = 0;
  15. ASSERT_EQ(0, sc_wr.decode<64>(u64)); // Out of buffer space
  16. }
  17. /*
  18. * Encoding some variables
  19. */
  20. ASSERT_EQ(1, sc_wr.encode<12>(uint16_t(0xbeda))); // --> 0xeda
  21. ASSERT_EQ(1, sc_wr.encode<1>(uint8_t(1)));
  22. ASSERT_EQ(1, sc_wr.encode<1>(uint16_t(0)));
  23. ASSERT_EQ(1, sc_wr.encode<4>(uint8_t(8)));
  24. ASSERT_EQ(1, sc_wr.encode<32>(uint32_t(0xdeadbeef)));
  25. ASSERT_EQ(1, sc_wr.encode<3>(int8_t(-1)));
  26. ASSERT_EQ(1, sc_wr.encode<4>(int8_t(-6)));
  27. ASSERT_EQ(1, sc_wr.encode<20>(int32_t(-123456)));
  28. ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<int64_t>::min()));
  29. ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<int64_t>::max()));
  30. ASSERT_EQ(1, sc_wr.encode<15>(int16_t(-1)));
  31. ASSERT_EQ(1, sc_wr.encode<2>(int16_t(-1)));
  32. ASSERT_EQ(1, sc_wr.encode<16>(std::numeric_limits<int16_t>::min()));
  33. ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<uint64_t>::max())); // Total 302 bit (38 bytes)
  34. ASSERT_EQ(0, sc_wr.encode<64>(std::numeric_limits<uint64_t>::min())); // Out of buffer space
  35. /*
  36. * Decoding back
  37. */
  38. uavcan::BitStream bs_rd(buf);
  39. uavcan::ScalarCodec sc_rd(bs_rd);
  40. uint8_t u8 = 0;
  41. int8_t i8 = 0;
  42. uint16_t u16 = 0;
  43. int16_t i16 = 0;
  44. uint32_t u32 = 0;
  45. int32_t i32 = 0;
  46. uint64_t u64 = 0;
  47. int64_t i64 = 0;
  48. #define CHECK(bitlen, variable, expected_value) \
  49. do { \
  50. ASSERT_EQ(1, sc_rd.decode<bitlen>(variable)); \
  51. ASSERT_EQ(expected_value, variable); \
  52. } while (0)
  53. CHECK(12, u16, 0xeda);
  54. CHECK(1, u8, 1);
  55. CHECK(1, u16, 0);
  56. CHECK(4, u8, 8);
  57. CHECK(32, u32, 0xdeadbeef);
  58. CHECK(3, i8, -1);
  59. CHECK(4, i8, -6);
  60. CHECK(20, i32, -123456);
  61. CHECK(64, i64, std::numeric_limits<int64_t>::min());
  62. CHECK(64, i64, std::numeric_limits<int64_t>::max());
  63. CHECK(15, i16, -1);
  64. CHECK(2, i8, -1);
  65. CHECK(16, i16, std::numeric_limits<int16_t>::min());
  66. CHECK(64, u64, std::numeric_limits<uint64_t>::max());
  67. #undef CHECK
  68. ASSERT_EQ(0, sc_rd.decode<64>(u64)); // Out of buffer space
  69. }
  70. TEST(ScalarCodec, RepresentationCorrectness)
  71. {
  72. uavcan::StaticTransferBuffer<4> buf;
  73. uavcan::BitStream bs_wr(buf);
  74. uavcan::ScalarCodec sc_wr(bs_wr);
  75. ASSERT_EQ(1, sc_wr.encode<12>(uint16_t(0xbeda))); // --> 0xeda
  76. ASSERT_EQ(1, sc_wr.encode<3>(int8_t(-1)));
  77. ASSERT_EQ(1, sc_wr.encode<4>(int8_t(-5)));
  78. ASSERT_EQ(1, sc_wr.encode<2>(int16_t(-1)));
  79. ASSERT_EQ(1, sc_wr.encode<4>(uint8_t(0x88))); // --> 8
  80. // This representation was carefully crafted and triple checked:
  81. static const std::string REFERENCE = "11011010 11101111 01111100 00000000";
  82. ASSERT_EQ(REFERENCE, bs_wr.toString());
  83. }