blob: 959c6a8c9634ef8ab2f1d3317558358d59220f79 [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "Formatter.h"
2
3#include <assert.h>
4
Andreas Huberc9410c72016-07-28 12:18:40 -07005namespace android {
6
Andreas Huber881227d2016-08-02 14:20:21 -07007Formatter::Formatter(FILE *file)
8 : mFile(file == NULL ? stdout : file),
9 mIndentDepth(0),
Andreas Huberc9410c72016-07-28 12:18:40 -070010 mAtStartOfLine(true) {
11}
12
Andreas Huber881227d2016-08-02 14:20:21 -070013Formatter::~Formatter() {
14 if (mFile != stdout) {
15 fclose(mFile);
16 }
17 mFile = NULL;
18}
19
Andreas Huberc9410c72016-07-28 12:18:40 -070020void Formatter::indent() {
21 ++mIndentDepth;
22}
23
24void Formatter::unindent() {
25 assert(mIndentDepth > 0);
26 --mIndentDepth;
27}
28
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070029Formatter &Formatter::operator<<(const std::string &out) {
Andreas Huberc9410c72016-07-28 12:18:40 -070030 const size_t len = out.length();
31 size_t start = 0;
32 while (start < len) {
33 size_t pos = out.find("\n", start);
34
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070035 if (pos == std::string::npos) {
Andreas Huberc9410c72016-07-28 12:18:40 -070036 if (mAtStartOfLine) {
Andreas Huber881227d2016-08-02 14:20:21 -070037 fprintf(mFile, "%*s", (int)(2 * mIndentDepth), "");
Andreas Huberc9410c72016-07-28 12:18:40 -070038 mAtStartOfLine = false;
39 }
40
Andreas Huber0e00de42016-08-03 09:56:02 -070041 output(out.substr(start));
Andreas Huberc9410c72016-07-28 12:18:40 -070042 break;
43 }
44
45 if (pos == start) {
Andreas Huber881227d2016-08-02 14:20:21 -070046 fprintf(mFile, "\n");
Andreas Huberc9410c72016-07-28 12:18:40 -070047 mAtStartOfLine = true;
48 } else if (pos > start) {
49 if (mAtStartOfLine) {
Andreas Huber881227d2016-08-02 14:20:21 -070050 fprintf(mFile, "%*s", (int)(2 * mIndentDepth), "");
Andreas Huberc9410c72016-07-28 12:18:40 -070051 }
52
Andreas Huber0e00de42016-08-03 09:56:02 -070053 output(out.substr(start, pos - start + 1));
Andreas Huberc9410c72016-07-28 12:18:40 -070054
55 mAtStartOfLine = true;
56 }
57
58 start = pos + 1;
59 }
60
61 return *this;
62}
63
64Formatter &Formatter::operator<<(size_t n) {
65 return (*this) << std::to_string(n);
66}
67
Andreas Huber0e00de42016-08-03 09:56:02 -070068void Formatter::setNamespace(const std::string &space) {
69 mSpace = space;
Andreas Huber0e00de42016-08-03 09:56:02 -070070}
71
72void Formatter::output(const std::string &text) const {
73 const size_t spaceLength = mSpace.size();
74 if (spaceLength > 0) {
75 // Remove all occurences of "mSpace" and output the filtered result.
76 size_t matchPos = text.find(mSpace);
77 if (matchPos != std::string::npos) {
78 std::string newText = text.substr(0, matchPos);
79 size_t startPos = matchPos + spaceLength;
80 while ((matchPos = text.find(mSpace, startPos))
81 != std::string::npos) {
82 newText.append(text.substr(startPos, matchPos - startPos));
83 startPos = matchPos + spaceLength;
84 }
85 newText.append(text.substr(startPos));
86 fprintf(mFile, "%s", newText.c_str());
87 return;
88 }
89 }
90
91 fprintf(mFile, "%s", text.c_str());
92}
93
Andreas Huberc9410c72016-07-28 12:18:40 -070094} // namespace android