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