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_ELEMENT_PARSER_H_ 9*103e46e4SHarish Mahendrakar #define SRC_ELEMENT_PARSER_H_ 10*103e46e4SHarish Mahendrakar 11*103e46e4SHarish Mahendrakar #include <cassert> 12*103e46e4SHarish Mahendrakar #include <cstdint> 13*103e46e4SHarish Mahendrakar 14*103e46e4SHarish Mahendrakar #include "src/ancestory.h" 15*103e46e4SHarish Mahendrakar #include "src/parser.h" 16*103e46e4SHarish Mahendrakar #include "webm/callback.h" 17*103e46e4SHarish Mahendrakar #include "webm/element.h" 18*103e46e4SHarish Mahendrakar 19*103e46e4SHarish Mahendrakar namespace webm { 20*103e46e4SHarish Mahendrakar 21*103e46e4SHarish Mahendrakar // Parses an element from a WebM byte stream. Objects that implement this 22*103e46e4SHarish Mahendrakar // interface are expected to be used as follows in order to parse the specific 23*103e46e4SHarish Mahendrakar // WebM element that they are designed to handle. 24*103e46e4SHarish Mahendrakar // 25*103e46e4SHarish Mahendrakar // Reader* reader = ...; // Create some Reader. 26*103e46e4SHarish Mahendrakar // Callback* callback = ...; // Create some Callback. 27*103e46e4SHarish Mahendrakar // 28*103e46e4SHarish Mahendrakar // ElementMetadata metadata = { 29*103e46e4SHarish Mahendrakar // id, // Element parsed from the reader. 30*103e46e4SHarish Mahendrakar // header_size, // The number of bytes used to encode the id and size. 31*103e46e4SHarish Mahendrakar // size_in_bytes, // The number of bytes in the element body. 32*103e46e4SHarish Mahendrakar // position, // The position of the element (starting at the ID). 33*103e46e4SHarish Mahendrakar // }; 34*103e46e4SHarish Mahendrakar // 35*103e46e4SHarish Mahendrakar // std::uint64_t max_size = ...; // Some upper bound on this element's size. 36*103e46e4SHarish Mahendrakar // ElementParser* parser = ...; // Create some parser capable of handling 37*103e46e4SHarish Mahendrakar // // elements that match id. 38*103e46e4SHarish Mahendrakar // 39*103e46e4SHarish Mahendrakar // Status status = parser->Init(metadata, max_size); 40*103e46e4SHarish Mahendrakar // if (!status.completed_ok()) { 41*103e46e4SHarish Mahendrakar // // An error occurred. See status.code for the reason. 42*103e46e4SHarish Mahendrakar // } else { 43*103e46e4SHarish Mahendrakar // do { 44*103e46e4SHarish Mahendrakar // std::uint64_t num_bytes_read = 0; 45*103e46e4SHarish Mahendrakar // status = parser->Feed(callback, reader, &num_bytes_read); 46*103e46e4SHarish Mahendrakar // } while (status.code == Status::kOkPartial); 47*103e46e4SHarish Mahendrakar // 48*103e46e4SHarish Mahendrakar // if (status.completed_ok()) { 49*103e46e4SHarish Mahendrakar // // Parsing successfully completed. 50*103e46e4SHarish Mahendrakar // } else { 51*103e46e4SHarish Mahendrakar // // An error occurred. If status.code is a parsing error (see status.h for 52*103e46e4SHarish Mahendrakar // // errors that are considered parsing errors), do not call Feed again; 53*103e46e4SHarish Mahendrakar // // parsing has already failed and further progress can't be made. If 54*103e46e4SHarish Mahendrakar // // status.code is not a parsing error (i.e. Status::kWouldBlock), then 55*103e46e4SHarish Mahendrakar // // Feed may be called again to attempt resuming parsing. 56*103e46e4SHarish Mahendrakar // } 57*103e46e4SHarish Mahendrakar // } 58*103e46e4SHarish Mahendrakar class ElementParser : public Parser { 59*103e46e4SHarish Mahendrakar public: 60*103e46e4SHarish Mahendrakar // Initializes the parser and prepares it for parsing its element. Returns 61*103e46e4SHarish Mahendrakar // Status::kOkCompleted if successful. Must not return Status::kOkPartial (it 62*103e46e4SHarish Mahendrakar // is not resumable). metadata is the metadata associated with this element. 63*103e46e4SHarish Mahendrakar // max_size must be <= metadata.size (unless metadata.size is 64*103e46e4SHarish Mahendrakar // kUnknownElementSize). 65*103e46e4SHarish Mahendrakar virtual Status Init(const ElementMetadata& metadata, 66*103e46e4SHarish Mahendrakar std::uint64_t max_size) = 0; 67*103e46e4SHarish Mahendrakar 68*103e46e4SHarish Mahendrakar // Initializes the parser after a seek was done and prepares it for parsing. 69*103e46e4SHarish Mahendrakar // The reader is now at the position of the child element indicated by 70*103e46e4SHarish Mahendrakar // child_metadata, whose ancestory is child_ancestory. The child element for 71*103e46e4SHarish Mahendrakar // this parser is the first element in child_ancestory, or if that is empty, 72*103e46e4SHarish Mahendrakar // then child_metadata itself. If the child is not a valid child of this 73*103e46e4SHarish Mahendrakar // parser, then a debug assertion is made (because that indicates a bug). InitAfterSeek(const Ancestory &,const ElementMetadata &)74*103e46e4SHarish Mahendrakar virtual void InitAfterSeek(const Ancestory& /* child_ancestory */, 75*103e46e4SHarish Mahendrakar const ElementMetadata& /* child_metadata */) { 76*103e46e4SHarish Mahendrakar assert(false); 77*103e46e4SHarish Mahendrakar } 78*103e46e4SHarish Mahendrakar 79*103e46e4SHarish Mahendrakar // Returns true and sets metadata if this parser read too far and read the 80*103e46e4SHarish Mahendrakar // element metadata for an element that is not its child. This may happen, for 81*103e46e4SHarish Mahendrakar // example, when an element with unknown size is being read (because its end 82*103e46e4SHarish Mahendrakar // is considered the first element that is not a valid child, so it must read 83*103e46e4SHarish Mahendrakar // further to detect this). If this did not happen and false is returned, then 84*103e46e4SHarish Mahendrakar // metadata will not be modified. metadata must not be null. GetCachedMetadata(ElementMetadata * metadata)85*103e46e4SHarish Mahendrakar virtual bool GetCachedMetadata(ElementMetadata* metadata) { 86*103e46e4SHarish Mahendrakar assert(metadata != nullptr); 87*103e46e4SHarish Mahendrakar 88*103e46e4SHarish Mahendrakar return false; 89*103e46e4SHarish Mahendrakar } 90*103e46e4SHarish Mahendrakar 91*103e46e4SHarish Mahendrakar // Returns true if this parser skipped the element instead of fully parsing 92*103e46e4SHarish Mahendrakar // it. This will be true if the user requested a kSkip action from the 93*103e46e4SHarish Mahendrakar // Callback in Feed(). This method should only be called after Feed() has 94*103e46e4SHarish Mahendrakar // returned kOkCompleted. If the element was skipped, do not try to access its 95*103e46e4SHarish Mahendrakar // value; it has no meaningful value and doing so will likely result in an 96*103e46e4SHarish Mahendrakar // assertion failing. WasSkipped()97*103e46e4SHarish Mahendrakar virtual bool WasSkipped() const { return false; } 98*103e46e4SHarish Mahendrakar }; 99*103e46e4SHarish Mahendrakar 100*103e46e4SHarish Mahendrakar } // namespace webm 101*103e46e4SHarish Mahendrakar 102*103e46e4SHarish Mahendrakar #endif // SRC_ELEMENT_PARSER_H_ 103