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
26namespace android {
27
28/*
29 * Implementation of Printer
30 */
31Printer::Printer() {
32    // Intentionally left empty
33}
34
35Printer::~Printer() {
36    // Intentionally left empty
37}
38
39void 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 */
63LogPrinter::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
73void 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
88void LogPrinter::printRaw(const char* string) {
89    __android_log_print(mPriority, mLogTag, "%s%s", mPrefix, string);
90}
91
92
93/*
94 * Implementation of FdPrinter
95 */
96FdPrinter::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
107void 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 */
124String8Printer::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
133void 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 */
150PrefixPrinter::PrefixPrinter(Printer& printer, const char* prefix) :
151        mPrinter(printer), mPrefix(prefix ?: "") {
152}
153
154void PrefixPrinter::printLine(const char* string) {
155    mPrinter.printFormatLine("%s%s", mPrefix, string);
156}
157
158}; //namespace android
159