blob: 50edeee478d9388ffbbd1a7394f376962ccfe455 [file] [log] [blame]
// Copyright 2020 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 "tools/fidlcat/lib/event.h"
#include "tools/fidlcat/lib/syscall_decoder_dispatcher.h"
namespace fidlcat {
void FidlcatPrinter::DisplayHandle(const zx_handle_info_t& handle) {
decoder_->DisplayHandle(handle, colors(), os());
}
void FidlcatPrinter::DisplayStatus(zx_status_t status) {
if (status == ZX_OK) {
(*this) << fidl_codec::Green;
} else {
(*this) << fidl_codec::Red;
}
(*this) << fidl_codec::StatusName(status) << fidl_codec::ResetColor;
}
bool FidlcatPrinter::DisplayReturnedValue(SyscallReturnType type, int64_t returned_value) {
switch (type) {
case SyscallReturnType::kNoReturn:
case SyscallReturnType::kVoid:
return false;
case SyscallReturnType::kStatus:
(*this) << "-> ";
DisplayStatus(static_cast<zx_status_t>(returned_value));
break;
case SyscallReturnType::kTicks:
(*this) << "-> " << fidl_codec::Green << "ticks" << fidl_codec::ResetColor << ": "
<< fidl_codec::Blue << static_cast<uint64_t>(returned_value)
<< fidl_codec::ResetColor;
break;
case SyscallReturnType::kTime:
(*this) << "-> " << fidl_codec::Green << "time" << fidl_codec::ResetColor << ": ";
DisplayTime(static_cast<zx_time_t>(returned_value));
break;
case SyscallReturnType::kUint32:
(*this) << "-> " << fidl_codec::Blue << static_cast<uint32_t>(returned_value)
<< fidl_codec::ResetColor;
break;
case SyscallReturnType::kUint64:
(*this) << "-> " << fidl_codec::Blue << static_cast<uint64_t>(returned_value)
<< fidl_codec::ResetColor;
break;
}
return true;
}
void FidlcatPrinter::DisplayInline(
const std::vector<std::unique_ptr<fidl_codec::StructMember>>& members,
const std::map<const fidl_codec::StructMember*, std::unique_ptr<fidl_codec::Value>>& values) {
(*this) << '(';
const char* separator = "";
for (const auto& member : members) {
auto it = values.find(member.get());
if (it == values.end())
continue;
(*this) << separator << member->name() << ":" << fidl_codec::Green << member->type()->Name()
<< fidl_codec::ResetColor << ": ";
it->second->PrettyPrint(member->type(), *this);
separator = ", ";
}
(*this) << ")";
}
void FidlcatPrinter::DisplayOutline(
const std::vector<std::unique_ptr<fidl_codec::StructMember>>& members,
const std::map<const fidl_codec::StructMember*, std::unique_ptr<fidl_codec::Value>>& values) {
fidl_codec::Indent indent(*this);
for (const auto& member : members) {
auto it = values.find(member.get());
if (it == values.end())
continue;
auto fidl_message_value = it->second->AsFidlMessageValue();
if (fidl_message_value != nullptr) {
it->second->PrettyPrint(member->type(), *this);
} else {
(*this) << member->name() << ":" << fidl_codec::Green << member->type()->Name()
<< fidl_codec::ResetColor << ": ";
it->second->PrettyPrint(member->type(), *this);
(*this) << '\n';
}
}
}
void InvokedEvent::PrettyPrint(FidlcatPrinter& printer) const {
printer << syscall()->name();
printer.DisplayInline(syscall()->input_inline_members(), inline_fields());
printer << '\n';
printer.DisplayOutline(syscall()->input_outline_members(), outline_fields());
}
void OutputEvent::PrettyPrint(FidlcatPrinter& printer) const {
fidl_codec::Indent indent(printer);
if (!printer.DisplayReturnedValue(syscall()->return_type(), returned_value_)) {
return;
}
// Adds the inline output arguments (if any).
if (!inline_fields().empty()) {
printer << ' ';
printer.DisplayInline(syscall()->output_inline_members(), inline_fields());
}
printer << '\n';
printer.DisplayOutline(syscall()->output_outline_members(), outline_fields());
}
} // namespace fidlcat