blob: 59ea5ef13ac75583c172d3e54cdb631ee27f5e4b [file] [log] [blame]
Mark Salyzyn9dd65102016-02-17 16:08:13 -08001/*
2 * Copyright (C) 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#include <errno.h>
18#include <inttypes.h>
19#include <stdbool.h>
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
Mark Salyzyn472245d2016-11-18 10:45:45 -080025#include <log/log_event_list.h>
Mark Salyzyn6debf982016-10-05 08:13:56 -070026#include <private/android_logger.h>
Mark Salyzyn9dd65102016-02-17 16:08:13 -080027
Mark Salyzynfacf94c2016-03-01 13:45:42 -080028#include "log_portability.h"
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080029
Mark Salyzyn9dd65102016-02-17 16:08:13 -080030#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
31
32typedef struct {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080033 uint32_t tag;
34 unsigned pos; /* Read/write position into buffer */
35 unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
36 unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
37 unsigned list_nest_depth;
38 unsigned len; /* Length or raw buffer. */
39 bool overflow;
40 bool list_stop; /* next call decrement list_nest_depth and issue a stop */
41 enum {
42 kAndroidLoggerRead = 1,
43 kAndroidLoggerWrite = 2,
44 } read_write_flag;
45 uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
Mark Salyzyn9dd65102016-02-17 16:08:13 -080046} android_log_context_internal;
47
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080048LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080049 size_t needed, i;
50 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080051
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080052 context = calloc(1, sizeof(android_log_context_internal));
53 if (!context) {
54 return NULL;
55 }
56 context->tag = tag;
57 context->read_write_flag = kAndroidLoggerWrite;
58 needed = sizeof(uint8_t) + sizeof(uint8_t);
59 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
60 context->overflow = true;
61 }
62 /* Everything is a list */
63 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
64 context->list[0] = context->pos + 1;
65 context->pos += needed;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080066
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080067 return (android_log_context)context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080068}
69
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080070LIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(const char* msg,
71 size_t len) {
72 android_log_context_internal* context;
73 size_t i;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080074
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080075 context = calloc(1, sizeof(android_log_context_internal));
76 if (!context) {
77 return NULL;
78 }
79 len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
80 context->len = len;
81 memcpy(context->storage, msg, len);
82 context->read_write_flag = kAndroidLoggerRead;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080083
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080084 return (android_log_context)context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080085}
86
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087LIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context* ctx) {
88 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080089
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080090 context = (android_log_context_internal*)*ctx;
91 if (!context) {
92 return -EBADF;
93 }
94 memset(context, 0, sizeof(*context));
95 free(context);
96 *ctx = NULL;
97 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -080098}
99
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800100LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800101 size_t needed;
102 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800103
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800104 context = (android_log_context_internal*)ctx;
105 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
106 return -EBADF;
107 }
108 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
109 context->overflow = true;
110 return -EOVERFLOW;
111 }
112 needed = sizeof(uint8_t) + sizeof(uint8_t);
113 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
114 context->overflow = true;
115 return -EIO;
116 }
117 context->count[context->list_nest_depth]++;
118 context->list_nest_depth++;
119 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
120 context->overflow = true;
121 return -EOVERFLOW;
122 }
123 if (context->overflow) {
124 return -EIO;
125 }
126 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
127 context->storage[context->pos + 1] = 0;
128 context->list[context->list_nest_depth] = context->pos + 1;
129 context->count[context->list_nest_depth] = 0;
130 context->pos += needed;
131 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800132}
133
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800134static inline void copy4LE(uint8_t* buf, uint32_t val) {
135 buf[0] = val & 0xFF;
136 buf[1] = (val >> 8) & 0xFF;
137 buf[2] = (val >> 16) & 0xFF;
138 buf[3] = (val >> 24) & 0xFF;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800139}
140
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800141LIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx,
142 int32_t value) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800143 size_t needed;
144 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800145
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800146 context = (android_log_context_internal*)ctx;
147 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
148 return -EBADF;
149 }
150 if (context->overflow) {
151 return -EIO;
152 }
153 needed = sizeof(uint8_t) + sizeof(value);
154 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
155 context->overflow = true;
156 return -EIO;
157 }
158 context->count[context->list_nest_depth]++;
159 context->storage[context->pos + 0] = EVENT_TYPE_INT;
160 copy4LE(&context->storage[context->pos + 1], value);
161 context->pos += needed;
162 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800163}
164
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800165static inline void copy8LE(uint8_t* buf, uint64_t val) {
166 buf[0] = val & 0xFF;
167 buf[1] = (val >> 8) & 0xFF;
168 buf[2] = (val >> 16) & 0xFF;
169 buf[3] = (val >> 24) & 0xFF;
170 buf[4] = (val >> 32) & 0xFF;
171 buf[5] = (val >> 40) & 0xFF;
172 buf[6] = (val >> 48) & 0xFF;
173 buf[7] = (val >> 56) & 0xFF;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800174}
175
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800176LIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx,
177 int64_t value) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800178 size_t needed;
179 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800180
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800181 context = (android_log_context_internal*)ctx;
182 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
183 return -EBADF;
184 }
185 if (context->overflow) {
186 return -EIO;
187 }
188 needed = sizeof(uint8_t) + sizeof(value);
189 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
190 context->overflow = true;
191 return -EIO;
192 }
193 context->count[context->list_nest_depth]++;
194 context->storage[context->pos + 0] = EVENT_TYPE_LONG;
195 copy8LE(&context->storage[context->pos + 1], value);
196 context->pos += needed;
197 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800198}
199
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800200LIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800201 const char* value,
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800202 size_t maxlen) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 size_t needed;
204 ssize_t len;
205 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800206
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800207 context = (android_log_context_internal*)ctx;
208 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
209 return -EBADF;
210 }
211 if (context->overflow) {
212 return -EIO;
213 }
214 if (!value) {
215 value = "";
216 }
217 len = strnlen(value, maxlen);
218 needed = sizeof(uint8_t) + sizeof(int32_t) + len;
219 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
220 /* Truncate string for delivery */
221 len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
222 if (len <= 0) {
223 context->overflow = true;
224 return -EIO;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800225 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800226 }
227 context->count[context->list_nest_depth]++;
228 context->storage[context->pos + 0] = EVENT_TYPE_STRING;
229 copy4LE(&context->storage[context->pos + 1], len);
230 if (len) {
231 memcpy(&context->storage[context->pos + 5], value, len);
232 }
233 context->pos += needed;
234 return len;
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800235}
236
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800237LIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800238 const char* value) {
239 return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800240}
241
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800242LIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx,
243 float value) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800244 size_t needed;
245 uint32_t ivalue;
246 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800247
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800248 context = (android_log_context_internal*)ctx;
249 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
250 return -EBADF;
251 }
252 if (context->overflow) {
253 return -EIO;
254 }
255 needed = sizeof(uint8_t) + sizeof(ivalue);
256 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
257 context->overflow = true;
258 return -EIO;
259 }
260 ivalue = *(uint32_t*)&value;
261 context->count[context->list_nest_depth]++;
262 context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
263 copy4LE(&context->storage[context->pos + 1], ivalue);
264 context->pos += needed;
265 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800266}
267
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800268LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800269 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800270
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800271 context = (android_log_context_internal*)ctx;
272 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
273 return -EBADF;
274 }
275 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
276 context->overflow = true;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800277 context->list_nest_depth--;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800278 return -EOVERFLOW;
279 }
280 if (!context->list_nest_depth) {
281 context->overflow = true;
282 return -EOVERFLOW;
283 }
284 if (context->list[context->list_nest_depth] <= 0) {
285 context->list_nest_depth--;
286 context->overflow = true;
287 return -EOVERFLOW;
288 }
289 context->storage[context->list[context->list_nest_depth]] =
290 context->count[context->list_nest_depth];
291 context->list_nest_depth--;
292 return 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800293}
294
295/*
296 * Logs the list of elements to the event log.
297 */
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800298LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
299 log_id_t id) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800300 android_log_context_internal* context;
301 const char* msg;
302 ssize_t len;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800303
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800304 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {
305 return -EINVAL;
306 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800307
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800308 context = (android_log_context_internal*)ctx;
309 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
310 return -EBADF;
311 }
312 if (context->list_nest_depth) {
313 return -EIO;
314 }
315 /* NB: if there was overflow, then log is truncated. Nothing reported */
316 context->storage[1] = context->count[0];
317 len = context->len = context->pos;
318 msg = (const char*)context->storage;
319 /* it's not a list */
320 if (context->count[0] <= 1) {
321 len -= sizeof(uint8_t) + sizeof(uint8_t);
322 if (len < 0) {
323 len = 0;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800324 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800325 msg += sizeof(uint8_t) + sizeof(uint8_t);
326 }
327 return (id == LOG_ID_EVENTS)
328 ? __android_log_bwrite(context->tag, msg, len)
329 : __android_log_security_bwrite(context->tag, msg, len);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800330}
331
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700332LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800333 const char** buffer) {
334 android_log_context_internal* context;
335 const char* msg;
336 ssize_t len;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700337
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800338 context = (android_log_context_internal*)ctx;
339 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
340 return -EBADF;
341 }
342 if (context->list_nest_depth) {
343 return -EIO;
344 }
345 if (buffer == NULL) {
346 return -EFAULT;
347 }
348 /* NB: if there was overflow, then log is truncated. Nothing reported */
349 context->storage[1] = context->count[0];
350 len = context->len = context->pos;
351 msg = (const char*)context->storage;
352 /* it's not a list */
353 if (context->count[0] <= 1) {
354 len -= sizeof(uint8_t) + sizeof(uint8_t);
355 if (len < 0) {
356 len = 0;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700357 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800358 msg += sizeof(uint8_t) + sizeof(uint8_t);
359 }
360 *buffer = msg;
361 return len;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700362}
363
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800364/*
365 * Extract a 4-byte value from a byte stream.
366 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800367static inline uint32_t get4LE(const uint8_t* src) {
368 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800369}
370
371/*
372 * Extract an 8-byte value from a byte stream.
373 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800374static inline uint64_t get8LE(const uint8_t* src) {
375 uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
376 uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
377 return ((uint64_t)high << 32) | (uint64_t)low;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800378}
379
380/*
381 * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
382 * If there is nothing to process, the complete field is set to non-zero. If
383 * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
384 * this and continues to call this function, the behavior is undefined
385 * (although it won't crash).
386 */
387static android_log_list_element android_log_read_next_internal(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800388 android_log_context ctx, int peek) {
389 android_log_list_element elem;
390 unsigned pos;
391 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800392
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800393 context = (android_log_context_internal*)ctx;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800394
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800395 memset(&elem, 0, sizeof(elem));
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800396
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800397 /* Nothing to parse from this context, so return complete. */
398 if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
399 (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
400 (context->count[context->list_nest_depth] >=
401 (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
402 elem.type = EVENT_TYPE_UNKNOWN;
403 if (context && (context->list_stop ||
404 ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
405 !context->count[context->list_nest_depth]))) {
406 elem.type = EVENT_TYPE_LIST_STOP;
407 }
408 elem.complete = true;
409 return elem;
410 }
411
412 /*
413 * Use a different variable to update the position in case this
414 * operation is a "peek".
415 */
416 pos = context->pos;
417 if (context->list_stop) {
418 elem.type = EVENT_TYPE_LIST_STOP;
419 elem.complete = !context->count[0] &&
420 (!context->list_nest_depth ||
421 ((context->list_nest_depth == 1) && !context->count[1]));
422 if (!peek) {
423 /* Suck in superfluous stop */
424 if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
425 context->pos = pos + 1;
426 }
427 if (context->list_nest_depth) {
428 --context->list_nest_depth;
429 if (context->count[context->list_nest_depth]) {
430 context->list_stop = false;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800431 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800432 } else {
433 context->list_stop = false;
434 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800435 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800436 return elem;
437 }
438 if ((pos + 1) > context->len) {
439 elem.type = EVENT_TYPE_UNKNOWN;
440 elem.complete = true;
441 return elem;
442 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800443
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800444 elem.type = context->storage[pos++];
445 switch ((int)elem.type) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800446 case EVENT_TYPE_FLOAT:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800447 /* Rely on union to translate elem.data.int32 into elem.data.float32 */
448 /* FALLTHRU */
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800449 case EVENT_TYPE_INT:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800450 elem.len = sizeof(int32_t);
451 if ((pos + elem.len) > context->len) {
452 elem.type = EVENT_TYPE_UNKNOWN;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800453 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800454 }
455 elem.data.int32 = get4LE(&context->storage[pos]);
456 /* common tangeable object suffix */
457 pos += elem.len;
458 elem.complete = !context->list_nest_depth && !context->count[0];
459 if (!peek) {
460 if (!context->count[context->list_nest_depth] ||
461 !--(context->count[context->list_nest_depth])) {
462 context->list_stop = true;
463 }
464 context->pos = pos;
465 }
466 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800467
468 case EVENT_TYPE_LONG:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800469 elem.len = sizeof(int64_t);
470 if ((pos + elem.len) > context->len) {
471 elem.type = EVENT_TYPE_UNKNOWN;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800472 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800473 }
474 elem.data.int64 = get8LE(&context->storage[pos]);
475 /* common tangeable object suffix */
476 pos += elem.len;
477 elem.complete = !context->list_nest_depth && !context->count[0];
478 if (!peek) {
479 if (!context->count[context->list_nest_depth] ||
480 !--(context->count[context->list_nest_depth])) {
481 context->list_stop = true;
482 }
483 context->pos = pos;
484 }
485 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800486
487 case EVENT_TYPE_STRING:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800488 if ((pos + sizeof(int32_t)) > context->len) {
489 elem.type = EVENT_TYPE_UNKNOWN;
490 elem.complete = true;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800491 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800492 }
493 elem.len = get4LE(&context->storage[pos]);
494 pos += sizeof(int32_t);
495 if ((pos + elem.len) > context->len) {
496 elem.len = context->len - pos; /* truncate string */
497 elem.complete = true;
498 if (!elem.len) {
499 elem.type = EVENT_TYPE_UNKNOWN;
500 return elem;
501 }
502 }
503 elem.data.string = (char*)&context->storage[pos];
504 /* common tangeable object suffix */
505 pos += elem.len;
506 elem.complete = !context->list_nest_depth && !context->count[0];
507 if (!peek) {
508 if (!context->count[context->list_nest_depth] ||
509 !--(context->count[context->list_nest_depth])) {
510 context->list_stop = true;
511 }
512 context->pos = pos;
513 }
514 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800515
516 case EVENT_TYPE_LIST:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800517 if ((pos + sizeof(uint8_t)) > context->len) {
518 elem.type = EVENT_TYPE_UNKNOWN;
519 elem.complete = true;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800520 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800521 }
522 elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
523 if (peek) {
524 return elem;
525 }
526 if (context->count[context->list_nest_depth]) {
527 context->count[context->list_nest_depth]--;
528 }
529 context->list_stop = !context->storage[pos];
530 context->list_nest_depth++;
531 if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
532 context->count[context->list_nest_depth] = context->storage[pos];
533 }
534 context->pos = pos + sizeof(uint8_t);
535 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800536
537 case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800538 if (!peek) {
539 context->pos = pos;
540 }
541 elem.type = EVENT_TYPE_UNKNOWN;
542 elem.complete = !context->list_nest_depth;
543 if (context->list_nest_depth > 0) {
544 elem.type = EVENT_TYPE_LIST_STOP;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800545 if (!peek) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800546 context->list_nest_depth--;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800547 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800548 }
549 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800550
551 default:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800552 elem.type = EVENT_TYPE_UNKNOWN;
553 return elem;
554 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800555}
556
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800557LIBLOG_ABI_PUBLIC android_log_list_element
558android_log_read_next(android_log_context ctx) {
559 return android_log_read_next_internal(ctx, 0);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800560}
561
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800562LIBLOG_ABI_PUBLIC android_log_list_element
563android_log_peek_next(android_log_context ctx) {
564 return android_log_read_next_internal(ctx, 1);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800565}