1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_FORMATS_WEBM_WEBM_PARSER_H_ 6 #define MEDIA_FORMATS_WEBM_WEBM_PARSER_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "media/base/media_export.h" 13 14 namespace media { 15 16 // Interface for receiving WebM parser events. 17 // 18 // Each method is called when an element of the specified type is parsed. 19 // The ID of the element that was parsed is given along with the value 20 // stored in the element. List elements generate calls at the start and 21 // end of the list. Any pointers passed to these methods are only guaranteed 22 // to be valid for the life of that call. Each method (except for OnListStart) 23 // returns a bool that indicates whether the parsed data is valid. OnListStart 24 // returns a pointer to a WebMParserClient object, which should be used to 25 // handle elements parsed out of the list being started. If false (or NULL by 26 // OnListStart) is returned then the parse is immediately terminated and an 27 // error is reported by the parser. 28 class MEDIA_EXPORT WebMParserClient { 29 public: 30 virtual ~WebMParserClient(); 31 32 virtual WebMParserClient* OnListStart(int id); 33 virtual bool OnListEnd(int id); 34 virtual bool OnUInt(int id, int64 val); 35 virtual bool OnFloat(int id, double val); 36 virtual bool OnBinary(int id, const uint8* data, int size); 37 virtual bool OnString(int id, const std::string& str); 38 39 protected: 40 WebMParserClient(); 41 42 DISALLOW_COPY_AND_ASSIGN(WebMParserClient); 43 }; 44 45 struct ListElementInfo; 46 47 // Parses a WebM list element and all of its children. This 48 // class supports incremental parsing of the list so Parse() 49 // can be called multiple times with pieces of the list. 50 // IsParsingComplete() will return true once the entire list has 51 // been parsed. 52 class MEDIA_EXPORT WebMListParser { 53 public: 54 // |id| - Element ID of the list we intend to parse. 55 // |client| - Called as different elements in the list are parsed. 56 WebMListParser(int id, WebMParserClient* client); 57 ~WebMListParser(); 58 59 // Resets the state of the parser so it can start parsing a new list. 60 void Reset(); 61 62 // Parses list data contained in |buf|. 63 // 64 // Returns < 0 if the parse fails. 65 // Returns 0 if more data is needed. 66 // Returning > 0 indicates success & the number of bytes parsed. 67 int Parse(const uint8* buf, int size); 68 69 // Returns true if the entire list has been parsed. 70 bool IsParsingComplete() const; 71 72 private: 73 enum State { 74 NEED_LIST_HEADER, 75 INSIDE_LIST, 76 DONE_PARSING_LIST, 77 PARSE_ERROR, 78 }; 79 80 struct ListState { 81 int id_; 82 int64 size_; 83 int64 bytes_parsed_; 84 const ListElementInfo* element_info_; 85 WebMParserClient* client_; 86 }; 87 88 void ChangeState(State new_state); 89 90 // Parses a single element in the current list. 91 // 92 // |header_size| - The size of the element header 93 // |id| - The ID of the element being parsed. 94 // |element_size| - The size of the element body. 95 // |data| - Pointer to the element contents. 96 // |size| - Number of bytes in |data| 97 // |client| - Client to pass the parsed data to. 98 // 99 // Returns < 0 if the parse fails. 100 // Returns 0 if more data is needed. 101 // Returning > 0 indicates success & the number of bytes parsed. 102 int ParseListElement(int header_size, 103 int id, int64 element_size, 104 const uint8* data, int size); 105 106 // Called when starting to parse a new list. 107 // 108 // |id| - The ID of the new list. 109 // |size| - The size of the new list. 110 // |client| - The client object to notify that a new list is being parsed. 111 // 112 // Returns true if this list can be started in the current context. False 113 // if starting this list causes some sort of parse error. 114 bool OnListStart(int id, int64 size); 115 116 // Called when the end of the current list has been reached. This may also 117 // signal the end of the current list's ancestors if the current list happens 118 // to be at the end of its parent. 119 // 120 // Returns true if no errors occurred while ending this list(s). 121 bool OnListEnd(); 122 123 // Checks to see if |id_b| is a sibling or ancestor of |id_a|. 124 bool IsSiblingOrAncestor(int id_a, int id_b) const; 125 126 State state_; 127 128 // Element ID passed to the constructor. 129 const int root_id_; 130 131 // Element level for |root_id_|. Used to verify that elements appear at 132 // the correct level. 133 const int root_level_; 134 135 // WebMParserClient to handle the root list. 136 WebMParserClient* const root_client_; 137 138 // Stack of state for all the lists currently being parsed. Lists are 139 // added and removed from this stack as they are parsed. 140 std::vector<ListState> list_state_stack_; 141 142 DISALLOW_COPY_AND_ASSIGN(WebMListParser); 143 }; 144 145 // Parses an element header & returns the ID and element size. 146 // 147 // Returns < 0 if the parse fails. 148 // Returns 0 if more data is needed. 149 // Returning > 0 indicates success & the number of bytes parsed. 150 // |*id| contains the element ID on success and is undefined otherwise. 151 // |*element_size| contains the element size on success and is undefined 152 // otherwise. 153 int MEDIA_EXPORT WebMParseElementHeader(const uint8* buf, int size, 154 int* id, int64* element_size); 155 156 } // namespace media 157 158 #endif // MEDIA_FORMATS_WEBM_WEBM_PARSER_H_ 159