1 /*
2  * Copyright (C) 2013 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 
17 #define LOG_TAG "Printer"
18 // #define LOG_NDEBUG 0
19 
20 #include <utils/Printer.h>
21 #include <utils/String8.h>
22 #include <utils/Log.h>
23 
24 #include <stdlib.h>
25 
26 namespace android {
27 
28 /*
29  * Implementation of Printer
30  */
Printer()31 Printer::Printer() {
32     // Intentionally left empty
33 }
34 
~Printer()35 Printer::~Printer() {
36     // Intentionally left empty
37 }
38 
printFormatLine(const char * format,...)39 void Printer::printFormatLine(const char* format, ...) {
40     va_list arglist;
41     va_start(arglist, format);
42 
43     char* formattedString;
44 
45 #ifndef _WIN32
46     if (vasprintf(&formattedString, format, arglist) < 0) { // returns -1 on error
47         ALOGE("%s: Failed to format string", __FUNCTION__);
48         return;
49     }
50 #else
51     return;
52 #endif
53 
54     va_end(arglist);
55 
56     printLine(formattedString);
57     free(formattedString);
58 }
59 
60 /*
61  * Implementation of LogPrinter
62  */
LogPrinter(const char * logtag,android_LogPriority priority,const char * prefix,bool ignoreBlankLines)63 LogPrinter::LogPrinter(const char* logtag,
64                        android_LogPriority priority,
65                        const char* prefix,
66                        bool ignoreBlankLines) :
67         mLogTag(logtag),
68         mPriority(priority),
69         mPrefix(prefix ?: ""),
70         mIgnoreBlankLines(ignoreBlankLines) {
71 }
72 
printLine(const char * string)73 void LogPrinter::printLine(const char* string) {
74     if (string == NULL) {
75         ALOGW("%s: NULL string passed in", __FUNCTION__);
76         return;
77     }
78 
79     if (mIgnoreBlankLines || (*string)) {
80         // Simple case: Line is not blank, or we don't care about printing blank lines
81         printRaw(string);
82     } else {
83         // Force logcat to print empty lines by adding prefixing with a space
84         printRaw(" ");
85     }
86 }
87 
printRaw(const char * string)88 void LogPrinter::printRaw(const char* string) {
89     __android_log_print(mPriority, mLogTag, "%s%s", mPrefix, string);
90 }
91 
92 
93 /*
94  * Implementation of FdPrinter
95  */
FdPrinter(int fd,unsigned int indent,const char * prefix)96 FdPrinter::FdPrinter(int fd, unsigned int indent, const char* prefix) :
97         mFd(fd), mIndent(indent), mPrefix(prefix ?: "") {
98 
99     if (fd < 0) {
100         ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, fd);
101     }
102 
103     // <indent><prefix><line> -- e.g. '%-4s%s\n' for indent=4
104     snprintf(mFormatString, sizeof(mFormatString), "%%-%us%%s\n", mIndent);
105 }
106 
printLine(const char * string)107 void FdPrinter::printLine(const char* string) {
108     if (string == NULL) {
109         ALOGW("%s: NULL string passed in", __FUNCTION__);
110         return;
111     } else if (mFd < 0) {
112         ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, mFd);
113         return;
114     }
115 
116 #ifndef _WIN32
117     dprintf(mFd, mFormatString, mPrefix, string);
118 #endif
119 }
120 
121 /*
122  * Implementation of String8Printer
123  */
String8Printer(String8 * target,const char * prefix)124 String8Printer::String8Printer(String8* target, const char* prefix) :
125         mTarget(target),
126         mPrefix(prefix ?: "") {
127 
128     if (target == NULL) {
129         ALOGW("%s: Target string was NULL", __FUNCTION__);
130     }
131 }
132 
printLine(const char * string)133 void String8Printer::printLine(const char* string) {
134     if (string == NULL) {
135         ALOGW("%s: NULL string passed in", __FUNCTION__);
136         return;
137     } else if (mTarget == NULL) {
138         ALOGW("%s: Target string was NULL", __FUNCTION__);
139         return;
140     }
141 
142     mTarget->append(mPrefix);
143     mTarget->append(string);
144     mTarget->append("\n");
145 }
146 
147 /*
148  * Implementation of PrefixPrinter
149  */
PrefixPrinter(Printer & printer,const char * prefix)150 PrefixPrinter::PrefixPrinter(Printer& printer, const char* prefix) :
151         mPrinter(printer), mPrefix(prefix ?: "") {
152 }
153 
printLine(const char * string)154 void PrefixPrinter::printLine(const char* string) {
155     mPrinter.printFormatLine("%s%s", mPrefix, string);
156 }
157 
158 }; //namespace android
159