// 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/client_protocol.h"

#include <lib/syslog/cpp/macros.h>

#include "src/developer/debug/ipc/message_reader.h"
#include "src/developer/debug/ipc/message_writer.h"
#include "src/developer/debug/ipc/protocol_helpers.h"

namespace debug_ipc {

// Record deserializers ----------------------------------------------------------------------------

bool Deserialize(MessageReader* reader, ProcessTreeRecord* record) {
  if (!reader->ReadUint32(reinterpret_cast<uint32_t*>(&record->type)))
    return false;
  if (!reader->ReadUint64(&record->koid))
    return false;
  if (!reader->ReadString(&record->name))
    return false;
  return Deserialize(reader, &record->children);
}

bool Deserialize(MessageReader* reader, ThreadRecord* record) {
  if (!Deserialize(reader, &record->id))
    return false;
  if (!reader->ReadString(&record->name))
    return false;

  uint32_t state;
  if (!reader->ReadUint32(&state))
    return false;
  if (state >= static_cast<uint32_t>(ThreadRecord::State::kLast))
    return false;
  record->state = static_cast<ThreadRecord::State>(state);

  uint32_t blocked_reason;
  if (!reader->ReadUint32(&blocked_reason))
    return false;
  if (state >= static_cast<uint32_t>(ThreadRecord::BlockedReason::kLast))
    return false;
  record->blocked_reason = static_cast<ThreadRecord::BlockedReason>(blocked_reason);

  uint32_t stack_amount;
  if (!reader->ReadUint32(&stack_amount))
    return false;
  if (stack_amount >= static_cast<uint32_t>(ThreadRecord::StackAmount::kLast))
    return false;
  record->stack_amount = static_cast<ThreadRecord::StackAmount>(stack_amount);

  if (!Deserialize(reader, &record->frames))
    return false;
  return true;
}

bool Deserialize(MessageReader* reader, ProcessRecord* record) {
  if (!reader->ReadUint64(&record->process_koid) || !reader->ReadString(&record->process_name)) {
    return false;
  }

  return Deserialize(reader, &record->threads);
}

bool Deserialize(MessageReader* reader, MemoryBlock* block) {
  if (!reader->ReadUint64(&block->address))
    return false;
  if (!reader->ReadBool(&block->valid))
    return false;
  if (!reader->ReadUint32(&block->size))
    return false;
  if (block->valid) {
    if (block->size > reader->remaining())
      return false;

    block->data.resize(block->size);
    if (!reader->ReadBytes(block->size, block->data.data()))
      return false;
  }
  return true;
}

bool Deserialize(MessageReader* reader, Module* module) {
  if (!reader->ReadString(&module->name))
    return false;
  if (!reader->ReadUint64(&module->base))
    return false;
  if (!reader->ReadUint64(&module->debug_address))
    return false;
  if (!reader->ReadString(&module->build_id))
    return false;
  return true;
}

bool Deserialize(MessageReader* reader, StackFrame* frame) {
  if (!reader->ReadUint64(&frame->ip))
    return false;
  if (!reader->ReadUint64(&frame->sp))
    return false;
  if (!reader->ReadUint64(&frame->cfa))
    return false;
  return Deserialize(reader, &frame->regs);
}

bool Deserialize(MessageReader* reader, BreakpointStats* stats) {
  if (!reader->ReadUint32(&stats->id))
    return false;
  if (!reader->ReadUint32(&stats->hit_count))
    return false;
  return reader->ReadBool(&stats->should_delete);
}

bool Deserialize(MessageReader* reader, AddressRegion* region) {
  if (!reader->ReadString(&region->name))
    return false;
  if (!reader->ReadUint64(&region->base))
    return false;
  if (!reader->ReadUint64(&region->size))
    return false;
  if (!reader->ReadUint64(&region->depth))
    return false;
  return true;
}

// Record serializers ------------------------------------------------------------------------------

void Serialize(const ProcessBreakpointSettings& settings, MessageWriter* writer) {
  Serialize(settings.id, writer);
  writer->WriteUint64(settings.address);
  Serialize(settings.address_range, writer);
}

void Serialize(const debug_ipc::AutomationOperand& operand, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(operand.kind()));
  writer->WriteUint32(operand.index());
  writer->WriteUint32(operand.value());
}

void Serialize(const debug_ipc::AutomationCondition& condition, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(condition.kind()));
  Serialize(condition.operand(), writer);
  writer->WriteUint64(condition.constant());
  writer->WriteUint64(condition.mask());
}

