blob: 95bb978d12531abf80622db990788bed95d6aad3 [file] [edit]
// Copyright 2026 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef NINJA_INPUT_STREAM_H_
#define NINJA_INPUT_STREAM_H_
#include <stddef.h>
#include <string.h>
#include <string>
/// Base interface class for simple input streams.
struct InputStream {
InputStream() = default;
virtual ~InputStream() = default;
// Allow move operations.
InputStream(InputStream&&) noexcept = default;
InputStream& operator=(InputStream&&) noexcept = default;
// Disallow copy operations.
InputStream(const InputStream&) = delete;
InputStream& operator=(const InputStream&) = delete;
/// Read |size| bytes from the stream into |buffer|.
/// Returns true on success, false on error or EOF.
virtual bool Read(char* buffer, size_t size) = 0;
/// Skip |size| bytes in the stream.
/// Returns true on success, false on error or EOF.
virtual bool Skip(size_t size) {
char buf[128];
while (size > 0) {
size_t to_read = size < sizeof(buf) ? size : sizeof(buf);
if (!Read(buf, to_read)) return false;
size -= to_read;
}
return true;
}
};
/// An InputStream derived class that reads from a memory buffer.
struct MemoryInputStream : public InputStream {
MemoryInputStream() : data_(nullptr), size_(0) {}
MemoryInputStream(const char* data, size_t size) : data_(data), size_(size) {}
bool Read(char* buffer, size_t size) override {
if (size > size_) return false;
memcpy(buffer, data_, size);
data_ += size;
size_ -= size;
return true;
}
bool Skip(size_t size) override {
if (size > size_) {
data_ += size_;
size_ = 0;
return false;
}
data_ += size;
size_ -= size;
return true;
}
private:
const char* data_ = nullptr;
size_t size_ = 0;
};
/// A wrapper stream that limits the number of bytes that can be read from
/// an underlying InputStream.
struct LimitedInputStream : public InputStream {
LimitedInputStream(InputStream& input, size_t limit) : input_(&input), limit_(limit) {}
bool Read(char* buffer, size_t size) override {
if (size > limit_) return false;
if (!input_->Read(buffer, size)) return false;
limit_ -= size;
return true;
}
bool Skip(size_t size) override {
if (size > limit_) {
input_->Skip(limit_);
limit_ = 0;
return false;
}
if (!input_->Skip(size)) return false;
limit_ -= size;
return true;
}
InputStream* input_;
size_t limit_;
};
#endif // NINJA_INPUT_STREAM_H_