blob: a59cb8738396178bd670354c1fd0e994973828ab [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
Stefan Lafon1b1b6f52017-08-24 20:14:06 -0700304 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800305 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)
Stefan Lafon1b1b6f52017-08-24 20:14:06 -0700329 : ((id == LOG_ID_STATS)
330 ? __android_log_stats_bwrite(context->tag, msg, len)
331 : __android_log_security_bwrite(context->tag, msg, len));
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800332}
333
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700334LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800335 const char** buffer) {
336 android_log_context_internal* context;
337 const char* msg;
338 ssize_t len;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700339
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800340 context = (android_log_context_internal*)ctx;
341 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
342 return -EBADF;
343 }
344 if (context->list_nest_depth) {
345 return -EIO;
346 }
347 if (buffer == NULL) {
348 return -EFAULT;
349 }
350 /* NB: if there was overflow, then log is truncated. Nothing reported */
351 context->storage[1] = context->count[0];
352 len = context->len = context->pos;
353 msg = (const char*)context->storage;
354 /* it's not a list */
355 if (context->count[0] <= 1) {
356 len -= sizeof(uint8_t) + sizeof(uint8_t);
357 if (len < 0) {
358 len = 0;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700359 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800360 msg += sizeof(uint8_t) + sizeof(uint8_t);
361 }
362 *buffer = msg;
363 return len;
Mark Salyzyn2ca4f492016-09-12 11:54:57 -0700364}
365
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800366/*
367 * Extract a 4-byte value from a byte stream.
368 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800369static inline uint32_t get4LE(const uint8_t* src) {
370 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800371}
372
373/*
374 * Extract an 8-byte value from a byte stream.
375 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800376static inline uint64_t get8LE(const uint8_t* src) {
377 uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
378 uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
379 return ((uint64_t)high << 32) | (uint64_t)low;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800380}
381
382/*
383 * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
384 * If there is nothing to process, the complete field is set to non-zero. If
385 * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
386 * this and continues to call this function, the behavior is undefined
387 * (although it won't crash).
388 */
389static android_log_list_element android_log_read_next_internal(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800390 android_log_context ctx, int peek) {
391 android_log_list_element elem;
392 unsigned pos;
393 android_log_context_internal* context;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800394
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800395 context = (android_log_context_internal*)ctx;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800396
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800397 memset(&elem, 0, sizeof(elem));
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800398
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800399 /* Nothing to parse from this context, so return complete. */
400 if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
401 (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
402 (context->count[context->list_nest_depth] >=
403 (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
404 elem.type = EVENT_TYPE_UNKNOWN;
405 if (context && (context->list_stop ||
406 ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
407 !context->count[context->list_nest_depth]))) {
408 elem.type = EVENT_TYPE_LIST_STOP;
409 }
410 elem.complete = true;
411 return elem;
412 }
413
414 /*
415 * Use a different variable to update the position in case this
416 * operation is a "peek".
417 */
418 pos = context->pos;
419 if (context->list_stop) {
420 elem.type = EVENT_TYPE_LIST_STOP;
421 elem.complete = !context->count[0] &&
422 (!context->list_nest_depth ||
423 ((context->list_nest_depth == 1) && !context->count[1]));
424 if (!peek) {
425 /* Suck in superfluous stop */
426 if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
427 context->pos = pos + 1;
428 }
429 if (context->list_nest_depth) {
430 --context->list_nest_depth;
431 if (context->count[context->list_nest_depth]) {
432 context->list_stop = false;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800433 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800434 } else {
435 context->list_stop = false;
436 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800437 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800438 return elem;
439 }
440 if ((pos + 1) > context->len) {
441 elem.type = EVENT_TYPE_UNKNOWN;
442 elem.complete = true;
443 return elem;
444 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800445
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800446 elem.type = context->storage[pos++];
447 switch ((int)elem.type) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800448 case EVENT_TYPE_FLOAT:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800449 /* Rely on union to translate elem.data.int32 into elem.data.float32 */
450 /* FALLTHRU */
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800451 case EVENT_TYPE_INT:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800452 elem.len = sizeof(int32_t);
453 if ((pos + elem.len) > context->len) {
454 elem.type = EVENT_TYPE_UNKNOWN;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800455 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800456 }
457 elem.data.int32 = get4LE(&context->storage[pos]);
458 /* common tangeable object suffix */
459 pos += elem.len;
460 elem.complete = !context->list_nest_depth && !context->count[0];
461 if (!peek) {
462 if (!context->count[context->list_nest_depth] ||
463 !--(context->count[context->list_nest_depth])) {
464 context->list_stop = true;
465 }
466 context->pos = pos;
467 }
468 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800469
470 case EVENT_TYPE_LONG:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800471 elem.len = sizeof(int64_t);
472 if ((pos + elem.len) > context->len) {
473 elem.type = EVENT_TYPE_UNKNOWN;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800474 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800475 }
476 elem.data.int64 = get8LE(&context->storage[pos]);
477 /* common tangeable object suffix */
478 pos += elem.len;
479 elem.complete = !context->list_nest_depth && !context->count[0];
480 if (!peek) {
481 if (!context->count[context->list_nest_depth] ||
482 !--(context->count[context->list_nest_depth])) {
483 context->list_stop = true;
484 }
485 context->pos = pos;
486 }
487 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800488
489 case EVENT_TYPE_STRING:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800490 if ((pos + sizeof(int32_t)) > context->len) {
491 elem.type = EVENT_TYPE_UNKNOWN;
492 elem.complete = true;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800493 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800494 }
495 elem.len = get4LE(&context->storage[pos]);
496 pos += sizeof(int32_t);
497 if ((pos + elem.len) > context->len) {
498 elem.len = context->len - pos; /* truncate string */
499 elem.complete = true;
500 if (!elem.len) {
501 elem.type = EVENT_TYPE_UNKNOWN;
502 return elem;
503 }
504 }
505 elem.data.string = (char*)&context->storage[pos];
506 /* common tangeable object suffix */
507 pos += elem.len;
508 elem.complete = !context->list_nest_depth && !context->count[0];
509 if (!peek) {
510 if (!context->count[context->list_nest_depth] ||
511 !--(context->count[context->list_nest_depth])) {
512 context->list_stop = true;
513 }
514 context->pos = pos;
515 }
516 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800517
518 case EVENT_TYPE_LIST:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800519 if ((pos + sizeof(uint8_t)) > context->len) {
520 elem.type = EVENT_TYPE_UNKNOWN;
521 elem.complete = true;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800522 return elem;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800523 }
524 elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
525 if (peek) {
526 return elem;
527 }
528 if (context->count[context->list_nest_depth]) {
529 context->count[context->list_nest_depth]--;
530 }
531 context->list_stop = !context->storage[pos];
532 context->list_nest_depth++;
533 if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
534 context->count[context->list_nest_depth] = context->storage[pos];
535 }
536 context->pos = pos + sizeof(uint8_t);
537 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800538
539 case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800540 if (!peek) {
541 context->pos = pos;
542 }
543 elem.type = EVENT_TYPE_UNKNOWN;
544 elem.complete = !context->list_nest_depth;
545 if (context->list_nest_depth > 0) {
546 elem.type = EVENT_TYPE_LIST_STOP;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800547 if (!peek) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800548 context->list_nest_depth--;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800549 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800550 }
551 return elem;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800552
553 default:
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800554 elem.type = EVENT_TYPE_UNKNOWN;
555 return elem;
556 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800557}
558
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800559LIBLOG_ABI_PUBLIC android_log_list_element
560android_log_read_next(android_log_context ctx) {
561 return android_log_read_next_internal(ctx, 0);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800562}
563
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800564LIBLOG_ABI_PUBLIC android_log_list_element
565android_log_peek_next(android_log_context ctx) {
566 return android_log_read_next_internal(ctx, 1);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800567}