blob: 13a7fdf2473c1dc8e5cde0878c460d550c6c743a [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "Formatter.h"
18
19#include <assert.h>
20
Andreas Huberc9410c72016-07-28 12:18:40 -070021namespace android {
22
Andreas Huber881227d2016-08-02 14:20:21 -070023Formatter::Formatter(FILE *file)
24 : mFile(file == NULL ? stdout : file),
25 mIndentDepth(0),
Andreas Huberc9410c72016-07-28 12:18:40 -070026 mAtStartOfLine(true) {
27}
28
Andreas Huber881227d2016-08-02 14:20:21 -070029Formatter::~Formatter() {
30 if (mFile != stdout) {
31 fclose(mFile);
32 }
33 mFile = NULL;
34}
35
Andreas Huberc9410c72016-07-28 12:18:40 -070036void Formatter::indent() {
37 ++mIndentDepth;
38}
39
40void Formatter::unindent() {
41 assert(mIndentDepth > 0);
42 --mIndentDepth;
43}
44
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070045Formatter &Formatter::operator<<(const std::string &out) {
Andreas Huberc9410c72016-07-28 12:18:40 -070046 const size_t len = out.length();
47 size_t start = 0;
48 while (start < len) {
49 size_t pos = out.find("\n", start);
50
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070051 if (pos == std::string::npos) {
Andreas Huberc9410c72016-07-28 12:18:40 -070052 if (mAtStartOfLine) {
Andreas Huber881227d2016-08-02 14:20:21 -070053 fprintf(mFile, "%*s", (int)(2 * mIndentDepth), "");
Andreas Huberc9410c72016-07-28 12:18:40 -070054 mAtStartOfLine = false;
55 }
56
Andreas Huber0e00de42016-08-03 09:56:02 -070057 output(out.substr(start));
Andreas Huberc9410c72016-07-28 12:18:40 -070058 break;
59 }
60
61 if (pos == start) {
Andreas Huber881227d2016-08-02 14:20:21 -070062 fprintf(mFile, "\n");
Andreas Huberc9410c72016-07-28 12:18:40 -070063 mAtStartOfLine = true;
64 } else if (pos > start) {
65 if (mAtStartOfLine) {
Andreas Huber881227d2016-08-02 14:20:21 -070066 fprintf(mFile, "%*s", (int)(2 * mIndentDepth), "");
Andreas Huberc9410c72016-07-28 12:18:40 -070067 }
68
Andreas Huber0e00de42016-08-03 09:56:02 -070069 output(out.substr(start, pos - start + 1));
Andreas Huberc9410c72016-07-28 12:18:40 -070070
71 mAtStartOfLine = true;
72 }
73
74 start = pos + 1;
75 }
76
77 return *this;
78}
79
80Formatter &Formatter::operator<<(size_t n) {
81 return (*this) << std::to_string(n);
82}
83
Andreas Huber0e00de42016-08-03 09:56:02 -070084void Formatter::setNamespace(const std::string &space) {
85 mSpace = space;
Andreas Huber0e00de42016-08-03 09:56:02 -070086}
87
88void Formatter::output(const std::string &text) const {
89 const size_t spaceLength = mSpace.size();
90 if (spaceLength > 0) {
91 // Remove all occurences of "mSpace" and output the filtered result.
92 size_t matchPos = text.find(mSpace);
93 if (matchPos != std::string::npos) {
94 std::string newText = text.substr(0, matchPos);
95 size_t startPos = matchPos + spaceLength;
96 while ((matchPos = text.find(mSpace, startPos))
97 != std::string::npos) {
98 newText.append(text.substr(startPos, matchPos - startPos));
99 startPos = matchPos + spaceLength;
100 }
101 newText.append(text.substr(startPos));
102 fprintf(mFile, "%s", newText.c_str());
103 return;
104 }
105 }
106
107 fprintf(mFile, "%s", text.c_str());
108}
109
Andreas Huberc9410c72016-07-28 12:18:40 -0700110} // namespace android