| // 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_ |