1*103e46e4SHarish Mahendrakar // Copyright (c) 2016 The WebM project authors. All Rights Reserved. 2*103e46e4SHarish Mahendrakar // 3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license 4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source 5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found 6*103e46e4SHarish Mahendrakar // in the file PATENTS. All contributing project authors may 7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree. 8*103e46e4SHarish Mahendrakar #ifndef SRC_BLOCK_PARSER_H_ 9*103e46e4SHarish Mahendrakar #define SRC_BLOCK_PARSER_H_ 10*103e46e4SHarish Mahendrakar 11*103e46e4SHarish Mahendrakar #include <cassert> 12*103e46e4SHarish Mahendrakar #include <cstdint> 13*103e46e4SHarish Mahendrakar #include <type_traits> 14*103e46e4SHarish Mahendrakar #include <vector> 15*103e46e4SHarish Mahendrakar 16*103e46e4SHarish Mahendrakar #include "src/block_header_parser.h" 17*103e46e4SHarish Mahendrakar #include "src/element_parser.h" 18*103e46e4SHarish Mahendrakar #include "src/var_int_parser.h" 19*103e46e4SHarish Mahendrakar #include "webm/callback.h" 20*103e46e4SHarish Mahendrakar #include "webm/dom_types.h" 21*103e46e4SHarish Mahendrakar #include "webm/element.h" 22*103e46e4SHarish Mahendrakar #include "webm/reader.h" 23*103e46e4SHarish Mahendrakar #include "webm/status.h" 24*103e46e4SHarish Mahendrakar 25*103e46e4SHarish Mahendrakar namespace webm { 26*103e46e4SHarish Mahendrakar 27*103e46e4SHarish Mahendrakar // Parses Block and SimpleBlock elements. It is recommended to use the 28*103e46e4SHarish Mahendrakar // BlockParser and SimpleBlockParser aliases. 29*103e46e4SHarish Mahendrakar // Spec reference: 30*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#Block 31*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#SimpleBlock 32*103e46e4SHarish Mahendrakar // http://www.webmproject.org/docs/container/#SimpleBlock 33*103e46e4SHarish Mahendrakar // http://www.webmproject.org/docs/container/#Block 34*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#block_structure 35*103e46e4SHarish Mahendrakar // http://matroska.org/technical/specs/index.html#simpleblock_structure 36*103e46e4SHarish Mahendrakar template <typename T> 37*103e46e4SHarish Mahendrakar class BasicBlockParser : public ElementParser { 38*103e46e4SHarish Mahendrakar static_assert(std::is_same<T, Block>::value || 39*103e46e4SHarish Mahendrakar std::is_same<T, SimpleBlock>::value, 40*103e46e4SHarish Mahendrakar "T must be Block or SimpleBlock"); 41*103e46e4SHarish Mahendrakar 42*103e46e4SHarish Mahendrakar public: 43*103e46e4SHarish Mahendrakar Status Init(const ElementMetadata& metadata, std::uint64_t max_size) override; 44*103e46e4SHarish Mahendrakar 45*103e46e4SHarish Mahendrakar Status Feed(Callback* callback, Reader* reader, 46*103e46e4SHarish Mahendrakar std::uint64_t* num_bytes_read) override; 47*103e46e4SHarish Mahendrakar 48*103e46e4SHarish Mahendrakar bool WasSkipped() const override; 49*103e46e4SHarish Mahendrakar 50*103e46e4SHarish Mahendrakar // Gets the parsed block header information. The frames are not included. This 51*103e46e4SHarish Mahendrakar // must not be called until the parse has been successfully completed. value()52*103e46e4SHarish Mahendrakar const T& value() const { 53*103e46e4SHarish Mahendrakar assert(state_ == State::kDone); 54*103e46e4SHarish Mahendrakar return value_; 55*103e46e4SHarish Mahendrakar } 56*103e46e4SHarish Mahendrakar 57*103e46e4SHarish Mahendrakar // Gets the parsed block header information. The frames are not included. This 58*103e46e4SHarish Mahendrakar // must not be called until the parse has been successfully completed. mutable_value()59*103e46e4SHarish Mahendrakar T* mutable_value() { 60*103e46e4SHarish Mahendrakar assert(state_ == State::kDone); 61*103e46e4SHarish Mahendrakar return &value_; 62*103e46e4SHarish Mahendrakar } 63*103e46e4SHarish Mahendrakar 64*103e46e4SHarish Mahendrakar private: 65*103e46e4SHarish Mahendrakar // The number of header bytes read (header meaning everything before the 66*103e46e4SHarish Mahendrakar // frames). 67*103e46e4SHarish Mahendrakar std::uint64_t header_bytes_read_ = 0; 68*103e46e4SHarish Mahendrakar 69*103e46e4SHarish Mahendrakar // The parsed header value for the element. 70*103e46e4SHarish Mahendrakar T value_{}; 71*103e46e4SHarish Mahendrakar 72*103e46e4SHarish Mahendrakar // Metadata for the frame that is currently being read. 73*103e46e4SHarish Mahendrakar FrameMetadata frame_metadata_; 74*103e46e4SHarish Mahendrakar 75*103e46e4SHarish Mahendrakar // Parser for parsing header metadata that is common between Block and 76*103e46e4SHarish Mahendrakar // SimpleBlock. 77*103e46e4SHarish Mahendrakar BlockHeaderParser header_parser_; 78*103e46e4SHarish Mahendrakar 79*103e46e4SHarish Mahendrakar // Parser for parsing unsigned EBML variable-sized integers. 80*103e46e4SHarish Mahendrakar VarIntParser uint_parser_; 81*103e46e4SHarish Mahendrakar 82*103e46e4SHarish Mahendrakar // The current lace size when parsing Xiph lace sizes. 83*103e46e4SHarish Mahendrakar std::uint64_t xiph_lace_size_ = 0; 84*103e46e4SHarish Mahendrakar 85*103e46e4SHarish Mahendrakar // Lace (frame) sizes, where each entry represents the size of a frame. 86*103e46e4SHarish Mahendrakar std::vector<std::uint64_t> lace_sizes_; 87*103e46e4SHarish Mahendrakar 88*103e46e4SHarish Mahendrakar // The current index into lace_sizes_ for the current frame being read. 89*103e46e4SHarish Mahendrakar std::size_t current_lace_ = 0; 90*103e46e4SHarish Mahendrakar 91*103e46e4SHarish Mahendrakar // Parsing states for the finite-state machine. 92*103e46e4SHarish Mahendrakar enum class State { 93*103e46e4SHarish Mahendrakar /* clang-format off */ 94*103e46e4SHarish Mahendrakar // State Transitions to state When 95*103e46e4SHarish Mahendrakar kReadingHeader, // kGettingAction no lacing 96*103e46e4SHarish Mahendrakar // kReadingLaceCount yes lacing 97*103e46e4SHarish Mahendrakar kReadingLaceCount, // kGettingAction no errors 98*103e46e4SHarish Mahendrakar kGettingAction, // kSkipping action == skip 99*103e46e4SHarish Mahendrakar // kValidatingSize no lacing 100*103e46e4SHarish Mahendrakar // kReadingXiphLaceSizes xiph lacing 101*103e46e4SHarish Mahendrakar // kReadingFirstEbmlLaceSize ebml lacing 102*103e46e4SHarish Mahendrakar // kCalculatingFixedLaceSizes fixed lacing 103*103e46e4SHarish Mahendrakar kReadingXiphLaceSizes, // kValidatingSize all sizes read 104*103e46e4SHarish Mahendrakar kReadingFirstEbmlLaceSize, // kReadingEbmlLaceSizes first size read 105*103e46e4SHarish Mahendrakar kReadingEbmlLaceSizes, // kValidatingSize all sizes read 106*103e46e4SHarish Mahendrakar kCalculatingFixedLaceSizes, // kReadingFrames no errors 107*103e46e4SHarish Mahendrakar kValidatingSize, // kReadingFrames no errors 108*103e46e4SHarish Mahendrakar kSkipping, // No transitions from here (must call Init) 109*103e46e4SHarish Mahendrakar kReadingFrames, // kDone all frames read 110*103e46e4SHarish Mahendrakar kDone, // No transitions from here (must call Init) 111*103e46e4SHarish Mahendrakar /* clang-format on */ 112*103e46e4SHarish Mahendrakar }; 113*103e46e4SHarish Mahendrakar 114*103e46e4SHarish Mahendrakar // The current state of the parser. 115*103e46e4SHarish Mahendrakar State state_ = State::kReadingHeader; 116*103e46e4SHarish Mahendrakar }; 117*103e46e4SHarish Mahendrakar 118*103e46e4SHarish Mahendrakar extern template class BasicBlockParser<Block>; 119*103e46e4SHarish Mahendrakar extern template class BasicBlockParser<SimpleBlock>; 120*103e46e4SHarish Mahendrakar 121*103e46e4SHarish Mahendrakar using BlockParser = BasicBlockParser<Block>; 122*103e46e4SHarish Mahendrakar using SimpleBlockParser = BasicBlockParser<SimpleBlock>; 123*103e46e4SHarish Mahendrakar 124*103e46e4SHarish Mahendrakar } // namespace webm 125*103e46e4SHarish Mahendrakar 126*103e46e4SHarish Mahendrakar #endif // SRC_BLOCK_PARSER_H_ 127