1ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
2ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
3ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin *
4ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * you may not use this file except in compliance with the License.
6ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * You may obtain a copy of the License at
7ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin *
8ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin *
10ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * See the License for the specific language governing permissions and
14ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * limitations under the License.
15ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
16ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
17ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#define LOG_TAG "Printer"
18ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin// #define LOG_NDEBUG 0
19ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
20ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <utils/Printer.h>
21ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <utils/String8.h>
22ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <utils/Log.h>
23ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
24ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <string.h>
25ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <stdio.h>
26ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin#include <stdlib.h>
27ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
28ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinnamespace android {
29ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
30ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
31ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Implementation of Printer
32ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
33ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinPrinter::Printer() {
34ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    // Intentionally left empty
35ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
36ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
37ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinPrinter::~Printer() {
38ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    // Intentionally left empty
39ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
40ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
41ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid Printer::printFormatLine(const char* format, ...) {
42ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    va_list arglist;
43ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    va_start(arglist, format);
44ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
45ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    char* formattedString;
46e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin
47e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin#ifndef USE_MINGW
48ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (vasprintf(&formattedString, format, arglist) < 0) { // returns -1 on error
49ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGE("%s: Failed to format string", __FUNCTION__);
50ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
51ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
52e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin#else
53e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin    return;
54e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin#endif
55e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin
56ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    va_end(arglist);
57ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
58ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    printLine(formattedString);
59ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    free(formattedString);
60ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
61ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
62ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
63ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Implementation of LogPrinter
64ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
65ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinLogPrinter::LogPrinter(const char* logtag,
66ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin                       android_LogPriority priority,
67ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin                       const char* prefix,
68ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin                       bool ignoreBlankLines) :
69ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mLogTag(logtag),
70ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mPriority(priority),
71ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mPrefix(prefix ?: ""),
72ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mIgnoreBlankLines(ignoreBlankLines) {
73ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
74ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
75ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid LogPrinter::printLine(const char* string) {
76ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (string == NULL) {
77ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: NULL string passed in", __FUNCTION__);
78ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
79ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
80ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
81ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (mIgnoreBlankLines || (*string)) {
82ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        // Simple case: Line is not blank, or we don't care about printing blank lines
83ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        printRaw(string);
84ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    } else {
85ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        // Force logcat to print empty lines by adding prefixing with a space
86ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        printRaw(" ");
87ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
88ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
89ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
90ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid LogPrinter::printRaw(const char* string) {
91ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    __android_log_print(mPriority, mLogTag, "%s%s", mPrefix, string);
92ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
93ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
94ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
95ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
96ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Implementation of FdPrinter
97ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
98ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinFdPrinter::FdPrinter(int fd, unsigned int indent, const char* prefix) :
99ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mFd(fd), mIndent(indent), mPrefix(prefix ?: "") {
100ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
101ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (fd < 0) {
102ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, fd);
103ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
104ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
105ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    // <indent><prefix><line> -- e.g. '%-4s%s\n' for indent=4
106ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    snprintf(mFormatString, sizeof(mFormatString), "%%-%us%%s\n", mIndent);
107ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
108ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
109ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid FdPrinter::printLine(const char* string) {
110ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (string == NULL) {
111ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: NULL string passed in", __FUNCTION__);
112ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
113ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    } else if (mFd < 0) {
114ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: File descriptor out of range (%d)", __FUNCTION__, mFd);
115ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
116ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
117ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
118e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin#ifndef USE_MINGW
119dcc98da018ce7639b0dea3eb9df464031093bfbdElliott Hughes    dprintf(mFd, mFormatString, mPrefix, string);
120e65b7ea8801145626504c724c28aedd0e5038a28Igor Murashkin#endif
121ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
122ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
123ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
124ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Implementation of String8Printer
125ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
126ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinString8Printer::String8Printer(String8* target, const char* prefix) :
127ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mTarget(target),
128ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mPrefix(prefix ?: "") {
129ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
130ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (target == NULL) {
131ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: Target string was NULL", __FUNCTION__);
132ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
133ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
134ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
135ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid String8Printer::printLine(const char* string) {
136ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    if (string == NULL) {
137ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: NULL string passed in", __FUNCTION__);
138ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
139ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    } else if (mTarget == NULL) {
140ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        ALOGW("%s: Target string was NULL", __FUNCTION__);
141ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        return;
142ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    }
143ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
144038ac694b36de2b081e62fcfb9b5f4a8c918c533Christopher Ferris    mTarget->append(mPrefix);
145ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    mTarget->append(string);
146ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    mTarget->append("\n");
147ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
148ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
149ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin/*
150ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin * Implementation of PrefixPrinter
151ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin */
152ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor MurashkinPrefixPrinter::PrefixPrinter(Printer& printer, const char* prefix) :
153ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin        mPrinter(printer), mPrefix(prefix ?: "") {
154ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
155ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
156ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkinvoid PrefixPrinter::printLine(const char* string) {
157ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin    mPrinter.printFormatLine("%s%s", mPrefix, string);
158ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}
159ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin
160ec79ef2e7b6b1d81266637ca0e002b5c0c5a789bIgor Murashkin}; //namespace android
161