19dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn/* 29dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Copyright (C) 2016 The Android Open Source Project 39dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * 49dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 59dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * you may not use this file except in compliance with the License. 69dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * You may obtain a copy of the License at 79dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * 89dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 99dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * 109dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Unless required by applicable law or agreed to in writing, software 119dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 129dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * See the License for the specific language governing permissions and 149dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * limitations under the License. 159dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn */ 169dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 179dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <errno.h> 189dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <inttypes.h> 199dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <stdbool.h> 209dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <stdint.h> 219dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <stdio.h> 229dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <stdlib.h> 239dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#include <string.h> 249dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 25472245d9625b8f0c52737aa8753524facfa211dbMark Salyzyn#include <log/log_event_list.h> 266debf985aa5127b43f1f79a010dc000f733793b8Mark Salyzyn#include <private/android_logger.h> 279dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 28facf94c74a2cc44f294c4789d36d5c7281c7bc3fMark Salyzyn#include "log_portability.h" 296d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn 309dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t)) 319dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 329dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyntypedef struct { 332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t tag; 342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned pos; /* Read/write position into buffer */ 352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */ 362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */ 372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned list_nest_depth; 382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned len; /* Length or raw buffer. */ 392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool overflow; 402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool list_stop; /* next call decrement list_nest_depth and issue a stop */ 412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn enum { 422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kAndroidLoggerRead = 1, 432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kAndroidLoggerWrite = 2, 442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } read_write_flag; 452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD]; 469dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} android_log_context_internal; 479dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 486d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) { 492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed, i; 502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = calloc(1, sizeof(android_log_context_internal)); 532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context) { 542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return NULL; 552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->tag = tag; 572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->read_write_flag = kAndroidLoggerWrite; 582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(uint8_t); 592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Everything is a list */ 632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_LIST; 642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list[0] = context->pos + 1; 652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (android_log_context)context; 689dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 699dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 702ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(const char* msg, 712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t len) { 722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t i; 742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = calloc(1, sizeof(android_log_context_internal)); 762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context) { 772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return NULL; 782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD; 802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->len = len; 812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memcpy(context->storage, msg, len); 822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->read_write_flag = kAndroidLoggerRead; 832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (android_log_context)context; 859dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 869dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 872ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context* ctx) { 882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)*ctx; 912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context) { 922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(context, 0, sizeof(*context)); 952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn free(context); 962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *ctx = NULL; 972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 989dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 999dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 1006d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) { 1012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed; 1022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 1032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 1062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { 1092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EOVERFLOW; 1112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(uint8_t); 1132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 1152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]++; 1182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_nest_depth++; 1192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { 1202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EOVERFLOW; 1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->overflow) { 1242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_LIST; 1272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 1] = 0; 1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list[context->list_nest_depth] = context->pos + 1; 1292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth] = 0; 1302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 1329dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 1339dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline void copy4LE(uint8_t* buf, uint32_t val) { 1352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[0] = val & 0xFF; 1362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[1] = (val >> 8) & 0xFF; 1372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[2] = (val >> 16) & 0xFF; 1382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[3] = (val >> 24) & 0xFF; 1399dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 1409dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 1416d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx, 1426d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn int32_t value) { 1432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed; 1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 1482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 1492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->overflow) { 1512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(value); 1542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 1552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]++; 1592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_INT; 1602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn copy4LE(&context->storage[context->pos + 1], value); 1612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 1622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 1639dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 1649dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 1652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline void copy8LE(uint8_t* buf, uint64_t val) { 1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[0] = val & 0xFF; 1672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[1] = (val >> 8) & 0xFF; 1682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[2] = (val >> 16) & 0xFF; 1692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[3] = (val >> 24) & 0xFF; 1702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[4] = (val >> 32) & 0xFF; 1712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[5] = (val >> 40) & 0xFF; 1722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[6] = (val >> 48) & 0xFF; 1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[7] = (val >> 56) & 0xFF; 1749dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 1759dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 1766d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx, 1776d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn int64_t value) { 1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed; 1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 1802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 1822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 1842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->overflow) { 1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(value); 1892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 1902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 1912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 1922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]++; 1942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_LONG; 1952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn copy8LE(&context->storage[context->pos + 1], value); 1962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 1972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 1989dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 1999dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 2006d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx, 2012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* value, 2026d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn size_t maxlen) { 2032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed; 2042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ssize_t len; 2052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 2062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 2082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 2092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 2102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->overflow) { 2122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 2132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!value) { 2152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn value = ""; 2162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = strnlen(value, maxlen); 2182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(int32_t) + len; 2192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 2202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Truncate string for delivery */ 2212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t); 2222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len <= 0) { 2232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 2242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 2252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]++; 2282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_STRING; 2292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn copy4LE(&context->storage[context->pos + 1], len); 2302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len) { 2312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memcpy(&context->storage[context->pos + 5], value, len); 2322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 2342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return len; 2351d5afc9e08d0f5d6a79716d8f003cef97a01dd68Mark Salyzyn} 2361d5afc9e08d0f5d6a79716d8f003cef97a01dd68Mark Salyzyn 2376d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx, 2382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* value) { 2392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD); 2409dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 2419dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 2426d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx, 2436d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn float value) { 2442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t needed; 2452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t ivalue; 2462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 2472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 2492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 2502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 2512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->overflow) { 2532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 2542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn needed = sizeof(uint8_t) + sizeof(ivalue); 2562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((context->pos + needed) > MAX_EVENT_PAYLOAD) { 2572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 2582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 2592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ivalue = *(uint32_t*)&value; 2612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]++; 2622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->pos + 0] = EVENT_TYPE_FLOAT; 2632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn copy4LE(&context->storage[context->pos + 1], ivalue); 2642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos += needed; 2652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 2669dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 2679dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 2686d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) { 2692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 2702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 2722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 2732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 2742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) { 2762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 2779dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn context->list_nest_depth--; 2782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EOVERFLOW; 2792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context->list_nest_depth) { 2812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 2822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EOVERFLOW; 2832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list[context->list_nest_depth] <= 0) { 2852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_nest_depth--; 2862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->overflow = true; 2872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EOVERFLOW; 2882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[context->list[context->list_nest_depth]] = 2902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]; 2912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_nest_depth--; 2922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 2939dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 2949dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 2959dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn/* 2969dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Logs the list of elements to the event log. 2979dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn */ 2986d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx, 2996d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn log_id_t id) { 3002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 3012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* msg; 3022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ssize_t len; 3032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3041b1b6f50c78d88e3256a5e13559d92fbb6d1c8feStefan Lafon if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) { 3052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EINVAL; 3062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 3092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 3102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 3112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth) { 3132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 3142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* NB: if there was overflow, then log is truncated. Nothing reported */ 3162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[1] = context->count[0]; 3172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = context->len = context->pos; 3182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn msg = (const char*)context->storage; 3192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* it's not a list */ 3202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->count[0] <= 1) { 3212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len -= sizeof(uint8_t) + sizeof(uint8_t); 3222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len < 0) { 3232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = 0; 3242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn msg += sizeof(uint8_t) + sizeof(uint8_t); 3262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (id == LOG_ID_EVENTS) 3282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ? __android_log_bwrite(context->tag, msg, len) 3291b1b6f50c78d88e3256a5e13559d92fbb6d1c8feStefan Lafon : ((id == LOG_ID_STATS) 3301b1b6f50c78d88e3256a5e13559d92fbb6d1c8feStefan Lafon ? __android_log_stats_bwrite(context->tag, msg, len) 3311b1b6f50c78d88e3256a5e13559d92fbb6d1c8feStefan Lafon : __android_log_security_bwrite(context->tag, msg, len)); 3329dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 3339dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 3342ca4f49476a4e4e46dc7b47b2ce56ccaaadb9c8dMark SalyzynLIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx, 3352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char** buffer) { 3362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 3372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* msg; 3382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ssize_t len; 3392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 3412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { 3422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EBADF; 3432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth) { 3452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EIO; 3462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (buffer == NULL) { 3482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -EFAULT; 3492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* NB: if there was overflow, then log is truncated. Nothing reported */ 3512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->storage[1] = context->count[0]; 3522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = context->len = context->pos; 3532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn msg = (const char*)context->storage; 3542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* it's not a list */ 3552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->count[0] <= 1) { 3562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len -= sizeof(uint8_t) + sizeof(uint8_t); 3572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len < 0) { 3582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn len = 0; 3592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn msg += sizeof(uint8_t) + sizeof(uint8_t); 3612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *buffer = msg; 3632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return len; 3642ca4f49476a4e4e46dc7b47b2ce56ccaaadb9c8dMark Salyzyn} 3652ca4f49476a4e4e46dc7b47b2ce56ccaaadb9c8dMark Salyzyn 3669dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn/* 3679dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Extract a 4-byte value from a byte stream. 3689dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn */ 3692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline uint32_t get4LE(const uint8_t* src) { 3702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 3719dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 3729dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 3739dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn/* 3749dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Extract an 8-byte value from a byte stream. 3759dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn */ 3762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline uint64_t get8LE(const uint8_t* src) { 3772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 3782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); 3792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ((uint64_t)high << 32) | (uint64_t)low; 3809dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 3819dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 3829dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn/* 3839dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type. 3849dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * If there is nothing to process, the complete field is set to non-zero. If 3859dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check 3869dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * this and continues to call this function, the behavior is undefined 3879dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn * (although it won't crash). 3889dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn */ 3899dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzynstatic android_log_list_element android_log_read_next_internal( 3902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context ctx, int peek) { 3912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_list_element elem; 3922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned pos; 3932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_context_internal* context; 3942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context = (android_log_context_internal*)ctx; 3962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(&elem, 0, sizeof(elem)); 3982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Nothing to parse from this context, so return complete. */ 4002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context || (kAndroidLoggerRead != context->read_write_flag) || 4012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) || 4022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (context->count[context->list_nest_depth] >= 4032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) { 4042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 4052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context && (context->list_stop || 4062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) && 4072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn !context->count[context->list_nest_depth]))) { 4082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_LIST_STOP; 4092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = true; 4112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* 4152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * Use a different variable to update the position in case this 4162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * operation is a "peek". 4172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn */ 4182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pos = context->pos; 4192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_stop) { 4202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_LIST_STOP; 4212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = !context->count[0] && 4222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (!context->list_nest_depth || 4232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ((context->list_nest_depth == 1) && !context->count[1])); 4242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!peek) { 4252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Suck in superfluous stop */ 4262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->storage[pos] == EVENT_TYPE_LIST_STOP) { 4272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos + 1; 4282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth) { 4302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn --context->list_nest_depth; 4312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->count[context->list_nest_depth]) { 4322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = false; 4339dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn } 4342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 4352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = false; 4362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + 1) > context->len) { 4412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 4422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = true; 4432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = context->storage[pos++]; 4472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn switch ((int)elem.type) { 4489dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_FLOAT: 4492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Rely on union to translate elem.data.int32 into elem.data.float32 */ 4502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* FALLTHRU */ 4519dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_INT: 4522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.len = sizeof(int32_t); 4532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + elem.len) > context->len) { 4542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 4559dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn return elem; 4562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.data.int32 = get4LE(&context->storage[pos]); 4582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* common tangeable object suffix */ 4592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pos += elem.len; 4602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = !context->list_nest_depth && !context->count[0]; 4612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!peek) { 4622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context->count[context->list_nest_depth] || 4632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn !--(context->count[context->list_nest_depth])) { 4642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = true; 4652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos; 4672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4699dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 4709dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_LONG: 4712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.len = sizeof(int64_t); 4722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + elem.len) > context->len) { 4732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 4749dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn return elem; 4752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.data.int64 = get8LE(&context->storage[pos]); 4772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* common tangeable object suffix */ 4782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pos += elem.len; 4792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = !context->list_nest_depth && !context->count[0]; 4802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!peek) { 4812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context->count[context->list_nest_depth] || 4822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn !--(context->count[context->list_nest_depth])) { 4832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = true; 4842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos; 4862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4889dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 4899dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_STRING: 4902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + sizeof(int32_t)) > context->len) { 4912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 4922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = true; 4932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 4942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.len = get4LE(&context->storage[pos]); 4962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pos += sizeof(int32_t); 4972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + elem.len) > context->len) { 4982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.len = context->len - pos; /* truncate string */ 4992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = true; 5002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!elem.len) { 5012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 5022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5039dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn } 5042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.data.string = (char*)&context->storage[pos]; 5062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* common tangeable object suffix */ 5072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pos += elem.len; 5082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = !context->list_nest_depth && !context->count[0]; 5092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!peek) { 5102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!context->count[context->list_nest_depth] || 5112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn !--(context->count[context->list_nest_depth])) { 5122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = true; 5139dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn } 5142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos; 5152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5179dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 5189dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_LIST: 5192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((pos + sizeof(uint8_t)) > context->len) { 5202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 5212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = true; 5222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH; 5252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (peek) { 5269dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn return elem; 5272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->count[context->list_nest_depth]) { 5292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth]--; 5302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_stop = !context->storage[pos]; 5322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_nest_depth++; 5332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) { 5342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->count[context->list_nest_depth] = context->storage[pos]; 5352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos + sizeof(uint8_t); 5372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5389dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 5399dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */ 5402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!peek) { 5412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->pos = pos; 5422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 5442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.complete = !context->list_nest_depth; 5452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (context->list_nest_depth > 0) { 5462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_LIST_STOP; 5479dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn if (!peek) { 5482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn context->list_nest_depth--; 5499dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn } 5502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5529dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 5539dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn default: 5542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn elem.type = EVENT_TYPE_UNKNOWN; 5552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return elem; 5562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5579dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 5589dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 5592ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC android_log_list_element 5602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynandroid_log_read_next(android_log_context ctx) { 5612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return android_log_read_next_internal(ctx, 0); 5629dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 5639dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn 5642ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC android_log_list_element 5652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynandroid_log_peek_next(android_log_context ctx) { 5662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return android_log_read_next_internal(ctx, 1); 5679dd6510dd09f40973b8834c5cad1217ce1c3011dMark Salyzyn} 568