libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers scalar_codec.cpp Source File

scalar_codec.cpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <gtest/gtest.h>
00006 #include <limits>
00007 #include <uavcan/marshal/scalar_codec.hpp>
00008 #include <uavcan/transport/transfer_buffer.hpp>
00009 
00010 
00011 TEST(ScalarCodec, Basic)
00012 {
00013     uavcan::StaticTransferBuffer<38> buf;
00014     uavcan::BitStream bs_wr(buf);
00015     uavcan::ScalarCodec sc_wr(bs_wr);
00016 
00017     {
00018         uint64_t u64 = 0;
00019         ASSERT_EQ(0, sc_wr.decode<64>(u64));    // Out of buffer space
00020     }
00021 
00022     /*
00023      * Encoding some variables
00024      */
00025     ASSERT_EQ(1, sc_wr.encode<12>(uint16_t(0xbeda)));    // --> 0xeda
00026     ASSERT_EQ(1, sc_wr.encode<1>(uint8_t(1)));
00027     ASSERT_EQ(1, sc_wr.encode<1>(uint16_t(0)));
00028     ASSERT_EQ(1, sc_wr.encode<4>(uint8_t(8)));
00029     ASSERT_EQ(1, sc_wr.encode<32>(uint32_t(0xdeadbeef)));
00030     ASSERT_EQ(1, sc_wr.encode<3>(int8_t(-1)));
00031     ASSERT_EQ(1, sc_wr.encode<4>(int8_t(-6)));
00032     ASSERT_EQ(1, sc_wr.encode<20>(int32_t(-123456)));
00033     ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<int64_t>::min()));
00034     ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<int64_t>::max()));
00035     ASSERT_EQ(1, sc_wr.encode<15>(int16_t(-1)));
00036     ASSERT_EQ(1, sc_wr.encode<2>(int16_t(-1)));
00037     ASSERT_EQ(1, sc_wr.encode<16>(std::numeric_limits<int16_t>::min()));
00038     ASSERT_EQ(1, sc_wr.encode<64>(std::numeric_limits<uint64_t>::max())); // Total 302 bit (38 bytes)
00039 
00040     ASSERT_EQ(0, sc_wr.encode<64>(std::numeric_limits<uint64_t>::min())); // Out of buffer space
00041 
00042     /*
00043      * Decoding back
00044      */
00045     uavcan::BitStream bs_rd(buf);
00046     uavcan::ScalarCodec sc_rd(bs_rd);
00047 
00048     uint8_t u8   = 0;
00049     int8_t i8    = 0;
00050     uint16_t u16 = 0;
00051     int16_t i16  = 0;
00052     uint32_t u32 = 0;
00053     int32_t i32  = 0;
00054     uint64_t u64 = 0;
00055     int64_t i64  = 0;
00056 
00057 #define CHECK(bitlen, variable, expected_value) \
00058     do { \
00059         ASSERT_EQ(1, sc_rd.decode<bitlen>(variable)); \
00060         ASSERT_EQ(expected_value, variable); \
00061     } while (0)
00062 
00063     CHECK(12, u16, 0xeda);
00064     CHECK(1,  u8,  1);
00065     CHECK(1,  u16, 0);
00066     CHECK(4,  u8,  8);
00067     CHECK(32, u32, 0xdeadbeef);
00068     CHECK(3,  i8,  -1);
00069     CHECK(4,  i8,  -6);
00070     CHECK(20, i32, -123456);
00071     CHECK(64, i64, std::numeric_limits<int64_t>::min());
00072     CHECK(64, i64, std::numeric_limits<int64_t>::max());
00073     CHECK(15, i16, -1);
00074     CHECK(2,  i8,  -1);
00075     CHECK(16, i16, std::numeric_limits<int16_t>::min());
00076     CHECK(64, u64, std::numeric_limits<uint64_t>::max());
00077 
00078 #undef CHECK
00079 
00080     ASSERT_EQ(0, sc_rd.decode<64>(u64)); // Out of buffer space
00081 }
00082 
00083 TEST(ScalarCodec, RepresentationCorrectness)
00084 {
00085     uavcan::StaticTransferBuffer<4> buf;
00086     uavcan::BitStream bs_wr(buf);
00087     uavcan::ScalarCodec sc_wr(bs_wr);
00088 
00089     ASSERT_EQ(1, sc_wr.encode<12>(uint16_t(0xbeda)));    // --> 0xeda
00090     ASSERT_EQ(1, sc_wr.encode<3>(int8_t(-1)));
00091     ASSERT_EQ(1, sc_wr.encode<4>(int8_t(-5)));
00092     ASSERT_EQ(1, sc_wr.encode<2>(int16_t(-1)));
00093     ASSERT_EQ(1, sc_wr.encode<4>(uint8_t(0x88)));        // --> 8
00094 
00095     // This representation was carefully crafted and triple checked:
00096     static const std::string REFERENCE = "11011010 11101111 01111100 00000000";
00097     ASSERT_EQ(REFERENCE, bs_wr.toString());
00098 }