// 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/agent_protocol.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, ProcessBreakpointSettings* settings) {
  if (!Deserialize(reader, &settings->id) || !reader->ReadUint64(&settings->address)) {
    return false;
  }
  return Deserialize(reader, &settings->address_range);
}

bool Deserialize(MessageReader* reader, AutomationOperand* operand) {
  uint32_t kind;
  uint32_t index;
  uint32_t value;

  if (!reader->ReadUint32(&kind))
    return false;
  if (!reader->ReadUint32(&index))
    return false;
  if (!reader->ReadUint32(&value))
    return false;
  operand->InitRaw(static_cast<AutomationOperandKind>(kind), index, value);
  return true;
}

bool Deserialize(MessageReader* reader, AutomationCondition* condition) {
  uint32_t kind;
  AutomationOperand operand;
  uint64_t constant;
  uint64_t mask;

  if (!reader->ReadUint32(&kind))
    return false;
  if (!Deserialize(reader, &operand))
    return false;
  if (!reader->ReadUint64(&constant))
    return false;
  if (!reader->ReadUint64(&mask))
    return false;
  condition->InitRaw(static_cast<AutomationConditionKind>(kind), operand, constant, mask);
  return true;
}

bool Deserialize(MessageReader* reader, AutomationInstruction* instruction) {
  uint32_t kind;
  AutomationOperand address;
  AutomationOperand length;
  AutomationOperand extra_1;
  AutomationOperand extra_2;
  uint32_t value;
  std::vector<AutomationCondition> conditions;

  if (!reader->ReadUint32(&kind))
    return false;
  if (!Deserialize(reader, &address))
    return false;
  if (!Deserialize(reader, &length))
    return false;
  if (!Deserialize(reader, &extra_1))
    return false;
  if (!Deserialize(reader, &extra_2))
    return false;
  if (!reader->ReadUint32(&value))
    return false;
  if (!Deserialize(reader, &conditions))
    return false;
  instruction->InitRaw(static_cast<AutomationInstructionKind>(kind), address, length, extra_1,
                       extra_2, value, std::move(conditions));
  return true;
}

bool Deserialize(MessageReader* reader, BreakpointSettings* settings) {
  if (!reader->ReadUint32(&settings->id))
    return false;

  uint32_t type;
  if (!reader->ReadUint32(&type) || type >= static_cast<uint32_t>(BreakpointType::kLast))
    return false;
  settings->type = static_cast<BreakpointType>(type);

  if (!reader->ReadString(&settings->name))
    return false;
  if (!reader->ReadBool(&settings->one_shot))
    return false;

  uint32_t stop;
  if (!reader->ReadUint32(&stop))
    return false;
  settings->stop = static_cast<Stop>(stop);

  if (!Deserialize(reader, &settings->locations))
    return false;

  if (!reader->ReadBool(&settings->has_automation))
    return false;

  return Deserialize(reader, &settings->instructions);
}

bool Deserialize(MessageReader* reader, ConfigAction* action) {
  uint32_t type = 0;
  if (!reader->ReadUint32(&type) || type >= static_cast<uint32_t>(ConfigAction::Type::kLast)) {
    return false;
  }
  action->type = static_cast<ConfigAction::Type>(type);
  if (!reader->ReadString(&action->value))
    return false;
  return true;
}

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

void Serialize(const ProcessTreeRecord& record, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(record.type));
  writer->WriteUint64(record.koid);
  writer->WriteString(record.name);
  Serialize(record.children, writer);
}

void Serialize(const ThreadRecord& record, MessageWriter* writer) {
  Serialize(record.id, writer);
  writer->WriteString(record.name);
  writer->WriteUint32(static_cast<uint32_t>(record.state));
  writer->WriteUint32(static_cast<uint32_t>(record.blocked_reason));
  writer->WriteUint32(static_cast<uint32_t>(record.stack_amount));
  Serialize(record.frames, writer);
}

void Serialize(const ProcessRecord& record, MessageWriter* writer) {
  writer->WriteUint64(record.process_koid);
  writer->WriteString(record.process_name);
  Serialize(record.threads, writer);
}

void Serialize(const MemoryBlock& block, MessageWriter* writer) {
  writer->WriteUint64(block.address);
  writer->WriteBool(block.valid);
  writer->WriteUint32(block.size);
  if (block.valid && block.size > 0)
    writer->WriteBytes(block.data.data(), block.size);
}

void Serialize(const Module& module, MessageWriter* writer) {
  writer->WriteString(module.name);
  writer->WriteUint64(module.base);
  writer->WriteUint64(module.debug_address);
  writer->WriteString(module.build_id);
}

void Serialize(const StackFrame& frame, MessageWriter* writer) {
  writer->WriteUint64(frame.ip);
  writer->WriteUint64(frame.sp);
  writer->WriteUint64(frame.cfa);
  Serialize(frame.regs, writer);
}

