-
Notifications
You must be signed in to change notification settings - Fork 3
/
ts_reader.hpp
87 lines (74 loc) · 1.96 KB
/
ts_reader.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#ifndef _TSD_TS_READER_HPP_
#define _TSD_TS_READER_HPP_
#include <iostream>
#include <istream>
#include <array>
#include <cstdint>
#include <stdexcept>
#include "util.hpp"
#include "transport_packet.hpp"
namespace tsd
{
class tsreader
{
std::array<char, transport_packet::size> buffer_;
public:
static const size_t max_resync_size = 0xFFFF;
public:
tsreader(std::istream& input) : input_(input) {}
bool next(transport_packet& result) {
while(true) {
input_.exceptions(std::istream::badbit);
input_.read(buffer_.data(), buffer_.size());
if(!input_)
return false;
// check packet sync byte
if(buffer_[0] != transport_packet::sync_byte) {
input_.exceptions(std::istream::failbit | std::istream::badbit);
auto pos = input_.tellg();
input_.seekg(
-std::min<decltype(pos)>(pos, transport_packet::size),
std::ios_base::cur);
if(!resync())
return false;
}
else {
break;
}
}
result.unpack(buffer_.data(), buffer_.size());
return true;
}
std::streampos tellg() {
input_.exceptions(std::istream::failbit | std::istream::badbit);
return input_.tellg();
}
void seekg(
std::streamoff off,
std::ios_base::seekdir way) {
input_.exceptions(std::istream::failbit | std::istream::badbit);
input_.seekg(off, way);
}
private:
bool resync() {
char ch;
const uint8_t* c = reinterpret_cast<uint8_t*>(&ch);
size_t i;
for(i = 0; i < max_resync_size; ++i) {
input_.exceptions(std::istream::badbit);
input_.get(ch);
if(!input_)
return false;
if(*c == transport_packet::sync_byte) {
input_.exceptions(std::istream::failbit | std::istream::badbit);
input_.seekg(-1, std::ios_base::cur);
return true;
}
}
throw std::runtime_error("invalid data. cannot find 0x47 sync byte");
}
private:
std::istream& input_;
};
} // namespace tsd
#endif