void Serialize(const debug_ipc::AutomationInstruction& instruction, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(instruction.kind()));
  Serialize(instruction.address(), writer);
  Serialize(instruction.length(), writer);
  Serialize(instruction.extra_1(), writer);
  Serialize(instruction.extra_2(), writer);
  writer->WriteUint32(instruction.value());
  Serialize(instruction.conditions(), writer);
}

void Serialize(const BreakpointSettings& settings, MessageWriter* writer) {
  writer->WriteUint32(settings.id);
  writer->WriteUint32(static_cast<uint32_t>(settings.type));
  writer->WriteString(settings.name);
  writer->WriteBool(settings.one_shot);
  writer->WriteUint32(static_cast<uint32_t>(settings.stop));
  Serialize(settings.locations, writer);
  writer->WriteBool(settings.has_automation);
  Serialize(settings.instructions, writer);
}

void Serialize(const ConfigAction& action, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(action.type));
  writer->WriteString(action.value);
}

// Hello -------------------------------------------------------------------------------------------

void WriteRequest(const HelloRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kHello, transaction_id);
}

bool ReadReply(MessageReader* reader, HelloReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(HelloReply), reply);
}

// Status ------------------------------------------------------------------------------------------

void WriteRequest(const StatusRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kStatus, transaction_id);
}

bool ReadReply(MessageReader* reader, StatusReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &reply->processes))
    return false;
  return Deserialize(reader, &reply->limbo);
}

// ProcessStatus -----------------------------------------------------------------------------------

void WriteRequest(const ProcessStatusRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kProcessStatus, transaction_id);
  writer->WriteUint64(request.process_koid);
}

bool ReadReply(MessageReader* reader, ProcessStatusReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &reply->status))
    return false;
  return true;
}

// Launch ------------------------------------------------------------------------------------------

void WriteRequest(const LaunchRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kLaunch, transaction_id);
  writer->WriteUint32(static_cast<uint32_t>(request.inferior_type));
  Serialize(request.argv, writer);
}

bool ReadReply(MessageReader* reader, LaunchReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&reply->timestamp))
    return false;

  uint32_t inferior_type;
  if (!reader->ReadUint32(&inferior_type) ||
      inferior_type >= static_cast<uint32_t>(InferiorType::kLast)) {
    return false;
  }
  reply->inferior_type = static_cast<InferiorType>(inferior_type);

  if (!Deserialize(reader, &reply->status))
    return false;
  if (!reader->ReadUint64(&reply->process_id))
    return false;
  if (!reader->ReadUint64(&reply->component_id))
    return false;
  if (!reader->ReadString(&reply->process_name))
    return false;
  return true;
}

// Kill --------------------------------------------------------------------------------------------

void WriteRequest(const KillRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kKill, transaction_id);
  writer->WriteUint64(request.process_koid);
}

bool ReadReply(MessageReader* reader, KillReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&reply->timestamp))
    return false;
  if (!Deserialize(reader, &reply->status))
    return false;
  return true;
}

// Attach ------------------------------------------------------------------------------------------

void WriteRequest(const AttachRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAttach, transaction_id);
  writer->WriteUint32(static_cast<uint32_t>(request.type));
  writer->WriteUint64(request.koid);
}

bool ReadReply(MessageReader* reader, AttachReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&reply->timestamp))
    return false;
  if (!reader->ReadUint64(&reply->koid))
    return false;
  if (!Deserialize(reader, &reply->status))
    return false;
  if (!reader->ReadString(&reply->name))
    return false;
  return true;
}

// Detach ------------------------------------------------------------------------------------------

void WriteRequest(const DetachRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kDetach, transaction_id);
  writer->WriteUint32(static_cast<uint32_t>(request.type));
  writer->WriteUint64(request.koid);
}

bool ReadReply(MessageReader* reader, DetachReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&reply->timestamp))
    return false;
  if (!Deserialize(reader, &reply->status))
    return false;
  return true;
}

// Pause -------------------------------------------------------------------------------------------

void WriteRequest(const PauseRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kPause, transaction_id);
  Serialize(request.id, writer);
}

bool ReadReply(MessageReader* reader, PauseReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->threads);
}

// QuitAgent ---------------------------------------------------------------------------------------

void WriteRequest(const QuitAgentRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kQuitAgent, transaction_id);
}

