fork download
  1. #include <iostream>
  2. #include <sstream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <iterator>
  6. #include <cstdint>
  7.  
  8. using namespace std;
  9.  
  10. struct TagHeader {
  11. uint16_t tag_code;
  12. uint32_t tag_length;
  13. };
  14.  
  15. static const int bits_per_byte = 8;
  16.  
  17. template<class int_type, class iterator_type>
  18. static int_type parse_int_le(iterator_type& i, iterator_type eof = iterator_type {}) {
  19. std::array<unsigned char, sizeof(int_type)> bytes;
  20. std::copy_n(i, sizeof(bytes), std::begin(bytes));
  21. i++;
  22. int_type value = 0;
  23. for(int byte_offset = sizeof(int_type) - 1; byte_offset >= 0; byte_offset--) {
  24. value |= static_cast<int_type>(bytes[byte_offset]) << byte_offset * bits_per_byte;
  25. }
  26. return value;
  27. }
  28.  
  29. template<class iterator_type>
  30. static TagHeader parse_tag_header(iterator_type& i, iterator_type eof) {
  31. TagHeader h;
  32. auto code_and_length = parse_int_le<uint16_t>(i, eof);
  33. std::cout << "code_and_length = " << code_and_length << "\n";
  34. h.tag_code = (code_and_length & (0xffff << 6)) >> 6; // top 10 bits are tag type
  35. h.tag_length = code_and_length & (0xffff >> 10); // lower 6 bits are length
  36. if(h.tag_length >= 63) {
  37. h.tag_length = parse_int_le<uint32_t>(i, eof);
  38. }
  39. return h;
  40. }
  41. int main() {
  42. {
  43. stringstream sstr;
  44. sstr << "\x8b\x15";
  45. istreambuf_iterator<char> i(sstr);
  46. istreambuf_iterator<char> eof;
  47.  
  48. auto th = parse_tag_header(i, eof);
  49. std::cout << th.tag_length << "\n";
  50. }
  51. std::cout << "\n";
  52. {
  53. stringstream sstr;
  54. sstr << "\x8b\x15";
  55. istreambuf_iterator<char> i(sstr);
  56. istreambuf_iterator<char> eof;
  57.  
  58. std::vector<char> tag_data(2);
  59. std::copy_n(i, 2, tag_data.begin());
  60. i++;
  61.  
  62. auto tag_i = tag_data.begin();
  63. auto tag_eof = tag_data.end();
  64.  
  65. auto th = parse_tag_header(tag_i, tag_eof);
  66. std::cout << th.tag_length << "\n";
  67. }
  68. return 0;
  69. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
code_and_length = 5515
11

code_and_length = 5515
11