blob: aef49cf83c2a3eaad71e4d2abfee9dd666959a9b [file] [log] [blame]
// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#ifndef SRC_RECURSIVE_PARSER_H_
#define SRC_RECURSIVE_PARSER_H_
#include <cassert>
#include <cstdint>
#include <memory>
#include <utility>
#include "src/element_parser.h"
#include "webm/callback.h"
#include "webm/reader.h"
#include "webm/status.h"
namespace webm {
// Lazily instantiates a parser of type T, and uses that parser to handle all
// parsing operations. The parser is allocated when Init is called. This class
// is intended to be used with recursive elements, where a parser needs to
// recursively instantiate parsers of the same type.
template <typename T>
class RecursiveParser : public ElementParser {
public:
RecursiveParser() = default;
RecursiveParser(RecursiveParser&&) = default;
RecursiveParser& operator=(RecursiveParser&&) = default;
RecursiveParser(const RecursiveParser&) = delete;
RecursiveParser& operator=(const RecursiveParser&) = delete;
Status Init(const ElementMetadata& metadata,
std::uint64_t max_size) override {
assert(metadata.size == kUnknownElementSize || metadata.size <= max_size);
if (!impl_) {
impl_.reset(new T);
}
return impl_->Init(metadata, max_size);
}
void InitAfterSeek(const Ancestory& child_ancestory,
const ElementMetadata& child_metadata) override {
if (!impl_) {
impl_.reset(new T);
}
impl_->InitAfterSeek(child_ancestory, child_metadata);
}
Status Feed(Callback* callback, Reader* reader,
std::uint64_t* num_bytes_read) override {
assert(callback != nullptr);
assert(reader != nullptr);
assert(num_bytes_read != nullptr);
assert(impl_ != nullptr);
return impl_->Feed(callback, reader, num_bytes_read);
}
decltype(std::declval<T>().value()) value() const {
assert(impl_ != nullptr);
return impl_->value();
}
decltype(std::declval<T>().mutable_value()) mutable_value() {
assert(impl_ != nullptr);
return impl_->mutable_value();
}
private:
std::unique_ptr<T> impl_;
};
} // namespace webm
#endif // SRC_RECURSIVE_PARSER_H_