1/* 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 "event_log_list_builder.h" 18 19#include <cinttypes> 20#include <memory> 21#include <string> 22#include <android-base/logging.h> 23#include <log/log.h> 24 25namespace { 26 27const size_t MAX_EVENT_PAYLOAD_SIZE = 512 - 1; // Leave room for final '\n'. 28const size_t EVENT_TYPE_SIZE = 1; // Size in bytes of the event type marker. 29 30} // namespace 31 32EventLogListBuilder::EventLogListBuilder() 33 : payload_count_(0), 34 payload_size_(0), 35 payload_(std::make_unique<uint8_t[]>(MAX_EVENT_PAYLOAD_SIZE)) { 36 memset(payload_.get(), 0, MAX_EVENT_PAYLOAD_SIZE); 37 38 // Set up the top-level EventLog data type. 39 AppendByte(EVENT_TYPE_LIST); 40 41 // Skip over the byte prepresenting the number of items in the list. This 42 // value is set in Release(). 43 payload_size_++; 44} 45 46bool EventLogListBuilder::Append(int value) { 47 DCHECK_NE(static_cast<uint8_t*>(nullptr), payload_.get()); 48 49 if (!IsSpaceAvailable(sizeof(value) + EVENT_TYPE_SIZE)) { 50 return false; 51 } 52 53 AppendByte(EVENT_TYPE_INT); 54 AppendData(&value, sizeof(value)); 55 56 payload_count_++; 57 return true; 58} 59 60bool EventLogListBuilder::Append(const std::string& value) { 61 DCHECK_NE(static_cast<uint8_t*>(nullptr), payload_.get()); 62 63 int len = value.length(); 64 if (!IsSpaceAvailable(sizeof(len) + len)) { 65 return false; 66 } 67 68 AppendByte(EVENT_TYPE_STRING); 69 AppendData(&len, sizeof(len)); 70 AppendData(value.c_str(), len); 71 72 payload_count_++; 73 return true; 74} 75 76void EventLogListBuilder::Release(std::unique_ptr<uint8_t[]>* log, 77 size_t* size) { 78 // Finalize the log payload. 79 payload_[1] = payload_count_; 80 81 // Return the log payload. 82 *size = payload_size_; 83 *log = std::move(payload_); 84} 85 86void EventLogListBuilder::AppendData(const void* data, size_t size) { 87 DCHECK_LT(payload_size_ + size, MAX_EVENT_PAYLOAD_SIZE); 88 memcpy(&payload_[payload_size_], data, size); 89 payload_size_ += size; 90} 91 92void EventLogListBuilder::AppendByte(uint8_t byte) { 93 DCHECK_LT(payload_size_ + sizeof(byte), MAX_EVENT_PAYLOAD_SIZE); 94 payload_[payload_size_++] = byte; 95} 96 97bool EventLogListBuilder::IsSpaceAvailable(size_t value_size) { 98 size_t space_needed = value_size + EVENT_TYPE_SIZE; 99 if (payload_size_ + space_needed > MAX_EVENT_PAYLOAD_SIZE) { 100 size_t remaining = MAX_EVENT_PAYLOAD_SIZE - payload_size_; 101 LOG(WARNING) << "Not enough space for value. remain=" << 102 remaining << "; needed=" << space_needed; 103 return false; 104 } 105 106 return true; 107} 108