void Serialize(const AddressRegion& region, MessageWriter* writer) {
  writer->WriteString(region.name);
  writer->WriteUint64(region.base);
  writer->WriteUint64(region.size);
  writer->WriteUint64(region.depth);
}

void Serialize(const BreakpointStats& stats, MessageWriter* writer) {
  writer->WriteUint32(stats.id);
  writer->WriteUint32(stats.hit_count);
  writer->WriteBool(stats.should_delete);
}

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

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

void WriteReply(const HelloReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kHello, transaction_id);
  writer->WriteBytes(&reply, sizeof(HelloReply));
}

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

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

void WriteReply(const StatusReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kStatus, transaction_id);
  Serialize(reply.processes, writer);
  Serialize(reply.limbo, writer);
}

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

bool ReadRequest(MessageReader* reader, ProcessStatusRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&request->process_koid))
    return false;
  return true;
}

void WriteReply(const ProcessStatusReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kProcessStatus, transaction_id);
  Serialize(reply.status, writer);
}

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

bool ReadRequest(MessageReader* reader, LaunchRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

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

  request->inferior_type = static_cast<InferiorType>(inferior_type);
  return Deserialize(reader, &request->argv);
}

void WriteReply(const LaunchReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kLaunch, transaction_id);
  writer->WriteUint64(reply.timestamp);
  writer->WriteUint32(static_cast<uint32_t>(reply.inferior_type));
  Serialize(reply.status, writer);
  writer->WriteUint64(reply.process_id);
  writer->WriteUint64(reply.component_id);
  writer->WriteString(reply.process_name);
}

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

bool ReadRequest(MessageReader* reader, KillRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadUint64(&request->process_koid);
}

void WriteReply(const KillReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kKill, transaction_id);
  writer->WriteUint64(reply.timestamp);
  Serialize(reply.status, writer);
}

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

bool ReadRequest(MessageReader* reader, AttachRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  uint32_t type;
  if (!reader->ReadUint32(&type))
    return false;
  if (type >= static_cast<uint32_t>(TaskType::kLast))
    return false;
  request->type = static_cast<TaskType>(type);
  return reader->ReadUint64(&request->koid);
}

void WriteReply(const AttachReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAttach, transaction_id);
  writer->WriteUint64(reply.timestamp);
  writer->WriteUint64(reply.koid);
  Serialize(reply.status, writer);
  writer->WriteString(reply.name);
}

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

bool ReadRequest(MessageReader* reader, DetachRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  uint32_t type;
  if (!reader->ReadUint32(&type))
    return false;
  if (type >= static_cast<uint32_t>(TaskType::kLast))
    return false;
  request->type = static_cast<TaskType>(type);
  return reader->ReadUint64(&request->koid);
}

void WriteReply(const DetachReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kDetach, transaction_id);
  writer->WriteUint64(reply.timestamp);
  Serialize(reply.status, writer);
}

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

bool ReadRequest(MessageReader* reader, PauseRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return Deserialize(reader, &request->id);
}

void WriteReply(const PauseReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kPause, transaction_id);
  Serialize(reply.threads, writer);
}

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

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

void WriteReply(const QuitAgentReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kQuitAgent, transaction_id);
}

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

bool ReadRequest(MessageReader* reader, ResumeRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!Deserialize(reader, &request->ids))
    return false;

  uint32_t how;
  if (!reader->ReadUint32(&how))
    return false;
  if (how >= static_cast<uint32_t>(ResumeRequest::How::kLast))
    return false;
  request->how = static_cast<ResumeRequest::How>(how);

  if (!reader->ReadUint64(&request->range_begin))
    return false;
  if (!reader->ReadUint64(&request->range_end))
    return false;

  return true;
}

void WriteReply(const ResumeReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kResume, transaction_id);
}

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

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

void WriteReply(const ProcessTreeReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kProcessTree, transaction_id);
  Serialize(reply.root, writer);
}

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

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

void WriteReply(const ThreadsReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreads, transaction_id);
  Serialize(reply.threads, writer);
}

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

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

void WriteReply(const ReadMemoryReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadMemory, transaction_id);
  Serialize(reply.blocks, writer);
}

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

bool ReadRequest(MessageReader* reader, AddOrChangeBreakpointRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &request->breakpoint);
}

void WriteReply(const AddOrChangeBreakpointReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddOrChangeBreakpoint, transaction_id);
  Serialize(reply.status, writer);
}

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

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

void WriteReply(const RemoveBreakpointReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kRemoveBreakpoint, transaction_id);
}

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

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

