1*103e46e4SHarish Mahendrakar // Copyright (c) 2016 The WebM project authors. All Rights Reserved. 2*103e46e4SHarish Mahendrakar // 3*103e46e4SHarish Mahendrakar // Use of this source code is governed by a BSD-style license 4*103e46e4SHarish Mahendrakar // that can be found in the LICENSE file in the root of the source 5*103e46e4SHarish Mahendrakar // tree. An additional intellectual property rights grant can be found 6*103e46e4SHarish Mahendrakar // in the file PATENTS. All contributing project authors may 7*103e46e4SHarish Mahendrakar // be found in the AUTHORS file in the root of the source tree. 8*103e46e4SHarish Mahendrakar #ifndef SRC_BOOL_PARSER_H_ 9*103e46e4SHarish Mahendrakar #define SRC_BOOL_PARSER_H_ 10*103e46e4SHarish Mahendrakar 11*103e46e4SHarish Mahendrakar #include <cassert> 12*103e46e4SHarish Mahendrakar #include <cstdint> 13*103e46e4SHarish Mahendrakar 14*103e46e4SHarish Mahendrakar #include "src/element_parser.h" 15*103e46e4SHarish Mahendrakar #include "src/parser_utils.h" 16*103e46e4SHarish Mahendrakar #include "webm/callback.h" 17*103e46e4SHarish Mahendrakar #include "webm/element.h" 18*103e46e4SHarish Mahendrakar #include "webm/reader.h" 19*103e46e4SHarish Mahendrakar #include "webm/status.h" 20*103e46e4SHarish Mahendrakar 21*103e46e4SHarish Mahendrakar namespace webm { 22*103e46e4SHarish Mahendrakar 23*103e46e4SHarish Mahendrakar // Parses a boolean from a byte stream. EBML does not have a boolean type, but 24*103e46e4SHarish Mahendrakar // the Matroska spec defines some unsigned integer elements that have a range of 25*103e46e4SHarish Mahendrakar // [0, 1]. The BoolParser parses these unsigned integer elements into 26*103e46e4SHarish Mahendrakar // true/false, and reports a Status::kInvalidElementValue error if the integer 27*103e46e4SHarish Mahendrakar // is outside of its permitted range. 28*103e46e4SHarish Mahendrakar class BoolParser : public ElementParser { 29*103e46e4SHarish Mahendrakar public: 30*103e46e4SHarish Mahendrakar explicit BoolParser(bool default_value = false) default_value_(default_value)31*103e46e4SHarish Mahendrakar : default_value_(default_value) {} 32*103e46e4SHarish Mahendrakar Init(const ElementMetadata & metadata,std::uint64_t max_size)33*103e46e4SHarish Mahendrakar Status Init(const ElementMetadata& metadata, 34*103e46e4SHarish Mahendrakar std::uint64_t max_size) override { 35*103e46e4SHarish Mahendrakar assert(metadata.size == kUnknownElementSize || metadata.size <= max_size); 36*103e46e4SHarish Mahendrakar 37*103e46e4SHarish Mahendrakar // Booleans are really just unsigned integers with a range limit of 0-1. 38*103e46e4SHarish Mahendrakar // Unsigned integers can't be encoded with more than 8 bytes. 39*103e46e4SHarish Mahendrakar if (metadata.size > 8) { 40*103e46e4SHarish Mahendrakar return Status(Status::kInvalidElementSize); 41*103e46e4SHarish Mahendrakar } 42*103e46e4SHarish Mahendrakar 43*103e46e4SHarish Mahendrakar size_ = num_bytes_remaining_ = static_cast<int>(metadata.size); 44*103e46e4SHarish Mahendrakar value_ = default_value_; 45*103e46e4SHarish Mahendrakar 46*103e46e4SHarish Mahendrakar return Status(Status::kOkCompleted); 47*103e46e4SHarish Mahendrakar } 48*103e46e4SHarish Mahendrakar Feed(Callback * callback,Reader * reader,std::uint64_t * num_bytes_read)49*103e46e4SHarish Mahendrakar Status Feed(Callback* callback, Reader* reader, 50*103e46e4SHarish Mahendrakar std::uint64_t* num_bytes_read) override { 51*103e46e4SHarish Mahendrakar assert(callback != nullptr); 52*103e46e4SHarish Mahendrakar assert(reader != nullptr); 53*103e46e4SHarish Mahendrakar assert(num_bytes_read != nullptr); 54*103e46e4SHarish Mahendrakar 55*103e46e4SHarish Mahendrakar std::uint64_t uint_value = 0; 56*103e46e4SHarish Mahendrakar const Status status = AccumulateIntegerBytes(num_bytes_remaining_, reader, 57*103e46e4SHarish Mahendrakar &uint_value, num_bytes_read); 58*103e46e4SHarish Mahendrakar num_bytes_remaining_ -= static_cast<int>(*num_bytes_read); 59*103e46e4SHarish Mahendrakar 60*103e46e4SHarish Mahendrakar // Only the last byte should have a value, and it should only be 0 or 1. 61*103e46e4SHarish Mahendrakar if ((num_bytes_remaining_ != 0 && uint_value != 0) || uint_value > 1) { 62*103e46e4SHarish Mahendrakar return Status(Status::kInvalidElementValue); 63*103e46e4SHarish Mahendrakar } 64*103e46e4SHarish Mahendrakar 65*103e46e4SHarish Mahendrakar if (size_ > 0) { 66*103e46e4SHarish Mahendrakar value_ = uint_value == 1; 67*103e46e4SHarish Mahendrakar } 68*103e46e4SHarish Mahendrakar 69*103e46e4SHarish Mahendrakar return status; 70*103e46e4SHarish Mahendrakar } 71*103e46e4SHarish Mahendrakar 72*103e46e4SHarish Mahendrakar // Gets the parsed bool. This must not be called until the parse had been 73*103e46e4SHarish Mahendrakar // successfully completed. value()74*103e46e4SHarish Mahendrakar bool value() const { 75*103e46e4SHarish Mahendrakar assert(num_bytes_remaining_ == 0); 76*103e46e4SHarish Mahendrakar return value_; 77*103e46e4SHarish Mahendrakar } 78*103e46e4SHarish Mahendrakar 79*103e46e4SHarish Mahendrakar // Gets the parsed bool. This must not be called until the parse had been 80*103e46e4SHarish Mahendrakar // successfully completed. mutable_value()81*103e46e4SHarish Mahendrakar bool* mutable_value() { 82*103e46e4SHarish Mahendrakar assert(num_bytes_remaining_ == 0); 83*103e46e4SHarish Mahendrakar return &value_; 84*103e46e4SHarish Mahendrakar } 85*103e46e4SHarish Mahendrakar 86*103e46e4SHarish Mahendrakar private: 87*103e46e4SHarish Mahendrakar bool value_; 88*103e46e4SHarish Mahendrakar bool default_value_; 89*103e46e4SHarish Mahendrakar int num_bytes_remaining_ = -1; 90*103e46e4SHarish Mahendrakar int size_; 91*103e46e4SHarish Mahendrakar }; 92*103e46e4SHarish Mahendrakar 93*103e46e4SHarish Mahendrakar } // namespace webm 94*103e46e4SHarish Mahendrakar 95*103e46e4SHarish Mahendrakar #endif // SRC_BOOL_PARSER_H_ 96