Merge "Track current position in Formatter"
diff --git a/host_utils/Formatter.cpp b/host_utils/Formatter.cpp
index 2268e30..24d690c 100644
--- a/host_utils/Formatter.cpp
+++ b/host_utils/Formatter.cpp
@@ -19,17 +19,18 @@
#include <assert.h>
#include <android-base/logging.h>
+#include <string>
#include <vector>
namespace android {
-Formatter::Formatter() : mFile(nullptr /* invalid */), mIndentDepth(0), mAtStartOfLine(true) {}
+Formatter::Formatter() : mFile(nullptr /* invalid */), mIndentDepth(0), mCurrentPosition(0) {}
Formatter::Formatter(FILE* file, size_t spacesPerIndent)
: mFile(file == nullptr ? stdout : file),
mIndentDepth(0),
mSpacesPerIndent(spacesPerIndent),
- mAtStartOfLine(true) {}
+ mCurrentPosition(0) {}
Formatter::~Formatter() {
if (mFile != stdout) {
@@ -116,34 +117,37 @@
return this->block(block);
}
-Formatter &Formatter::operator<<(const std::string &out) {
+Formatter& Formatter::operator<<(const std::string& out) {
const size_t len = out.length();
size_t start = 0;
while (start < len) {
size_t pos = out.find('\n', start);
if (pos == std::string::npos) {
- if (mAtStartOfLine) {
+ if (mCurrentPosition == 0) {
fprintf(mFile, "%*s", (int)(getIndentation()), "");
fprintf(mFile, "%s", mLinePrefix.c_str());
- mAtStartOfLine = false;
+ mCurrentPosition = getIndentation() + mLinePrefix.size();
}
- output(out.substr(start));
+ std::string sub = out.substr(start);
+ output(sub);
+ mCurrentPosition += sub.size();
break;
}
- if (mAtStartOfLine && (pos > start || !mLinePrefix.empty())) {
+ if (mCurrentPosition == 0 && (pos > start || !mLinePrefix.empty())) {
fprintf(mFile, "%*s", (int)(getIndentation()), "");
fprintf(mFile, "%s", mLinePrefix.c_str());
+ mCurrentPosition = getIndentation() + mLinePrefix.size();
}
if (pos == start) {
fprintf(mFile, "\n");
- mAtStartOfLine = true;
+ mCurrentPosition = 0;
} else if (pos > start) {
output(out.substr(start, pos - start + 1));
- mAtStartOfLine = true;
+ mCurrentPosition = 0;
}
start = pos + 1;
@@ -152,52 +156,46 @@
return *this;
}
+void Formatter::printBlock(const WrappedOutput::Block& block, size_t lineLength) {
+ size_t lineStart = mCurrentPosition ?: (getIndentation() + mLinePrefix.size());
+ size_t blockSize = block.computeSize(false);
+ if (blockSize + lineStart < lineLength) {
+ block.print(*this, false);
+ return;
+ }
+
+ // Everything will not fit on this line. Try to fit it on the next line.
+ blockSize = block.computeSize(true);
+ if ((blockSize + getIndentation() + mSpacesPerIndent + mLinePrefix.size()) < lineLength) {
+ *this << "\n";
+ indent();
+
+ block.print(*this, true);
+
+ unindent();
+ return;
+ }
+
+ if (!block.content.empty()) {
+ // Doesn't have subblocks. This means that the block itself is too big.
+ // Have to print it out.
+ *this << "\n";
+ indent();
+
+ block.print(*this, true);
+
+ unindent();
+ return;
+ }
+
+ // Everything will not fit on this line. Go through all the children
+ for (const WrappedOutput::Block& subBlock : block.blocks) {
+ printBlock(subBlock, lineLength);
+ }
+}
+
Formatter& Formatter::operator<<(const WrappedOutput& wrappedOutput) {
- CHECK(mAtStartOfLine) << "This function should only be called at the start of a new line";
-
- size_t currentPosition = getIndentation();
- std::function<void(Formatter&, const WrappedOutput::Block&)> printBlock =
- [&](Formatter& out, const WrappedOutput::Block& block) {
- size_t blockSize = block.computeSize(false);
- if (blockSize + currentPosition < wrappedOutput.mLineLength) {
- block.print(out, false);
- currentPosition += blockSize;
- return;
- }
-
- // Everything will not fit on this line. Try to fit it on the next line.
- blockSize = block.computeSize(true);
- if (blockSize + getIndentation() + mSpacesPerIndent < wrappedOutput.mLineLength) {
- out << "\n";
- out.indent();
-
- block.print(out, true);
- currentPosition = getIndentation() + blockSize;
-
- out.unindent();
- return;
- }
-
- if (!block.content.empty()) {
- // Doesn't have subblocks. This means that the block itself is too big.
- // Have to print it out.
- out << "\n";
- out.indent();
-
- block.print(out, true);
- currentPosition = getIndentation() + blockSize;
-
- out.unindent();
- return;
- }
-
- // Everything will not fit on this line. Go through all the children
- for (const WrappedOutput::Block& subBlock : block.blocks) {
- printBlock(out, subBlock);
- }
- };
-
- printBlock(*this, wrappedOutput.mRootBlock);
+ printBlock(wrappedOutput.mRootBlock, wrappedOutput.mLineLength);
return *this;
}
diff --git a/host_utils/include/hidl-util/Formatter.h b/host_utils/include/hidl-util/Formatter.h
index 5ce2351..3c0e116 100644
--- a/host_utils/include/hidl-util/Formatter.h
+++ b/host_utils/include/hidl-util/Formatter.h
@@ -165,8 +165,6 @@
Formatter &operator<<(float c);
Formatter &operator<<(double c);
Formatter &operator<<(long double c);
-
- // This assumes that the formatter is currently on a newline
Formatter& operator<<(const WrappedOutput& wrappedOutput);
// Puts a prefix before each line. This is useful if
@@ -187,10 +185,11 @@
FILE* mFile; // invalid if nullptr
size_t mIndentDepth;
size_t mSpacesPerIndent;
- bool mAtStartOfLine;
+ size_t mCurrentPosition;
std::string mLinePrefix;
+ void printBlock(const WrappedOutput::Block& block, size_t lineLength);
void output(const std::string &text) const;
Formatter(const Formatter&) = delete;