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