blob: 336c56dd06273ed124950c9f8daed64def84a625 [file] [log] [blame]
// Copyright (c) 2025 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_GN_OUTPUT_STREAM_H_
#define TOOLS_GN_OUTPUT_STREAM_H_
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <string>
// GN generates a lot of text that it sends to various
// output streams. Initially, this was done using std::ostream
// but this interface (and implementation) is inefficient due
// to legacy feature requirements that GN does not need.
//
// OutputStream is an abstract interface for an output stream
// that provides a subset of the std::ostream API, but performs
// far faster. In practice, using it results in 6% faster
// `gn gen` times for large build plans that generate huge
// Ninja build plans.
class OutputStream {
public:
virtual ~OutputStream() {}
// Add |len| bytes of data to the output stream.
virtual void write(const char* str, size_t len) = 0;
// Add a single byte of data to the output stream.
virtual void put(char ch) = 0;
// Convenience helpers for C literals and standard strings.
void write(const char* str) { write(str, ::strlen(str)); }
void write(const std::string& str) { write(str.data(), str.size()); }
// Operator << overload for std::ostream compatibility.
OutputStream& operator<<(char ch) {
put(ch);
return *this;
}
OutputStream& operator<<(const char* str) {
write(str);
return *this;
}
OutputStream& operator<<(const std::string& str) {
write(str);
return *this;
}
OutputStream& operator<<(const std::string_view& str) {
write(str.data(), str.size());
return *this;
}
// Add decimal representations to the output stream.
OutputStream& operator<<(int value);
OutputStream& operator<<(long value);
OutputStream& operator<<(long long value);
OutputStream& operator<<(unsigned value);
OutputStream& operator<<(unsigned long value);
OutputStream& operator<<(unsigned long long value);
};
// A StringOutputStream stores all input into an std::string.
// This is a replacement for std::ostringstream.
class StringOutputStream : public OutputStream {
public:
// Constructor creates empty string.
StringOutputStream() {}
virtual ~StringOutputStream() {}
// Retrieve reference to result.
const std::string str() const { return str_; }
// Move result out of the instance.
std::string release() { return std::move(str_); }
// OutputStream overrides
void write(const char* str, size_t len) override { str_.append(str, len); }
void put(char ch) override { str_.push_back(ch); }
protected:
std::string str_;
};
// A FileOutputStream writes all input into a file.
class FileOutputStream : public OutputStream {
public:
// Constructor opens a FILE instance in binary mode.
// Use fail() after the call to verify for errors.
FileOutputStream(const char* utf8_path);
// Destructor closes the FILE instance.
virtual ~FileOutputStream();
// Return true if an error occured during construction
// or a write or put call.
bool fail() const;
// OutputStream overrides.
void write(const char* str, size_t len) override;
void put(char ch) override;
protected:
FILE* file_ = nullptr;
};
#endif // TOOLS_GN_OUTPUT_STREAM_H_