diff options
author | Samuel Huang <huangs@chromium.org> | 2018-03-13 18:19:34 +0000 |
---|---|---|
committer | Edward Lesmes <ehmaldonado@google.com> | 2021-07-23 21:50:59 +0000 |
commit | 06f1ae9aaca969ee95ef840f22b6b461c304542d (patch) | |
tree | f1e5c6624e70628e81fbf38d6cd14b974abe5d93 /io_utils.h | |
download | zucchini-06f1ae9aaca969ee95ef840f22b6b461c304542d.tar.gz |
[Zucchini] Move Zucchini from /chrome/installer/ to /components/.
(Use "git log --follow" to see older revisions of files).
/components/ is the most logical place to put Zucchini, which only
depends on /base and /testing/gtest. This move also enables Zucchini to
be used by the Component Updater. Details:
- Move all files; run the following to change deps and guards:
sed 's/chrome\/installer/components/' *.cc *.h -i
sed 's/CHROME_INSTALLER/COMPONENTS/' *.cc *.h -i
- Sorting works out pretty well!
- Change all 'chrome/installer/zucchini' to 'components/zucchini'
throughout other parts of the repo; sort if necessary.
- Fix 6 'git cl lint' errors.
- Change 1 Bind() usage to BindRepeated().
- Update OWNER.
Bug: 729154
Change-Id: I50c5a7d411ea85f707b5994ab319dfb2a1acccf7
Reviewed-on: https://chromium-review.googlesource.com/954923
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Commit-Queue: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542857}
NOKEYCHECK=True
GitOrigin-RevId: 577ef6c435e8d43be6e3e60ccbcbd1881780f4ec
Diffstat (limited to 'io_utils.h')
-rw-r--r-- | io_utils.h | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/io_utils.h b/io_utils.h new file mode 100644 index 0000000..56f7075 --- /dev/null +++ b/io_utils.h @@ -0,0 +1,146 @@ +// Copyright 2017 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 COMPONENTS_ZUCCHINI_IO_UTILS_H_ +#define COMPONENTS_ZUCCHINI_IO_UTILS_H_ + +#include <stdint.h> + +#include <cctype> +#include <istream> +#include <ostream> +#include <sstream> +#include <string> + +#include "base/macros.h" + +namespace zucchini { + +// An std::ostream wrapper that that limits number of std::endl lines to output, +// useful for preventing excessive debug message output. Usage requires some +// work by the caller. Sample: +// static LimitedOutputStream los(std::cerr, 10); +// if (!los.full()) { +// ... // Prepare message. Block may be skipped so don't do other work! +// los << message; +// los << std::endl; // Important! +// } +class LimitedOutputStream : public std::ostream { + private: + class StreamBuf : public std::stringbuf { + public: + StreamBuf(std::ostream& os, int limit); + ~StreamBuf() override; + + int sync() override; + bool full() const { return counter_ >= limit_; } + + private: + std::ostream& os_; + const int limit_; + int counter_ = 0; + }; + + public: + LimitedOutputStream(std::ostream& os, int limit); + bool full() const { return buf_.full(); } + + private: + StreamBuf buf_; + + DISALLOW_COPY_AND_ASSIGN(LimitedOutputStream); +}; + +// A class to render hexadecimal numbers for std::ostream with 0-padding. This +// is more concise and flexible than stateful STL manipulator alternatives; so: +// std::ios old_fmt(nullptr); +// old_fmt.copyfmt(std::cout); +// std::cout << std::uppercase << std::hex; +// std::cout << std::setfill('0') << std::setw(8) << int_data << std::endl; +// std::cout.copyfmt(old_fmt); +// can be expressed as: +// std::cout << AxHex<8>(int_data) << std::endl; +template <int N, typename T = uint32_t> +struct AsHex { + explicit AsHex(T value_in) : value(value_in) {} + T value; +}; + +template <int N, typename T> +std::ostream& operator<<(std::ostream& os, const AsHex<N, T>& as_hex) { + char buf[N + 1]; + buf[N] = '\0'; + T value = as_hex.value; + for (int i = N - 1; i >= 0; --i, value >>= 4) + buf[i] = "0123456789ABCDEF"[static_cast<int>(value & 0x0F)]; + if (value) + os << "..."; // To indicate data truncation, or negative values. + os << buf; + return os; +} + +// An output manipulator to simplify printing list separators. Sample usage: +// PrefixSep sep(","); +// for (int i : {3, 1, 4, 1, 5, 9}) +// std::cout << sep << i; +// std::cout << std::endl; // Outputs "3,1,4,1,5,9\n". +class PrefixSep { + public: + explicit PrefixSep(const std::string& sep_str) : sep_str_(sep_str) {} + + friend std::ostream& operator<<(std::ostream& ostr, PrefixSep& obj); + + private: + std::string sep_str_; + bool first_ = true; + + DISALLOW_COPY_AND_ASSIGN(PrefixSep); +}; + +// An input manipulator that dictates the expected next character in +// |std::istream|, and invalidates the stream if expectation is not met. +class EatChar { + public: + explicit EatChar(char ch) : ch_(ch) {} + + friend inline std::istream& operator>>(std::istream& istr, + const EatChar& obj) { + if (!istr.fail() && istr.get() != obj.ch_) + istr.setstate(std::ios_base::failbit); + return istr; + } + + private: + char ch_; + + DISALLOW_COPY_AND_ASSIGN(EatChar); +}; + +// An input manipulator that reads an unsigned integer from |std::istream|, +// and invalidates the stream on failure. Intolerant of leading white spaces, +template <typename T> +class StrictUInt { + public: + explicit StrictUInt(T& var) : var_(var) {} + StrictUInt(const StrictUInt&) = default; + + friend std::istream& operator>>(std::istream& istr, StrictUInt<T> obj) { + if (!istr.fail() && !::isdigit(istr.peek())) { + istr.setstate(std::ios_base::failbit); + return istr; + } + return istr >> obj.var_; + } + + private: + T& var_; +}; + +// Stub out uint8_t: istream treats it as char, and value won't be read as int! +template <> +struct StrictUInt<uint8_t> {}; + +} // namespace zucchini + +#endif // COMPONENTS_ZUCCHINI_IO_UTILS_H_ |