blob: a3a43fcf79fd1c5944c21802d87f79c6a2d572be [file] [log] [blame]
// 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