| // 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_ |