| // Copyright 2018 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/ipc/message_reader.h" | |
| #include <string.h> | |
| #include "src/developer/debug/ipc/protocol.h" | |
| namespace debug_ipc { | |
| MessageReader::MessageReader(std::vector<char> message) : message_(std::move(message)) {} | |
| MessageReader::~MessageReader() {} | |
| bool MessageReader::ReadBytes(uint32_t len, void* output) { | |
| if (message_.size() - offset_ < len) | |
| return SetError(); | |
| memcpy(output, &message_[offset_], len); | |
| offset_ += len; | |
| return true; | |
| } | |
| bool MessageReader::ReadInt32(int32_t* output) { return ReadBytes(sizeof(int32_t), output); } | |
| bool MessageReader::ReadUint32(uint32_t* output) { return ReadBytes(sizeof(uint32_t), output); } | |
| bool MessageReader::ReadInt64(int64_t* output) { return ReadBytes(sizeof(int64_t), output); } | |
| bool MessageReader::ReadUint64(uint64_t* output) { return ReadBytes(sizeof(uint64_t), output); } | |
| bool MessageReader::ReadString(std::string* output) { | |
| // Size header. | |
| uint32_t str_len; | |
| if (!ReadUint32(&str_len)) | |
| return SetError(); | |
| if (str_len > remaining()) | |
| return SetError(); | |
| // String bytes. | |
| output->resize(str_len); | |
| if (str_len == 0) | |
| return true; | |
| if (!ReadBytes(str_len, &(*output)[0])) { | |
| *output = std::string(); | |
| return SetError(); | |
| } | |
| return true; | |
| } | |
| bool MessageReader::ReadBool(bool* output) { | |
| uint32_t read; | |
| if (!ReadUint32(&read)) | |
| return false; | |
| if (read != 0 && read != 1) | |
| return false; | |
| *output = !!read; | |
| return true; | |
| } | |
| bool MessageReader::ReadHeader(MsgHeader* output) { | |
| if (!ReadUint32(&output->size)) | |
| return false; | |
| uint32_t type; | |
| if (!ReadUint32(&type)) | |
| return false; | |
| if (type >= static_cast<uint32_t>(MsgHeader::Type::kNumMessages)) | |
| return false; | |
| output->type = static_cast<MsgHeader::Type>(type); | |
| return ReadUint32(&output->transaction_id); | |
| ; | |
| } | |
| bool MessageReader::SetError() { | |
| has_error_ = true; | |
| return false; | |
| } | |
| } // namespace debug_ipc |