blob: eca192104879ed5f4ce4125e5f28ab9f9581fffb [file]
// 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 "debug-ipc/message_reader.h"
#include <string.h>
#include "debug-ipc/protocol.h"
namespace debug_ipc {
MessageReader::MessageReader(const char* message, uint32_t len)
: message_(message), message_len_(len) {}
MessageReader::~MessageReader() {}
bool MessageReader::ReadBytes(uint32_t len, void* output) {
if (message_len_ - 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(shared::string* output) {
// Size header.
uint32_t str_len;
if (!ReadUint32(&str_len)) return SetError();
if (str_len > remaining()) return SetError();
// String bytes.
*output = shared::string(str_len, '\0');
if (str_len == 0) return true;
if (!ReadBytes(str_len, const_cast<char*>(&(*output)[0]))) {
*output = shared::string();
return SetError();
}
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 true;
}
bool MessageReader::SetError() {
has_error_ = true;
return false;
}
} // namespace debug_ipc