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 #include "src/virtual_block_parser.h"
9 
10 #include <cassert>
11 #include <cstdint>
12 
13 #include "webm/element.h"
14 
15 namespace webm {
16 
Init(const ElementMetadata & metadata,std::uint64_t max_size)17 Status VirtualBlockParser::Init(const ElementMetadata& metadata,
18                                 std::uint64_t max_size) {
19   assert(metadata.size == kUnknownElementSize || metadata.size <= max_size);
20 
21   if (metadata.size == kUnknownElementSize || metadata.size < 4) {
22     return Status(Status::kInvalidElementSize);
23   }
24 
25   *this = {};
26   my_size_ = metadata.size;
27 
28   return Status(Status::kOkCompleted);
29 }
30 
Feed(Callback * callback,Reader * reader,std::uint64_t * num_bytes_read)31 Status VirtualBlockParser::Feed(Callback* callback, Reader* reader,
32                                 std::uint64_t* num_bytes_read) {
33   assert(callback != nullptr);
34   assert(reader != nullptr);
35   assert(num_bytes_read != nullptr);
36 
37   *num_bytes_read = 0;
38 
39   Status status;
40   std::uint64_t local_num_bytes_read;
41 
42   while (true) {
43     switch (state_) {
44       case State::kReadingHeader: {
45         status = parser_.Feed(callback, reader, &local_num_bytes_read);
46         *num_bytes_read += local_num_bytes_read;
47         total_bytes_read_ += local_num_bytes_read;
48         if (!status.completed_ok()) {
49           return status;
50         }
51         value_.track_number = parser_.value().track_number;
52         value_.timecode = parser_.value().timecode;
53         state_ = State::kValidatingSize;
54         continue;
55       }
56 
57       case State::kValidatingSize: {
58         if (my_size_ < total_bytes_read_) {
59           return Status(Status::kInvalidElementValue);
60         }
61         state_ = State::kDone;
62         continue;
63       }
64 
65       case State::kDone: {
66         return Status(Status::kOkCompleted);
67       }
68     }
69   }
70 }
71 
72 }  // namespace webm
73