1 /*
2  * Copyright (C) 2006 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 #ifndef ANDROID_TEXTOUTPUT_H
18 #define ANDROID_TEXTOUTPUT_H
19 
20 #include <utils/Errors.h>
21 #include <utils/String8.h>
22 
23 #include <stdint.h>
24 #include <string.h>
25 #include <sstream>
26 
27 // ---------------------------------------------------------------------------
28 namespace android {
29 
30 class TextOutput
31 {
32 public:
33                         TextOutput();
34     virtual             ~TextOutput();
35 
36     virtual status_t    print(const char* txt, size_t len) = 0;
37     virtual void        moveIndent(int delta) = 0;
38 
39     class Bundle {
40     public:
Bundle(TextOutput & to)41         inline explicit Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }
~Bundle()42         inline ~Bundle() { mTO.popBundle(); }
43     private:
44         TextOutput&     mTO;
45     };
46 
47     virtual void        pushBundle() = 0;
48     virtual void        popBundle() = 0;
49 };
50 
51 // ---------------------------------------------------------------------------
52 
53 // DO NOT USE: prefer libutils/libbase logs, which don't require static data to
54 // be allocated.
55 // Text output stream for printing to the log (via utils/Log.h).
56 extern TextOutput& alog;
57 
58 // DO NOT USE: prefer libutils/libbase logs, which don't require static data to
59 // be allocated.
60 // Text output stream for printing to stdout.
61 extern TextOutput& aout;
62 
63 // DO NOT USE: prefer libutils/libbase logs, which don't require static data to
64 // be allocated.
65 // Text output stream for printing to stderr.
66 extern TextOutput& aerr;
67 
68 typedef TextOutput& (*TextOutputManipFunc)(TextOutput&);
69 
70 TextOutput& endl(TextOutput& to);
71 TextOutput& indent(TextOutput& to);
72 TextOutput& dedent(TextOutput& to);
73 
74 template<typename T>
75 TextOutput& operator<<(TextOutput& to, const T& val)
76 {
77     std::stringstream strbuf;
78     strbuf << val;
79     std::string str = strbuf.str();
80     to.print(str.c_str(), str.size());
81     return to;
82 }
83 
84 TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func);
85 
86 class TypeCode
87 {
88 public:
89     inline explicit TypeCode(uint32_t code);
90     inline ~TypeCode();
91 
92     inline uint32_t typeCode() const;
93 
94 private:
95     uint32_t mCode;
96 };
97 
98 TextOutput& operator<<(TextOutput& to, const TypeCode& val);
99 
100 class HexDump
101 {
102 public:
103     HexDump(const void *buf, size_t size, size_t bytesPerLine=16);
104     inline ~HexDump();
105 
106     inline HexDump& setBytesPerLine(size_t bytesPerLine);
107     inline HexDump& setSingleLineCutoff(int32_t bytes);
108     inline HexDump& setAlignment(size_t alignment);
109     inline HexDump& setCArrayStyle(bool enabled);
110 
111     inline const void* buffer() const;
112     inline size_t size() const;
113     inline size_t bytesPerLine() const;
114     inline int32_t singleLineCutoff() const;
115     inline size_t alignment() const;
116     inline bool carrayStyle() const;
117 
118 private:
119     const void* mBuffer;
120     size_t mSize;
121     size_t mBytesPerLine;
122     int32_t mSingleLineCutoff;
123     size_t mAlignment;
124     bool mCArrayStyle;
125 };
126 
127 TextOutput& operator<<(TextOutput& to, const HexDump& val);
128 inline TextOutput& operator<<(TextOutput& to,
129                               decltype(std::endl<char,
130                                        std::char_traits<char>>)
131                               /*val*/) {
132     endl(to);
133     return to;
134 }
135 
136 inline TextOutput& operator<<(TextOutput& to, const char &c)
137 {
138     to.print(&c, 1);
139     return to;
140 }
141 
142 inline TextOutput& operator<<(TextOutput& to, const bool &val)
143 {
144     if (val) to.print("true", 4);
145     else to.print("false", 5);
146     return to;
147 }
148 
149 inline TextOutput& operator<<(TextOutput& to, const String16& val)
150 {
151     to << String8(val).string();
152     return to;
153 }
154 
155 // ---------------------------------------------------------------------------
156 // No user servicable parts below.
157 
endl(TextOutput & to)158 inline TextOutput& endl(TextOutput& to)
159 {
160     to.print("\n", 1);
161     return to;
162 }
163 
indent(TextOutput & to)164 inline TextOutput& indent(TextOutput& to)
165 {
166     to.moveIndent(1);
167     return to;
168 }
169 
dedent(TextOutput & to)170 inline TextOutput& dedent(TextOutput& to)
171 {
172     to.moveIndent(-1);
173     return to;
174 }
175 
176 inline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func)
177 {
178     return (*func)(to);
179 }
180 
TypeCode(uint32_t code)181 inline TypeCode::TypeCode(uint32_t code) : mCode(code) { }
~TypeCode()182 inline TypeCode::~TypeCode() { }
typeCode()183 inline uint32_t TypeCode::typeCode() const { return mCode; }
184 
~HexDump()185 inline HexDump::~HexDump() { }
186 
setBytesPerLine(size_t bytesPerLine)187 inline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) {
188     mBytesPerLine = bytesPerLine; return *this;
189 }
setSingleLineCutoff(int32_t bytes)190 inline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) {
191     mSingleLineCutoff = bytes; return *this;
192 }
setAlignment(size_t alignment)193 inline HexDump& HexDump::setAlignment(size_t alignment) {
194     mAlignment = alignment; return *this;
195 }
setCArrayStyle(bool enabled)196 inline HexDump& HexDump::setCArrayStyle(bool enabled) {
197     mCArrayStyle = enabled; return *this;
198 }
199 
buffer()200 inline const void* HexDump::buffer() const { return mBuffer; }
size()201 inline size_t HexDump::size() const { return mSize; }
bytesPerLine()202 inline size_t HexDump::bytesPerLine() const { return mBytesPerLine; }
singleLineCutoff()203 inline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; }
alignment()204 inline size_t HexDump::alignment() const { return mAlignment; }
carrayStyle()205 inline bool HexDump::carrayStyle() const { return mCArrayStyle; }
206 
207 // ---------------------------------------------------------------------------
208 } // namespace android
209 
210 #endif // ANDROID_TEXTOUTPUT_H
211