• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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