Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bit_stream.cpp Source File

bit_stream.cpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <gtest/gtest.h>
00006 #include <uavcan/marshal/bit_stream.hpp>
00007 #include <uavcan/transport/transfer_buffer.hpp>
00008 
00009 
00010 TEST(BitStream, ToString)
00011 {
00012     {
00013         uavcan::StaticTransferBuffer<8> buf;
00014         uavcan::BitStream bs(buf);
00015         ASSERT_EQ("", bs.toString());
00016         ASSERT_EQ("", bs.toString());
00017     }
00018     {
00019         const uint8_t data[] = {0xad};   // 10101101
00020         uavcan::StaticTransferBuffer<8> buf;
00021         uavcan::BitStream bs(buf);
00022         ASSERT_EQ(1, bs.write(data, 8)); // all 8
00023         ASSERT_EQ("10101101", bs.toString());
00024     }
00025     {
00026         const uint8_t data[] = {0xad, 0xbe};  // 10101101 10111110
00027         uavcan::StaticTransferBuffer<8> buf;
00028         uavcan::BitStream bs(buf);
00029         ASSERT_EQ(1, bs.write(data, 16));     // all 16
00030         ASSERT_EQ("10101101 10111110", bs.toString());
00031     }
00032     {
00033         const uint8_t data[] = {0xad, 0xbe, 0xfc};  // 10101101 10111110 11111100
00034         uavcan::StaticTransferBuffer<8> buf;
00035         uavcan::BitStream bs(buf);
00036         ASSERT_EQ(1, bs.write(data, 20));           // 10101101 10111110 1111
00037         ASSERT_EQ("10101101 10111110 11110000", bs.toString());
00038     }
00039 }
00040 
00041 
00042 TEST(BitStream, BitOrderSimple)
00043 {
00044     /*
00045      * a = 1010
00046      * b = 1011
00047      * c = 1100
00048      * d = 1101
00049      * e = 1110
00050      * f = 1111
00051      */
00052     uavcan::StaticTransferBuffer<32> buf;
00053     {   // Write
00054         const uint8_t data[] = {0xad, 0xbe};            // adbe
00055         uavcan::BitStream bs(buf);
00056         ASSERT_EQ(1, bs.write(data, 12));               // adb0
00057         ASSERT_EQ("10101101 10110000", bs.toString());  // adb0
00058     }
00059     {   // Read
00060         uavcan::BitStream bs(buf);
00061         ASSERT_EQ("10101101 10110000", bs.toString());  // Same data
00062         uint8_t data[] = {0xFF, 0xFF};                  // Uninitialized
00063         ASSERT_EQ(1, bs.read(data, 12));
00064         ASSERT_EQ(0xad, data[0]);
00065         ASSERT_EQ(0xb0, data[1]);
00066     }
00067 }
00068 
00069 
00070 TEST(BitStream, BitOrderComplex)
00071 {
00072     static const std::string REFERENCE =
00073         "10101101 10111111 11101111 01010110 11011111 01000100 10001101 00010101 10011110 00100110 10101111 00110111 10111100 00000100";
00074 
00075     uavcan::StaticTransferBuffer<32> buf;
00076     {   // Write
00077         const uint8_t data1[] = {0xad, 0xbe};              // 10101101 10111110
00078         const uint8_t data2[] = {0xfc};                    // 11111100
00079         const uint8_t data3[] = {0xde, 0xad, 0xbe, 0xef};  // 11011110 10101101 10111110 11101111
00080         const uint8_t data4[] = {0x12, 0x34, 0x56, 0x78,   // 00010010 00110100 01010110 01111000
00081                                  0x9a, 0xbc, 0xde, 0xf0};  // 10011010 10111100 11011110 11110000
00082 
00083         uavcan::BitStream bs(buf);
00084         ASSERT_EQ(1, bs.write(data1, 11));  // 10101101 101
00085         std::cout << bs.toString() << std::endl;
00086         ASSERT_EQ(1, bs.write(data2, 6));   //             11111 1
00087         std::cout << bs.toString() << std::endl;
00088         ASSERT_EQ(1, bs.write(data3, 25));  //                    1101111 01010110 11011111 01
00089         std::cout << bs.toString() << std::endl;
00090         ASSERT_EQ(1, bs.write(data4, 64));  // all 64, total 42 + 64 = 106
00091         std::cout << bs.toString() << std::endl;
00092         ASSERT_EQ(1, bs.write(data4, 4));   // 0001
00093         std::cout << bs.toString() << std::endl;
00094 
00095         std::cout << "Reference:\n" << REFERENCE << std::endl;
00096 
00097         ASSERT_EQ(REFERENCE, bs.toString());
00098     }
00099     {   // Read back in the same order
00100         uint8_t data[8];
00101         std::fill(data, data + sizeof(data), 0xA5);    // Filling with garbage
00102         uavcan::BitStream bs(buf);
00103         ASSERT_EQ(REFERENCE, bs.toString());
00104 
00105         ASSERT_EQ(1, bs.read(data, 11));     // 10101101 10100000
00106         ASSERT_EQ(0xad, data[0]);
00107         ASSERT_EQ(0xa0, data[1]);
00108 
00109         ASSERT_EQ(1, bs.read(data, 6));      // 11111100
00110         ASSERT_EQ(0xfc, data[0]);
00111 
00112         ASSERT_EQ(1, bs.read(data, 25));     // 11011110 10101101 10111110 10000000
00113         ASSERT_EQ(0xde, data[0]);
00114         ASSERT_EQ(0xad, data[1]);
00115         ASSERT_EQ(0xbe, data[2]);
00116         ASSERT_EQ(0x80, data[3]);
00117 
00118         ASSERT_EQ(1, bs.read(data, 64));     // Data - see above
00119         ASSERT_EQ(0x12, data[0]);
00120         ASSERT_EQ(0x34, data[1]);
00121         ASSERT_EQ(0x56, data[2]);
00122         ASSERT_EQ(0x78, data[3]);
00123         ASSERT_EQ(0x9a, data[4]);
00124         ASSERT_EQ(0xbc, data[5]);
00125         ASSERT_EQ(0xde, data[6]);
00126         ASSERT_EQ(0xf0, data[7]);
00127     }
00128 }
00129 
00130 
00131 TEST(BitStream, BitByBit)
00132 {
00133     static const int NUM_BYTES = 1024;
00134     uavcan::StaticTransferBuffer<NUM_BYTES> buf;
00135     uavcan::BitStream bs_wr(buf);
00136 
00137     std::string binary_string;
00138     unsigned counter = 0;
00139     for (int byte = 0; byte < NUM_BYTES; byte++)
00140     {
00141         for (int bit = 0; bit < 8; bit++, counter++)
00142         {
00143             const bool value = counter % 3 == 0;
00144             binary_string.push_back(value ? '1' : '0');
00145             const uint8_t data[] = { uint8_t(value << 7) };
00146             ASSERT_EQ(1, bs_wr.write(data, 1));
00147         }
00148         binary_string.push_back(' ');
00149     }
00150     binary_string.erase(binary_string.length() - 1, 1);
00151 
00152     /*
00153      * Currently we have no free buffer space, so next write() must fail
00154      */
00155     const uint8_t dummy_data_wr[] = { 0xFF };
00156     ASSERT_EQ(0, bs_wr.write(dummy_data_wr, 1));
00157 
00158     /*
00159      * Bitstream content validation
00160      */
00161 //    std::cout << bs.toString() << std::endl;
00162 //    std::cout << "Reference:\n" << binary_string << std::endl;
00163     ASSERT_EQ(binary_string, bs_wr.toString());
00164 
00165     /*
00166      * Read back
00167      */
00168     uavcan::BitStream bs_rd(buf);
00169     counter = 0;
00170     for (int byte = 0; byte < NUM_BYTES; byte++)
00171     {
00172         for (int bit = 0; bit < 8; bit++, counter++)
00173         {
00174             const bool value = counter % 3 == 0;
00175             uint8_t data[1];
00176             ASSERT_EQ(1, bs_rd.read(data, 1));
00177             if (value)
00178             {
00179                 ASSERT_EQ(0x80, data[0]);
00180             }
00181             else
00182             {
00183                 ASSERT_EQ(0, data[0]);
00184             }
00185         }
00186     }
00187 
00188     /*
00189      * Making sure that reading out of buffer range will fail with error
00190      */
00191     uint8_t dummy_data_rd[] = { 0xFF };
00192     ASSERT_EQ(0, bs_wr.read(dummy_data_rd, 1));
00193     ASSERT_EQ(0xFF, dummy_data_rd[0]);
00194 }