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_WEBM_PARSER_H_
9 #define INCLUDE_WEBM_WEBM_PARSER_H_
10 
11 #include <memory>
12 
13 #include "./callback.h"
14 #include "./reader.h"
15 #include "./status.h"
16 
17 /**
18  \file
19  The main parser class for parsing WebM files.
20  */
21 
22 namespace webm {
23 
24 /**
25  \defgroup PUBLIC_API Public API
26  Public types and header files intended for use by users.
27  */
28 
29 /**
30  \addtogroup PUBLIC_API
31  @{
32  */
33 
34 /**
35  Incrementally parses a WebM document encoded in a byte stream.
36 
37  It is expected that the parsing will begin at the start of the WebM
38  file/document. Otherwise, the `DidSeek()` method should be used to inform the
39  parser that reading may not necessarily begin at the beginning of the document
40  and the parser should be prepared to handle data at an arbitrary point in the
41  document.
42 
43  WebM files are mostly a subset of Matroska, with a few small modifications.
44  Matroska is a format built on top of EBML.
45  */
46 // Spec references:
47 // http://www.webmproject.org/docs/container/
48 // https://matroska.org/technical/specs/index.html
49 // https://github.com/Matroska-Org/ebml-specification/blob/master/specification.markdown
50 class WebmParser {
51  public:
52   /**
53    Constructs the object and prepares it for parsing.
54    */
55   WebmParser();
56 
57   /*
58    Cleans up the parser. No further cleanup is required from the user.
59    */
60   ~WebmParser();
61 
62   // Non-copyable and non-movable.
63   WebmParser(const WebmParser&) = delete;
64   WebmParser& operator=(const WebmParser&) = delete;
65 
66   /**
67    Resets the parser after a seek was performed on the reader, which prepares
68    the parser for starting at an arbitrary point in the stream.
69 
70    The seek must be to the start of an element (that is, it can't be any random
71    byte) or parsing will fail.
72    */
73   void DidSeek();
74 
75   /**
76    Feeds data into the parser from the provided reader.
77 
78    If a parsing error code has been returned (which indicates a malformed
79    document), calling Feed() again will just result in the same error; parsing
80    has already failed at that point and further progress can't be made.
81 
82    \param callback The callback which receives parsing events. No internal
83    references are maintained to `callback`, so it may be modified or freed after
84    this method returns.
85    \param reader The reader the parser will use to request data. No internal
86    references are maintained to `reader`, so it may be modified or freed after
87    this method returns.
88    \return `Status::kOkCompleted` when parsing completes successfully.
89    `Status::kOkPartial` or another non-parsing error code (see status.h for
90    error codes classified as parsing errors) will be returned if parsing has
91    only partially completed, and Feed() should be called again to resume
92    parsing.
93    */
94   Status Feed(Callback* callback, Reader* reader);
95 
96   /**
97    Swaps this parser and the provided parser.
98 
99    \param other The parser to swap values/states with. Must not be null.
100    */
101   void Swap(WebmParser* other);
102 
103  private:
104   // This header can only rely on sources in the public API.
105   class DocumentParser;
106 
107   // The internal implementation of the parser.
108   std::unique_ptr<DocumentParser> parser_;
109 
110   // The status of the parser, used to prevent further progress if an
111   // unrecoverable parsing error has already been encountered.
112   Status parsing_status_ = Status(Status::kOkPartial);
113 };
114 
115 /**
116  Swaps the two parsers.
117 
118  This is provided so code can use argument dependent lookup in an idiomatic way
119  when swapping (especially since `std::swap` won't work since the parser is
120  non-movable).
121 
122  \param left The first parser to swap.
123  \param right The second parser to swap.
124  */
125 void swap(WebmParser& left, WebmParser& right);
126 
127 /**
128  @}
129  */
130 
131 }  // namespace webm
132 
133 #endif  // INCLUDE_WEBM_WEBM_PARSER_H_
134