bit_stream.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <gtest/gtest.h>
  5. #include <uavcan/marshal/bit_stream.hpp>
  6. #include <uavcan/transport/transfer_buffer.hpp>
  7. TEST(BitStream, ToString)
  8. {
  9. {
  10. uavcan::StaticTransferBuffer<8> buf;
  11. uavcan::BitStream bs(buf);
  12. ASSERT_EQ("", bs.toString());
  13. ASSERT_EQ("", bs.toString());
  14. }
  15. {
  16. const uint8_t data[] = {0xad}; // 10101101
  17. uavcan::StaticTransferBuffer<8> buf;
  18. uavcan::BitStream bs(buf);
  19. ASSERT_EQ(1, bs.write(data, 8)); // all 8
  20. ASSERT_EQ("10101101", bs.toString());
  21. }
  22. {
  23. const uint8_t data[] = {0xad, 0xbe}; // 10101101 10111110
  24. uavcan::StaticTransferBuffer<8> buf;
  25. uavcan::BitStream bs(buf);
  26. ASSERT_EQ(1, bs.write(data, 16)); // all 16
  27. ASSERT_EQ("10101101 10111110", bs.toString());
  28. }
  29. {
  30. const uint8_t data[] = {0xad, 0xbe, 0xfc}; // 10101101 10111110 11111100
  31. uavcan::StaticTransferBuffer<8> buf;
  32. uavcan::BitStream bs(buf);
  33. ASSERT_EQ(1, bs.write(data, 20)); // 10101101 10111110 1111
  34. ASSERT_EQ("10101101 10111110 11110000", bs.toString());
  35. }
  36. }
  37. TEST(BitStream, BitOrderSimple)
  38. {
  39. /*
  40. * a = 1010
  41. * b = 1011
  42. * c = 1100
  43. * d = 1101
  44. * e = 1110
  45. * f = 1111
  46. */
  47. uavcan::StaticTransferBuffer<32> buf;
  48. { // Write
  49. const uint8_t data[] = {0xad, 0xbe}; // adbe
  50. uavcan::BitStream bs(buf);
  51. ASSERT_EQ(1, bs.write(data, 12)); // adb0
  52. ASSERT_EQ("10101101 10110000", bs.toString()); // adb0
  53. }
  54. { // Read
  55. uavcan::BitStream bs(buf);
  56. ASSERT_EQ("10101101 10110000", bs.toString()); // Same data
  57. uint8_t data[] = {0xFF, 0xFF}; // Uninitialized
  58. ASSERT_EQ(1, bs.read(data, 12));
  59. ASSERT_EQ(0xad, data[0]);
  60. ASSERT_EQ(0xb0, data[1]);
  61. }
  62. }
  63. TEST(BitStream, BitOrderComplex)
  64. {
  65. static const std::string REFERENCE =
  66. "10101101 10111111 11101111 01010110 11011111 01000100 10001101 00010101 10011110 00100110 10101111 00110111 10111100 00000100";
  67. uavcan::StaticTransferBuffer<32> buf;
  68. { // Write
  69. const uint8_t data1[] = {0xad, 0xbe}; // 10101101 10111110
  70. const uint8_t data2[] = {0xfc}; // 11111100
  71. const uint8_t data3[] = {0xde, 0xad, 0xbe, 0xef}; // 11011110 10101101 10111110 11101111
  72. const uint8_t data4[] = {0x12, 0x34, 0x56, 0x78, // 00010010 00110100 01010110 01111000
  73. 0x9a, 0xbc, 0xde, 0xf0}; // 10011010 10111100 11011110 11110000
  74. uavcan::BitStream bs(buf);
  75. ASSERT_EQ(1, bs.write(data1, 11)); // 10101101 101
  76. std::cout << bs.toString() << std::endl;
  77. ASSERT_EQ(1, bs.write(data2, 6)); // 11111 1
  78. std::cout << bs.toString() << std::endl;
  79. ASSERT_EQ(1, bs.write(data3, 25)); // 1101111 01010110 11011111 01
  80. std::cout << bs.toString() << std::endl;
  81. ASSERT_EQ(1, bs.write(data4, 64)); // all 64, total 42 + 64 = 106
  82. std::cout << bs.toString() << std::endl;
  83. ASSERT_EQ(1, bs.write(data4, 4)); // 0001
  84. std::cout << bs.toString() << std::endl;
  85. std::cout << "Reference:\n" << REFERENCE << std::endl;
  86. ASSERT_EQ(REFERENCE, bs.toString());
  87. }
  88. { // Read back in the same order
  89. uint8_t data[8];
  90. std::fill(data, data + sizeof(data), 0xA5); // Filling with garbage
  91. uavcan::BitStream bs(buf);
  92. ASSERT_EQ(REFERENCE, bs.toString());
  93. ASSERT_EQ(1, bs.read(data, 11)); // 10101101 10100000
  94. ASSERT_EQ(0xad, data[0]);
  95. ASSERT_EQ(0xa0, data[1]);
  96. ASSERT_EQ(1, bs.read(data, 6)); // 11111100
  97. ASSERT_EQ(0xfc, data[0]);
  98. ASSERT_EQ(1, bs.read(data, 25)); // 11011110 10101101 10111110 10000000
  99. ASSERT_EQ(0xde, data[0]);
  100. ASSERT_EQ(0xad, data[1]);
  101. ASSERT_EQ(0xbe, data[2]);
  102. ASSERT_EQ(0x80, data[3]);
  103. ASSERT_EQ(1, bs.read(data, 64)); // Data - see above
  104. ASSERT_EQ(0x12, data[0]);
  105. ASSERT_EQ(0x34, data[1]);
  106. ASSERT_EQ(0x56, data[2]);
  107. ASSERT_EQ(0x78, data[3]);
  108. ASSERT_EQ(0x9a, data[4]);
  109. ASSERT_EQ(0xbc, data[5]);
  110. ASSERT_EQ(0xde, data[6]);
  111. ASSERT_EQ(0xf0, data[7]);
  112. }
  113. }
  114. TEST(BitStream, BitByBit)
  115. {
  116. static const int NUM_BYTES = 1024;
  117. uavcan::StaticTransferBuffer<NUM_BYTES> buf;
  118. uavcan::BitStream bs_wr(buf);
  119. std::string binary_string;
  120. unsigned counter = 0;
  121. for (int byte = 0; byte < NUM_BYTES; byte++)
  122. {
  123. for (int bit = 0; bit < 8; bit++, counter++)
  124. {
  125. const bool value = counter % 3 == 0;
  126. binary_string.push_back(value ? '1' : '0');
  127. const uint8_t data[] = { uint8_t(value << 7) };
  128. ASSERT_EQ(1, bs_wr.write(data, 1));
  129. }
  130. binary_string.push_back(' ');
  131. }
  132. binary_string.erase(binary_string.length() - 1, 1);
  133. /*
  134. * Currently we have no free buffer space, so next write() must fail
  135. */
  136. const uint8_t dummy_data_wr[] = { 0xFF };
  137. ASSERT_EQ(0, bs_wr.write(dummy_data_wr, 1));
  138. /*
  139. * Bitstream content validation
  140. */
  141. // std::cout << bs.toString() << std::endl;
  142. // std::cout << "Reference:\n" << binary_string << std::endl;
  143. ASSERT_EQ(binary_string, bs_wr.toString());
  144. /*
  145. * Read back
  146. */
  147. uavcan::BitStream bs_rd(buf);
  148. counter = 0;
  149. for (int byte = 0; byte < NUM_BYTES; byte++)
  150. {
  151. for (int bit = 0; bit < 8; bit++, counter++)
  152. {
  153. const bool value = counter % 3 == 0;
  154. uint8_t data[1];
  155. ASSERT_EQ(1, bs_rd.read(data, 1));
  156. if (value)
  157. {
  158. ASSERT_EQ(0x80, data[0]);
  159. }
  160. else
  161. {
  162. ASSERT_EQ(0, data[0]);
  163. }
  164. }
  165. }
  166. /*
  167. * Making sure that reading out of buffer range will fail with error
  168. */
  169. uint8_t dummy_data_rd[] = { 0xFF };
  170. ASSERT_EQ(0, bs_wr.read(dummy_data_rd, 1));
  171. ASSERT_EQ(0xFF, dummy_data_rd[0]);
  172. }