void WriteReply(const SysInfoReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kSysInfo, transaction_id);
  writer->WriteString(reply.version);
  writer->WriteUint32(reply.num_cpus);
  writer->WriteUint32(reply.memory_mb);
  writer->WriteUint32(reply.hw_breakpoint_count);
  writer->WriteUint32(reply.hw_watchpoint_count);
}

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

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

void WriteReply(const ThreadStatusReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreadStatus, transaction_id);
  Serialize(reply.record, writer);
}

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

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

void WriteReply(const ModulesReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kModules, transaction_id);
  Serialize(reply.modules, writer);
}

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

bool ReadRequest(MessageReader* reader, JobFilterRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->job_koid))
    return false;
  return Deserialize(reader, &request->filters);
}

void WriteReply(const JobFilterReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kJobFilter, transaction_id);
  Serialize(reply.status, writer);
  Serialize(reply.matched_processes, writer);
}

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

bool ReadRequest(MessageReader* reader, WriteMemoryRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->process_koid))
    return false;
  if (!reader->ReadUint64(&request->address))
    return false;
  return Deserialize(reader, &request->data);
}

void WriteReply(const WriteMemoryReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteMemory, transaction_id);
  Serialize(reply.status, writer);
}

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

bool ReadRequest(MessageReader* reader, LoadInfoHandleTableRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadUint64(&request->process_koid);
}

void WriteReply(const LoadInfoHandleTableReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kLoadInfoHandleTable, transaction_id);
  Serialize(reply.status, writer);
  Serialize(reply.handles, writer);
}

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

bool ReadRequest(MessageReader* reader, UpdateGlobalSettingsRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return Deserialize(reader, &request->exception_strategies);
}

void WriteReply(const UpdateGlobalSettingsReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kUpdateGlobalSettings, transaction_id);
  Serialize(reply.status, writer);
}

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

bool ReadRequest(MessageReader* reader, ReadRegistersRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &request->id))
    return false;

  return Deserialize(reader, &request->categories);
}

void WriteReply(const ReadRegistersReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadRegisters, transaction_id);
  Serialize(reply.registers, writer);
}

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

bool ReadRequest(MessageReader* reader, WriteRegistersRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!Deserialize(reader, &request->id))
    return false;
  return Deserialize(reader, &request->registers);
}

void WriteReply(const WriteRegistersReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteRegisters, transaction_id);
  Serialize(reply.status, writer);
  Serialize(reply.registers, writer);
}

// Address space -----------------------------------------------------------------------------------

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

void WriteReply(const AddressSpaceReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddressSpace, transaction_id);
  Serialize(reply.map, writer);
}

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

bool ReadRequest(MessageReader* reader, ConfigAgentRequest* request, uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return Deserialize(reader, &request->actions);
}

void WriteReply(const ConfigAgentReply& reply, uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kConfigAgent, transaction_id);
  Serialize(reply.results, writer);
}

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

void WriteNotifyProcessExiting(const NotifyProcessExiting& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyProcessExiting, 0);
  writer->WriteUint64(notify.timestamp);
  writer->WriteUint64(notify.process_koid);
  writer->WriteInt64(notify.return_code);
}

void WriteNotifyProcessStarting(const NotifyProcessStarting& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyProcessStarting, 0);
  writer->WriteUint64(notify.timestamp);
  writer->WriteUint32(static_cast<uint32_t>(notify.type));
  writer->WriteUint64(notify.koid);
  writer->WriteUint32(notify.component_id);
  writer->WriteString(notify.name);
}

void WriteNotifyThread(MsgHeader::Type type, const NotifyThread& notify, MessageWriter* writer) {
  writer->WriteHeader(type, 0);
  writer->WriteUint64(notify.timestamp);
  Serialize(notify.record, writer);
}

void WriteNotifyException(const NotifyException& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyException, 0);
  writer->WriteUint64(notify.timestamp);
  Serialize(notify.thread, writer);
  writer->WriteUint32(static_cast<uint32_t>(notify.type));
  writer->WriteBytes(&notify.exception, sizeof(notify.exception));
  Serialize(notify.hit_breakpoints, writer);
  Serialize(notify.other_affected_threads, writer);
  Serialize(notify.memory_blocks, writer);
}

void WriteNotifyModules(const NotifyModules& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyModules, 0);
  writer->WriteUint64(notify.timestamp);
  writer->WriteUint64(notify.process_koid);
  Serialize(notify.modules, writer);
  Serialize(notify.stopped_threads, writer);
}

void WriteNotifyIO(const NotifyIO& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyIO, 0);
  writer->WriteUint64(notify.timestamp);
  writer->WriteUint64(notify.process_koid);
  writer->WriteUint32(static_cast<uint32_t>(notify.type));
  writer->WriteString(notify.data);
  writer->WriteBool(notify.more_data_available);
}

}  // namespace debug_ipc