bool ReadReply(MessageReader* reader, QuitAgentReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return true;
}

// Resume ------------------------------------------------------------------------------------------

void WriteRequest(const ResumeRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kResume, transaction_id);
  Serialize(request.ids, writer);
  writer->WriteUint32(static_cast<uint32_t>(request.how));
  writer->WriteUint64(request.range_begin);
  writer->WriteUint64(request.range_end);
}

bool ReadReply(MessageReader* reader, ResumeReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return true;
}

// ProcessTree -------------------------------------------------------------------------------------

void WriteRequest(const ProcessTreeRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kProcessTree, transaction_id);
  writer->WriteBytes(&request, sizeof(ProcessTreeRequest));
}

bool ReadReply(MessageReader* reader, ProcessTreeReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return Deserialize(reader, &reply->root);
}

// Threads -----------------------------------------------------------------------------------------

void WriteRequest(const ThreadsRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreads, transaction_id);
  writer->WriteBytes(&request, sizeof(ThreadsRequest));
}

bool ReadReply(MessageReader* reader, ThreadsReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->threads);
}

// ReadMemory --------------------------------------------------------------------------------------

void WriteRequest(const ReadMemoryRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadMemory, transaction_id);
  writer->WriteBytes(&request, sizeof(ReadMemoryRequest));
}

bool ReadReply(MessageReader* reader, ReadMemoryReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->blocks);
}

// ReadRegisters -----------------------------------------------------------------------------------

void WriteRequest(const ReadRegistersRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadRegisters, transaction_id);

  Serialize(request.id, writer);
  Serialize(request.categories, writer);
}

bool ReadReply(MessageReader* reader, ReadRegistersReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;

  *transaction_id = header.transaction_id;
  return Deserialize(reader, &reply->registers);
}

// WriteRegisters ----------------------------------------------------------------------------------

void WriteRequest(const WriteRegistersRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteRegisters, transaction_id);
  Serialize(request.id, writer);
  Serialize(request.registers, writer);
}

bool ReadReply(MessageReader* reader, WriteRegistersReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;

  *transaction_id = header.transaction_id;
  if (!Deserialize(reader, &reply->status))
    return false;
  return Deserialize(reader, &reply->registers);
}

// AddOrChangeBreakpoint ---------------------------------------------------------------------------

void WriteRequest(const AddOrChangeBreakpointRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddOrChangeBreakpoint, transaction_id);
  Serialize(request.breakpoint, writer);
}

bool ReadReply(MessageReader* reader, AddOrChangeBreakpointReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->status);
}

// RemoveBreakpoint --------------------------------------------------------------------------------

void WriteRequest(const RemoveBreakpointRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kRemoveBreakpoint, transaction_id);
  writer->WriteBytes(&request, sizeof(RemoveBreakpointRequest));
}

bool ReadReply(MessageReader* reader, RemoveBreakpointReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return true;
}

// SysInfo -----------------------------------------------------------------------------------------

void WriteRequest(const SysInfoRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kSysInfo, transaction_id);
}

bool ReadReply(MessageReader* reader, SysInfoReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadString(&reply->version) || !reader->ReadUint32(&reply->num_cpus) ||
      !reader->ReadUint32(&reply->memory_mb) || !reader->ReadUint32(&reply->hw_breakpoint_count) ||
      !reader->ReadUint32(&reply->hw_watchpoint_count)) {
    return false;
  }
  return true;
}

// ThreadStatus ------------------------------------------------------------------------------------

void WriteRequest(const ThreadStatusRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreadStatus, transaction_id);
  writer->WriteBytes(&request, sizeof(ThreadStatusRequest));
}

bool ReadReply(MessageReader* reader, ThreadStatusReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  Deserialize(reader, &reply->record);
  return true;
}

// Modules -----------------------------------------------------------------------------------------

void WriteRequest(const ModulesRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kModules, transaction_id);
  writer->WriteBytes(&request, sizeof(ModulesRequest));
}

bool ReadReply(MessageReader* reader, ModulesReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  Deserialize(reader, &reply->modules);
  return true;
}

// Address Space -----------------------------------------------------------------------------------

void WriteRequest(const AddressSpaceRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddressSpace, transaction_id);
  writer->WriteBytes(&request, sizeof(AddressSpaceRequest));
}

bool ReadReply(MessageReader* reader, AddressSpaceReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->map);
}

// JobFilter --------------------------------------------------------------------------------------

