aboutsummaryrefslogtreecommitdiff
path: root/io_utils.h
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2018-03-13 18:19:34 +0000
committerEdward Lesmes <ehmaldonado@google.com>2021-07-23 21:50:59 +0000
commit06f1ae9aaca969ee95ef840f22b6b461c304542d (patch)
treef1e5c6624e70628e81fbf38d6cd14b974abe5d93 /io_utils.h
downloadzucchini-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.h146
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_