Bitstream Interpretation Library (BIL)  0.1
V5BitstreamReader.cpp
Go to the documentation of this file.
1 
11 #include <exception/Exception.hpp>
12 
13 using namespace bil;
14 
15 
16 void V5BitstreamReader::read(Bitstream& bitstream, const boost::uint32_t* words, size_t wordCount)
17 {
18  // reset syntax checker
19  m_syntaxChecker.reset();
20 
21  // load packets one by one
22  std::auto_ptr<Packet> newPacketPtr;
23  while (wordCount > 0)
24  {
25  // try to extract a packet
26  size_t wordAdvance = extractPacket(words, wordCount, newPacketPtr);
27 
28  // check advance
29  if (0 == wordAdvance) throw Exception();
30  else if (wordAdvance > wordCount) throw Exception();
31  // advance in bitstream
32  words += wordAdvance;
33  wordCount -= wordAdvance;
34 
35  // check if packet returned
36  if (0 == newPacketPtr.get()) continue;
37  // do syntax check to know, if packet type is allowed at this state
38  newPacketPtr->accept(m_syntaxChecker);
39  // add packet to bitstream
40  bitstream.append(newPacketPtr);
41  }
42 }
43 
44 
45 size_t V5BitstreamReader::extractPacket(const boost::uint32_t* words, size_t wordCount, std::auto_ptr<Packet>& packetPtr)
46 {
47  // behind sync word: look for type 1 packets, type 2 packets, and dummy
48  // words with value of 0x00000000
49  if (behindSyncWord())
50  {
51  // check if given data words start with a type 1 packet
52  if (0 < isType1Packet(words, wordCount))
53  {
54  packetPtr.reset(new Type1Packet());
55  return readType1Packet(*(static_cast<Type1Packet*>(packetPtr.get())), words, wordCount);
56  }
57  // if directly after a type 1 packet: check if given data words start
58  // with a type 2 packet
59  if ((lastPacketWasType1()) && (0 < isType2Packet(words, wordCount)))
60  {
61  packetPtr.reset(new Type2Packet());
62  return readType2Packet(*(static_cast<Type2Packet*>(packetPtr.get())), words, wordCount);
63  }
64  // check if given data words start with a dummy word of 0x00000000
65  if ((0 < wordCount) && (DummyWord::NULL_WORD == *words))
66  {
67  packetPtr.reset(new DummyWord());
68  (static_cast<DummyWord*>(packetPtr.get()))->value(*words);
69  return 1;
70  }
71  }
72  // in front of sync word: look for buswidth pattern, sync word, and dummy
73  // words with value of 0xffffffff
74  else
75  {
76  // check if given data words start with a dummy word of 0xffffffff
77  if ((0 < wordCount) && (DummyWord::FULL_WORD == *words))
78  {
79  packetPtr.reset(new DummyWord());
80  (static_cast<DummyWord*>(packetPtr.get()))->value(*words);
81  return 1;
82  }
83  // check if given data words start with buswidth pattern
84  size_t packetWordCount = isBuswidthPattern(words, wordCount);
85  if (0 < packetWordCount)
86  {
87  packetPtr.reset(new BuswidthPattern());
88  return packetWordCount;
89  }
90  // check if given data words start with sync word
91  packetWordCount = isSyncWord(words, wordCount);
92  if (0 < packetWordCount)
93  {
94  packetPtr.reset(new SyncWord());
95  return packetWordCount;
96  }
97  }
98 
99  // no matching packet found
100  packetPtr.reset();
101  return 0;
102 }
103 
104 
106 {
107  return m_syntaxChecker.behindSyncWord();
108 }
109 
110 
112 {
113  return m_syntaxChecker.lastPacketWasType1();
114 }
115 
116 
118 {
119  return m_syntaxChecker.lastType1Address();
120 }
121 
122 
123 void bil::readV5Bitstream(Bitstream& bitstream, const boost::uint32_t* words, size_t wordCount)
124 {
125  V5BitstreamReader bsr;
126  bsr.read(bitstream, words, wordCount);
127 }