Home | History | Annotate | Download | only in webm
      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