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