xref: /aosp_15_r20/external/libwebm/webm_parser/src/element_parser.h (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
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