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