void WriteRequest(const JobFilterRequest& request, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kJobFilter, transaction_id);
  writer->WriteUint64(request.job_koid);
  return Serialize(request.filters, writer);
}

bool ReadReply(MessageReader* reader, JobFilterReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &reply->status))
    return false;
  return Deserialize(reader, &reply->matched_processes);
}

// WriteMemory -------------------------------------------------------------------------------------

void WriteRequest(const WriteMemoryRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteMemory, transaction_id);
  writer->WriteUint64(request.process_koid);
  writer->WriteUint64(request.address);
  return Serialize(request.data, writer);
}

bool ReadReply(MessageReader* reader, WriteMemoryReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->status);
}

// LoadInfoHandleTable -----------------------------------------------------------------------------

void WriteRequest(const LoadInfoHandleTableRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kLoadInfoHandleTable, transaction_id);
  writer->WriteBytes(&request, sizeof(LoadInfoHandleTableRequest));
}

bool ReadReply(MessageReader* reader, LoadInfoHandleTableReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &reply->status))
    return false;
  return Deserialize(reader, &reply->handles);
}

// UpdateGlobalSettings ---------------------------------------------------------------------------

void WriteRequest(const UpdateGlobalSettingsRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kUpdateGlobalSettings, transaction_id);
  Serialize(request.exception_strategies, writer);
}

bool ReadReply(MessageReader* reader, UpdateGlobalSettingsReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->status);
}

// ConfigAgent -------------------------------------------------------------------------------------

void WriteRequest(const ConfigAgentRequest& request, uint32_t transaction_id,
                  MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kConfigAgent, transaction_id);
  Serialize(request.actions, writer);
}

bool ReadReply(MessageReader* reader, ConfigAgentReply* reply, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &reply->results);
}

// Notifications -----------------------------------------------------------------------------------

bool ReadNotifyProcessExiting(MessageReader* reader, NotifyProcessExiting* process) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&process->timestamp))
    return false;
  if (!reader->ReadUint64(&process->process_koid))
    return false;
  if (!reader->ReadInt64(&process->return_code))
    return false;
  return true;
}

bool ReadNotifyProcessStarting(MessageReader* reader, NotifyProcessStarting* process) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&process->timestamp))
    return false;

  uint32_t type = UINT32_MAX;
  if (!reader->ReadUint32(&type) ||
      type >= static_cast<uint32_t>(NotifyProcessStarting::Type::kLast)) {
    return false;
  }
  process->type = static_cast<NotifyProcessStarting::Type>(type);

  if (!reader->ReadUint64(&process->koid))
    return false;
  if (!reader->ReadUint32(&process->component_id))
    return false;
  if (!reader->ReadString(&process->name))
    return false;
  return true;
}

bool ReadNotifyThread(MessageReader* reader, NotifyThread* notify) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&notify->timestamp))
    return false;
  return Deserialize(reader, &notify->record);
}

bool ReadNotifyException(MessageReader* reader, NotifyException* notify) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&notify->timestamp))
    return false;
  if (!Deserialize(reader, &notify->thread))
    return false;

  if (!Deserialize(reader, &notify->type))
    return false;

  if (!reader->ReadBytes(sizeof(notify->exception), &notify->exception))
    return false;

  if (!Deserialize(reader, &notify->hit_breakpoints))
    return false;
  if (!Deserialize(reader, &notify->other_affected_threads))
    return false;
  return Deserialize(reader, &notify->memory_blocks);
}

bool ReadNotifyModules(MessageReader* reader, NotifyModules* notify) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&notify->timestamp))
    return false;
  if (!reader->ReadUint64(&notify->process_koid))
    return false;

  if (!Deserialize(reader, &notify->modules))
    return false;
  return Deserialize(reader, &notify->stopped_threads);
}

bool ReadNotifyIO(MessageReader* reader, NotifyIO* notify) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  if (!reader->ReadUint64(&notify->timestamp))
    return false;

  if (!reader->ReadUint64(&notify->process_koid))
    return false;

  uint32_t type;
  if (!reader->ReadUint32(&type) || type >= static_cast<uint32_t>(NotifyIO::Type::kLast)) {
    return false;
  }
  notify->type = static_cast<NotifyIO::Type>(type);

  if (!reader->ReadString(&notify->data) || !reader->ReadBool(&notify->more_data_available)) {
    return false;
  }

  return true;
}

}  // namespace debug_ipc
