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 INCLUDE_WEBM_CALLBACK_H_
9 #define INCLUDE_WEBM_CALLBACK_H_
10 
11 #include <cstdint>
12 
13 #include "./dom_types.h"
14 #include "./reader.h"
15 #include "./status.h"
16 
17 /**
18  \file
19  The main callback type that receives parsing events.
20  */
21 
22 namespace webm {
23 
24 /**
25  \addtogroup PUBLIC_API
26  @{
27  */
28 
29 /**
30  The action to be performed when parsing an element.
31  */
32 enum class Action {
33   /**
34    Read and parse the element.
35    */
36   kRead,
37 
38   /**
39    Skip the element. Skipped elements are not parsed or stored, and the callback
40    is not given any further notifications regarding the element.
41    */
42   kSkip,
43 };
44 
45 /**
46  A callback that receives parsing events.
47 
48  Every method that returns a `Status` should return `Status::kOkCompleted` when
49  the method has completed and parsing should continue. Returning any other value
50  will cause parsing to stop. Parsing may be resumed if the returned status was
51  not a parsing error (see `Status::is_parsing_error()`). When parsing is
52  resumed, the same `Callback` method will be called again.
53 
54  Methods that take a `Reader` expect the implementation to consume (either via
55  `Reader::Read()` or `Reader::Skip()`) the specified number of bytes before
56  returning `Status::kOkCompleted`. Default implementations will call
57  `Reader::Skip()` to skip the specified number of bytes and the resulting
58  `Status` will be returned (unless it's `Status::kOkPartial`, in which case
59  `Reader::Skip()` will be called again to skip more data).
60 
61  Throwing an exception from the member functions is permitted, though if the
62  exception will be caught and parsing resumed, then the reader should not
63  advance its position (for methods that take a `Reader`) before the exception is
64  thrown. When parsing is resumed, the same `Callback` method will be called
65  again.
66 
67  Users should derive from this class and override member methods as needed.
68  */
69 class Callback {
70  public:
71   virtual ~Callback() = default;
72 
73   /**
74    Called when the parser starts a new element. This is called after the
75    elements ID and size has been parsed, but before any of its body has been
76    read (or validated).
77 
78    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
79 
80    \param metadata Metadata about the element that has just been encountered.
81    \param[out] action The action that should be taken when handling this
82    element. Will not be null.
83    */
84   virtual Status OnElementBegin(const ElementMetadata& metadata,
85                                 Action* action);
86 
87   /**
88    Called when the parser encounters an unknown element.
89 
90    Defaults to calling (and returning the result of) `Reader::Skip()`.
91 
92    \param metadata Metadata about the element.
93    \param reader The reader that should be used to consume data. Will not be
94    null.
95    \param[in,out] bytes_remaining The number of remaining bytes that need to be
96    consumed for the element. Will not be null.
97    \return `Status::kOkCompleted` when the element has been fully consumed and
98    `bytes_remaining` is now zero.
99    */
100   virtual Status OnUnknownElement(const ElementMetadata& metadata,
101                                   Reader* reader,
102                                   std::uint64_t* bytes_remaining);
103 
104   /**
105    Called when the parser encounters an `Id::kEbml` element and it has been
106    fully parsed.
107 
108    Defaults to returning `Status::kOkCompleted`.
109 
110    \param metadata Metadata about the element.
111    \param ebml The parsed element.
112    */
113   virtual Status OnEbml(const ElementMetadata& metadata, const Ebml& ebml);
114 
115   /**
116    Called when the parser encounters an Id::kVoid element.
117 
118    Defaults to calling (and returning the result of) Reader::Skip.
119 
120    \param metadata Metadata about the element.
121    \param reader The reader that should be used to consume data. Will not be
122    null.
123    \param[in,out] bytes_remaining The number of remaining bytes that need to be
124    consumed for the element. Will not be null.
125    \return `Status::kOkCompleted` when the element has been fully consumed and
126    `bytes_remaining` is now zero.
127    */
128   virtual Status OnVoid(const ElementMetadata& metadata, Reader* reader,
129                         std::uint64_t* bytes_remaining);
130 
131   /**
132    Called when the parser starts an `Id::kSegment` element.
133 
134    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
135 
136    \param metadata Metadata about the element that has just been encountered.
137    \param[out] action The action that should be taken when handling this
138    element. Will not be null.
139    */
140   virtual Status OnSegmentBegin(const ElementMetadata& metadata,
141                                 Action* action);
142 
143   /**
144    Called when the parser encounters an `Id::kSeek` element and it has been
145    fully parsed.
146 
147    Defaults to returning `Status::kOkCompleted`.
148 
149    \param metadata Metadata about the element.
150    \param seek The parsed element.
151    */
152   virtual Status OnSeek(const ElementMetadata& metadata, const Seek& seek);
153 
154   /**
155    Called when the parser encounters an `Id::kInfo` element and it has been
156    fully parsed.
157 
158    Defaults to returning `Status::kOkCompleted`.
159 
160    \param metadata Metadata about the element.
161    \param info The parsed element.
162    */
163   virtual Status OnInfo(const ElementMetadata& metadata, const Info& info);
164 
165   /**
166    Called when the parser starts an `Id::kCluster` element.
167 
168    Because Cluster elements should start with a Timecode (and optionally
169    PrevSize) child, this method is not invoked until a child BlockGroup or
170    SimpleBlock element is encountered (or the Cluster ends if no such child
171    exists).
172 
173    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
174 
175    \param metadata Metadata about the element.
176    \param cluster The element, as it has currently been parsed.
177    \param[out] action The action that should be taken when handling this
178    element. Will not be null.
179    */
180   virtual Status OnClusterBegin(const ElementMetadata& metadata,
181                                 const Cluster& cluster, Action* action);
182 
183   /**
184    Called when the parser starts an `Id::kSimpleBlock` element.
185 
186    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
187 
188    \param metadata Metadata about the element.
189    \param simple_block The parsed SimpleBlock header.
190    \param[out] action The action that should be taken when handling this
191    element. Will not be null.
192    */
193   virtual Status OnSimpleBlockBegin(const ElementMetadata& metadata,
194                                     const SimpleBlock& simple_block,
195                                     Action* action);
196 
197   /**
198    Called when the parser finishes an `Id::kSimpleBlock` element.
199 
200    Defaults to returning `Status::kOkCompleted`.
201 
202    \param metadata Metadata about the element.
203    \param simple_block The parsed SimpleBlock header.
204    */
205   virtual Status OnSimpleBlockEnd(const ElementMetadata& metadata,
206                                   const SimpleBlock& simple_block);
207 
208   /**
209    Called when the parser starts an `Id::kBlockGroup` element.
210 
211    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
212 
213    \param metadata Metadata about the element.
214    \param[out] action The action that should be taken when handling this
215    element. Will not be null.
216    */
217   virtual Status OnBlockGroupBegin(const ElementMetadata& metadata,
218                                    Action* action);
219 
220   /**
221    Called when the parser starts an `Id::kBlock` element.
222 
223    Defaults to `Action::kRead` and returning `Status::kOkCompleted`.
224 
225    \param metadata Metadata about the element.
226    \param block The parsed Block header.
227    \param[out] action The action that should be taken when handling this
228    element. Will not be null.
229    */
230   virtual Status OnBlockBegin(const ElementMetadata& metadata,
231                               const Block& block, Action* action);
232 
233   /**
234    Called when the parser finishes an `Id::Block` element.
235 
236    Defaults to returning `Status::kOkCompleted`.
237 
238    \param metadata Metadata about the element.
239    \param block The parsed Block header.
240    */
241   virtual Status OnBlockEnd(const ElementMetadata& metadata,
242                             const Block& block);
243 
244   /**
245    Called when the parser finishes an `Id::kBlockGroup` element.
246 
247    Defaults to returning `Status::kOkCompleted`.
248 
249    \param metadata Metadata about the element.
250    \param block_group The parsed element.
251    */
252   virtual Status OnBlockGroupEnd(const ElementMetadata& metadata,
253                                  const BlockGroup& block_group);
254 
255   /**
256    Called when the parser encounters a frame within a `Id::kBlock` or
257    `Id::kSimpleBlock` element.
258 
259    Defaults to calling (and returning the result of) `Reader::Skip`.
260 
261    \param metadata Metadata about the frame.
262    \param reader The reader that should be used to consume data. Will not be
263    null.
264    \param[in,out] bytes_remaining The number of remaining bytes that need to be
265    consumed for the frame. Will not be null.
266    \return `Status::kOkCompleted` when the frame has been fully consumed and
267    `bytes_remaining` is now zero.
268    */
269   virtual Status OnFrame(const FrameMetadata& metadata, Reader* reader,
270                          std::uint64_t* bytes_remaining);
271 
272   /**
273    Called when the parser finishes an `Id::kCluster` element.
274 
275    Defaults to returning `Status::kOkCompleted`.
276 
277    \param metadata Metadata about the element.
278    \param cluster The parsed element.
279    */
280   virtual Status OnClusterEnd(const ElementMetadata& metadata,
281                               const Cluster& cluster);
282 
283   /**
284    Called when the parser starts an `Id::kTrackEntry` element.
285 
286    Defaults to returning `Status::kOkCompleted`.
287 
288    \param metadata Metadata about the element.
289    \param track_entry The parsed element.
290    */
291   virtual Status OnTrackEntry(const ElementMetadata& metadata,
292                               const TrackEntry& track_entry);
293 
294   /**
295    Called when the parser encounters an `Id::kCuePoint` element and it has been
296    fully parsed.
297 
298    Defaults to returning `Status::kOkCompleted`.
299 
300    \param metadata Metadata about the element.
301    \param cue_point The parsed element.
302    */
303   virtual Status OnCuePoint(const ElementMetadata& metadata,
304                             const CuePoint& cue_point);
305 
306   /**
307    Called when the parser encounters an `Id::kEditionEntry` element and it has
308    been fully parsed.
309 
310    Defaults to returning `Status::kOkCompleted`.
311 
312    \param metadata Metadata about the element.
313    \param edition_entry The parsed element.
314    */
315   virtual Status OnEditionEntry(const ElementMetadata& metadata,
316                                 const EditionEntry& edition_entry);
317 
318   /**
319    Called when the parser encounters an `Id::kTag` element and it has been fully
320    parsed.
321 
322    Defaults to returning `Status::kOkCompleted`.
323 
324    \param metadata Metadata about the element.
325    \param tag The parsed element.
326    */
327   virtual Status OnTag(const ElementMetadata& metadata, const Tag& tag);
328 
329   /**
330    Called when the parser finishes an `Id::kSegment` element.
331 
332    Defaults to returning `Status::kOkCompleted`.
333 
334    \param metadata Metadata about the element.
335    */
336   virtual Status OnSegmentEnd(const ElementMetadata& metadata);
337 
338  protected:
339   /**
340    Calls (and returns the result of) `Reader::Skip()`, skipping (up to) the
341    requested number of bytes.
342 
343    Unlike `Reader::Skip()`, this method may be called with `*bytes_remaining ==
344    0`, which will result in `Status::kOkCompleted`. `Reader::Skip()` will be
345    called multiple times if it returns `Status::kOkPartial` until it returns a
346    different status (indicating the requested number of bytes has been fully
347    skipped or some error occurred).
348 
349    \param reader The reader that should be used to skip data. Must not be null.
350    \param[in,out] bytes_remaining The number of remaining bytes that need to be
351    skipped. Must not be null. May be zero.
352    \return The result of `Reader::Skip()`.
353    */
354   static Status Skip(Reader* reader, std::uint64_t* bytes_remaining);
355 };
356 
357 /**
358  @}
359  */
360 
361 }  // namespace webm
362 
363 #endif  // INCLUDE_WEBM_CALLBACK_H_
364