1 /* 2 * Copyright (C) 2005-2016 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 #pragma once 18 19 #include <errno.h> 20 #include <stdint.h> 21 22 #ifdef __cplusplus 23 #include <string> 24 #endif 25 26 #include <log/log.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 /* For manipulating lists of events. */ 33 34 #define ANDROID_MAX_LIST_NEST_DEPTH 8 35 36 /* 37 * The opaque context used to manipulate lists of events. 38 */ 39 #ifndef __android_log_context_defined 40 #define __android_log_context_defined 41 typedef struct android_log_context_internal* android_log_context; 42 #endif 43 44 /* 45 * Elements returned when reading a list of events. 46 */ 47 #ifndef __android_log_list_element_defined 48 #define __android_log_list_element_defined 49 typedef struct { 50 AndroidEventLogType type; 51 uint16_t complete; 52 uint16_t len; 53 union { 54 int32_t int32; 55 int64_t int64; 56 char* string; 57 float float32; 58 } data; 59 } android_log_list_element; 60 #endif 61 62 /* 63 * Creates a context associated with an event tag to write elements to 64 * the list of events. 65 */ 66 android_log_context create_android_logger(uint32_t tag); 67 68 /* All lists must be braced by a begin and end call */ 69 /* 70 * NB: If the first level braces are missing when specifying multiple 71 * elements, we will manufacturer a list to embrace it for your API 72 * convenience. For a single element, it will remain solitary. 73 */ 74 int android_log_write_list_begin(android_log_context ctx); 75 int android_log_write_list_end(android_log_context ctx); 76 77 int android_log_write_int32(android_log_context ctx, int32_t value); 78 int android_log_write_int64(android_log_context ctx, int64_t value); 79 int android_log_write_string8(android_log_context ctx, const char* value); 80 int android_log_write_string8_len(android_log_context ctx, const char* value, 81 size_t maxlen); 82 int android_log_write_float32(android_log_context ctx, float value); 83 84 /* Submit the composed list context to the specified logger id */ 85 /* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ 86 int android_log_write_list(android_log_context ctx, log_id_t id); 87 88 /* 89 * Creates a context from a raw buffer representing a list of events to be read. 90 */ 91 android_log_context create_android_log_parser(const char* msg, size_t len); 92 93 android_log_list_element android_log_read_next(android_log_context ctx); 94 android_log_list_element android_log_peek_next(android_log_context ctx); 95 96 /* Reset writer context */ 97 int android_log_reset(android_log_context ctx); 98 99 /* Reset reader context */ 100 int android_log_parser_reset(android_log_context ctx, 101 const char* msg, size_t len); 102 103 /* Finished with reader or writer context */ 104 int android_log_destroy(android_log_context* ctx); 105 106 #ifdef __cplusplus 107 #ifndef __class_android_log_event_list_defined 108 #define __class_android_log_event_list_defined 109 /* android_log_list C++ helpers */ 110 extern "C++" { 111 class android_log_event_list { 112 private: 113 android_log_context ctx; 114 int ret; 115 116 android_log_event_list(const android_log_event_list&) = delete; 117 void operator=(const android_log_event_list&) = delete; 118 119 public: android_log_event_list(int tag)120 explicit android_log_event_list(int tag) : ret(0) { 121 ctx = create_android_logger(static_cast<uint32_t>(tag)); 122 } ~android_log_event_list()123 ~android_log_event_list() { 124 android_log_destroy(&ctx); 125 } 126 close()127 int close() { 128 int retval = android_log_destroy(&ctx); 129 if (retval < 0) ret = retval; 130 return retval; 131 } 132 133 /* To allow above C calls to use this class as parameter */ android_log_context()134 operator android_log_context() const { 135 return ctx; 136 } 137 138 /* return errors or transmit status */ status()139 int status() const { 140 return ret; 141 } 142 begin()143 int begin() { 144 int retval = android_log_write_list_begin(ctx); 145 if (retval < 0) ret = retval; 146 return ret; 147 } end()148 int end() { 149 int retval = android_log_write_list_end(ctx); 150 if (retval < 0) ret = retval; 151 return ret; 152 } 153 154 android_log_event_list& operator<<(int32_t value) { 155 int retval = android_log_write_int32(ctx, value); 156 if (retval < 0) ret = retval; 157 return *this; 158 } 159 160 android_log_event_list& operator<<(uint32_t value) { 161 int retval = android_log_write_int32(ctx, static_cast<int32_t>(value)); 162 if (retval < 0) ret = retval; 163 return *this; 164 } 165 166 android_log_event_list& operator<<(bool value) { 167 int retval = android_log_write_int32(ctx, value ? 1 : 0); 168 if (retval < 0) ret = retval; 169 return *this; 170 } 171 172 android_log_event_list& operator<<(int64_t value) { 173 int retval = android_log_write_int64(ctx, value); 174 if (retval < 0) ret = retval; 175 return *this; 176 } 177 178 android_log_event_list& operator<<(uint64_t value) { 179 int retval = android_log_write_int64(ctx, static_cast<int64_t>(value)); 180 if (retval < 0) ret = retval; 181 return *this; 182 } 183 184 android_log_event_list& operator<<(const char* value) { 185 int retval = android_log_write_string8(ctx, value); 186 if (retval < 0) ret = retval; 187 return *this; 188 } 189 190 android_log_event_list& operator<<(const std::string& value) { 191 int retval = 192 android_log_write_string8_len(ctx, value.data(), value.length()); 193 if (retval < 0) ret = retval; 194 return *this; 195 } 196 197 android_log_event_list& operator<<(float value) { 198 int retval = android_log_write_float32(ctx, value); 199 if (retval < 0) ret = retval; 200 return *this; 201 } 202 203 int write(log_id_t id = LOG_ID_EVENTS) { 204 /* facilitate -EBUSY retry */ 205 if ((ret == -EBUSY) || (ret > 0)) ret = 0; 206 int retval = android_log_write_list(ctx, id); 207 /* existing errors trump transmission errors */ 208 if (!ret) ret = retval; 209 return ret; 210 } 211 212 int operator<<(log_id_t id) { 213 write(id); 214 android_log_destroy(&ctx); 215 return ret; 216 } 217 218 /* 219 * Append<Type> methods removes any integer promotion 220 * confusion, and adds access to string with length. 221 * Append methods are also added for all types for 222 * convenience. 223 */ 224 AppendInt(int32_t value)225 bool AppendInt(int32_t value) { 226 int retval = android_log_write_int32(ctx, value); 227 if (retval < 0) ret = retval; 228 return ret >= 0; 229 } 230 AppendLong(int64_t value)231 bool AppendLong(int64_t value) { 232 int retval = android_log_write_int64(ctx, value); 233 if (retval < 0) ret = retval; 234 return ret >= 0; 235 } 236 AppendString(const char * value)237 bool AppendString(const char* value) { 238 int retval = android_log_write_string8(ctx, value); 239 if (retval < 0) ret = retval; 240 return ret >= 0; 241 } 242 AppendString(const char * value,size_t len)243 bool AppendString(const char* value, size_t len) { 244 int retval = android_log_write_string8_len(ctx, value, len); 245 if (retval < 0) ret = retval; 246 return ret >= 0; 247 } 248 AppendString(const std::string & value)249 bool AppendString(const std::string& value) { 250 int retval = 251 android_log_write_string8_len(ctx, value.data(), value.length()); 252 if (retval < 0) ret = retval; 253 return ret; 254 } 255 Append(const std::string & value)256 bool Append(const std::string& value) { 257 int retval = 258 android_log_write_string8_len(ctx, value.data(), value.length()); 259 if (retval < 0) ret = retval; 260 return ret; 261 } 262 AppendFloat(float value)263 bool AppendFloat(float value) { 264 int retval = android_log_write_float32(ctx, value); 265 if (retval < 0) ret = retval; 266 return ret >= 0; 267 } 268 269 template <typename Tvalue> Append(Tvalue value)270 bool Append(Tvalue value) { 271 *this << value; 272 return ret >= 0; 273 } 274 Append(const char * value,size_t len)275 bool Append(const char* value, size_t len) { 276 int retval = android_log_write_string8_len(ctx, value, len); 277 if (retval < 0) ret = retval; 278 return ret >= 0; 279 } 280 }; 281 } 282 #endif 283 #endif 284 285 #ifdef __cplusplus 286 } 287 #endif 288