| // Copyright (c) 2016 The WebM project authors. All Rights Reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style license | |
| // that can be found in the LICENSE file in the root of the source | |
| // tree. An additional intellectual property rights grant can be found | |
| // in the file PATENTS. All contributing project authors may | |
| // be found in the AUTHORS file in the root of the source tree. | |
| #ifndef SRC_ELEMENT_PARSER_H_ | |
| #define SRC_ELEMENT_PARSER_H_ | |
| #include <cassert> | |
| #include <cstdint> | |
| #include "src/ancestory.h" | |
| #include "src/parser.h" | |
| #include "webm/callback.h" | |
| #include "webm/element.h" | |
| namespace webm { | |
| // Parses an element from a WebM byte stream. Objects that implement this | |
| // interface are expected to be used as follows in order to parse the specific | |
| // WebM element that they are designed to handle. | |
| // | |
| // Reader* reader = ...; // Create some Reader. | |
| // Callback* callback = ...; // Create some Callback. | |
| // | |
| // ElementMetadata metadata = { | |
| // id, // Element parsed from the reader. | |
| // header_size, // The number of bytes used to encode the id and size. | |
| // size_in_bytes, // The number of bytes in the element body. | |
| // position, // The position of the element (starting at the ID). | |
| // }; | |
| // | |
| // std::uint64_t max_size = ...; // Some upper bound on this element's size. | |
| // ElementParser* parser = ...; // Create some parser capable of handling | |
| // // elements that match id. | |
| // | |
| // Status status = parser->Init(metadata, max_size); | |
| // if (!status.completed_ok()) { | |
| // // An error occurred. See status.code for the reason. | |
| // } else { | |
| // do { | |
| // std::uint64_t num_bytes_read = 0; | |
| // status = parser->Feed(callback, reader, &num_bytes_read); | |
| // } while (status.code == Status::kOkPartial); | |
| // | |
| // if (status.completed_ok()) { | |
| // // Parsing successfully completed. | |
| // } else { | |
| // // An error occurred. If status.code is a parsing error (see status.h for | |
| // // errors that are considered parsing errors), do not call Feed again; | |
| // // parsing has already failed and further progress can't be made. If | |
| // // status.code is not a parsing error (i.e. Status::kWouldBlock), then | |
| // // Feed may be called again to attempt resuming parsing. | |
| // } | |
| // } | |
| class ElementParser : public Parser { | |
| public: | |
| // Initializes the parser and prepares it for parsing its element. Returns | |
| // Status::kOkCompleted if successful. Must not return Status::kOkPartial (it | |
| // is not resumable). metadata is the metadata associated with this element. | |
| // max_size must be <= metadata.size (unless metadata.size is | |
| // kUnknownElementSize). | |
| virtual Status Init(const ElementMetadata& metadata, | |
| std::uint64_t max_size) = 0; | |
| // Initializes the parser after a seek was done and prepares it for parsing. | |
| // The reader is now at the position of the child element indicated by | |
| // child_metadata, whose ancestory is child_ancestory. The child element for | |
| // this parser is the first element in child_ancestory, or if that is empty, | |
| // then child_metadata itself. If the child is not a valid child of this | |
| // parser, then a debug assertion is made (because that indicates a bug). | |
| virtual void InitAfterSeek(const Ancestory& /* child_ancestory */, | |
| const ElementMetadata& /* child_metadata */) { | |
| assert(false); | |
| } | |
| // Returns true and sets metadata if this parser read too far and read the | |
| // element metadata for an element that is not its child. This may happen, for | |
| // example, when an element with unknown size is being read (because its end | |
| // is considered the first element that is not a valid child, so it must read | |
| // further to detect this). If this did not happen and false is returned, then | |
| // metadata will not be modified. metadata must not be null. | |
| virtual bool GetCachedMetadata(ElementMetadata* metadata) { | |
| assert(metadata != nullptr); | |
| return false; | |
| } | |
| // Returns true if this parser skipped the element instead of fully parsing | |
| // it. This will be true if the user requested a kSkip action from the | |
| // Callback in Feed(). This method should only be called after Feed() has | |
| // returned kOkCompleted. If the element was skipped, do not try to access its | |
| // value; it has no meaningful value and doing so will likely result in an | |
| // assertion failing. | |
| virtual bool WasSkipped() const { return false; } | |
| }; | |
| } // namespace webm | |
| #endif // SRC_ELEMENT_PARSER_H_ |