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