Skip to content

Commit

Permalink
Split protobuf_util namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
uweseimet committed Jan 27, 2025
1 parent c98e010 commit 9f87802
Show file tree
Hide file tree
Showing 20 changed files with 478 additions and 432 deletions.
4 changes: 2 additions & 2 deletions cpp/command/command_dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
#include "command_image_support.h"
#include "command_response.h"
#include "controllers/controller_factory.h"
#include "protobuf/protobuf_util.h"
#include "protobuf/target_api_util.h"
#include "base/property_handler.h"
#include "shared/s2p_exceptions.h"

using namespace command_response;
using namespace protobuf_util;
using namespace s2p_util;
using namespace target_api_util;

bool CommandDispatcher::DispatchCommand(const CommandContext &context, PbResult &result)
{
Expand Down
4 changes: 2 additions & 2 deletions cpp/command/command_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
#include "controllers/controller_factory.h"
#include "devices/disk.h"
#include "devices/scsi_generic.h"
#include "protobuf/protobuf_util.h"
#include "protobuf/target_api_util.h"
#include "shared/s2p_exceptions.h"

using namespace protobuf_util;
using namespace s2p_util;
using namespace target_api_util;

bool CommandExecutor::ProcessDeviceCmd(const CommandContext &context, const PbDeviceDefinition &pb_device, bool dryRun)
{
Expand Down
6 changes: 3 additions & 3 deletions cpp/command/command_image_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2021-2024 Uwe Seimet
// Copyright (C) 2021-2025 Uwe Seimet
//
//---------------------------------------------------------------------------

Expand All @@ -12,10 +12,10 @@
#ifdef BUILD_STORAGE_DEVICE
#include "devices/storage_device.h"
#endif
#include "protobuf/protobuf_util.h"
#include "protobuf/target_api_util.h"

using namespace s2p_util;
using namespace protobuf_util;
using namespace target_api_util;

CommandImageSupport::CommandImageSupport()
{
Expand Down
4 changes: 2 additions & 2 deletions cpp/command/command_response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
#include "command_image_support.h"
#include "devices/disk.h"
#include "devices/scsi_generic.h"
#include "protobuf/protobuf_util.h"
#include "protobuf/target_api_util.h"
#include "shared/network_util.h"
#include "shared/s2p_version.h"

using namespace network_util;
using namespace protobuf_util;
using namespace s2p_util;
using namespace target_api_util;

namespace
{
Expand Down
6 changes: 3 additions & 3 deletions cpp/devices/host_services.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@
#include "command/command_context.h"
#include "command/command_dispatcher.h"
#include "controllers/abstract_controller.h"
#include "protobuf/protobuf_util.h"
#include "protobuf/target_api_util.h"
#include "shared/s2p_exceptions.h"
#include "page_handler.h"

using namespace std::chrono;
using namespace google::protobuf;
using namespace google::protobuf::util;
using namespace memory_util;
using namespace protobuf_util;
using namespace target_api_util;

HostServices::HostServices(int lun) : PrimaryDevice(SCHS, lun)
{
Expand Down Expand Up @@ -311,7 +311,7 @@ int HostServices::WriteData(cdb_t cdb, data_out_t buf, int, int l)

PbResult result;
CommandContext context(cmd, GetLogger());
context.SetLocale(protobuf_util::GetParam(cmd, "locale"));
context.SetLocale(target_api_util::GetParam(cmd, "locale"));
if (!dispatcher->DispatchCommand(context, result)) {
LogTrace("Failed to execute " + PbOperation_Name(cmd.operation()) + " operation");
throw ScsiException(SenseKey::ABORTED_COMMAND, Asc::INTERNAL_TARGET_FAILURE);
Expand Down
159 changes: 1 addition & 158 deletions cpp/protobuf/protobuf_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,171 +2,14 @@
//
// SCSI2Pi, SCSI device emulator and SCSI tools for the Raspberry Pi
//
// Copyright (C) 2021-2024 Uwe Seimet
// Copyright (C) 2021-2025 Uwe Seimet
//
//---------------------------------------------------------------------------

#include "protobuf_util.h"
#include <array>
#include <unistd.h>
#include "shared/s2p_exceptions.h"

using namespace s2p_util;

PbDeviceType protobuf_util::ParseDeviceType(const string &value)
{
if (PbDeviceType type; PbDeviceType_Parse(ToUpper(value), &type)) {
return type;
}

// Handle convenience device types (shortcuts)
const auto &it = DEVICE_TYPES.find(tolower(value[0]));
return it != DEVICE_TYPES.end() ? it->second : UNDEFINED;
}

PbCachingMode protobuf_util::ParseCachingMode(const string &value)
{
string v = value;
ranges::replace(v, '-', '_');

if (PbCachingMode mode; PbCachingMode_Parse(ToUpper(v), &mode)) {
return mode;
}

throw ParserException("Invalid caching mode '" + value + "'");
}

void protobuf_util::ParseParameters(PbDeviceDefinition &device, const string &params)
{
if (params.empty()) {
return;
}

// Old style parameter (filename only), for backwards compatibility and convenience
if (params.find(KEY_VALUE_SEPARATOR) == string::npos) {
SetParam(device, "file", params);
return;
}

for (const auto &p : Split(params, COMPONENT_SEPARATOR)) {
if (const auto &param = Split(p, KEY_VALUE_SEPARATOR, 2); param.size() == 2) {
SetParam(device, param[0], param[1]);
}
}
}

string protobuf_util::SetCommandParams(PbCommand &command, const string &params)
{
if (params.empty()) {
return "";
}

if (params.find(KEY_VALUE_SEPARATOR) != string::npos) {
return SetFromGenericParams(command, params);
}

switch (const auto &components = Split(params, COMPONENT_SEPARATOR, 3); components.size()) {
case 3:
SetParam(command, "operations", components[2]);
[[fallthrough]];

case 2:
SetParam(command, "file_pattern", components[1]);
SetParam(command, "folder_pattern", components[0]);
break;

case 1:
SetParam(command, "file_pattern", components[0]);
break;

default:
assert(false);
break;
}

return "";
}

string protobuf_util::SetFromGenericParams(PbCommand &command, const string &params)
{
for (const string &key_value : Split(params, COMPONENT_SEPARATOR)) {
const auto &param = Split(key_value, KEY_VALUE_SEPARATOR, 2);
if (param.size() > 1 && !param[0].empty()) {
SetParam(command, param[0], param[1]);
}
else {
return "Parameter '" + key_value + "' has to be a key/value pair";
}
}

return "";
}

void protobuf_util::SetProductData(PbDeviceDefinition &device, const string &data)
{
const auto &components = Split(data, COMPONENT_SEPARATOR, 3);
switch (components.size()) {
case 3:
device.set_revision(components[2]);
[[fallthrough]];

case 2:
device.set_product(components[1]);
[[fallthrough]];

case 1:
device.set_vendor(components[0]);
break;

default:
break;
}
}

string protobuf_util::SetIdAndLun(PbDeviceDefinition &device, const string &value)
{
int id;
int lun;
if (const string &error = ParseIdAndLun(value, id, lun); !error.empty()) {
return error;
}

device.set_id(id);
device.set_unit(lun != -1 ? lun : 0);

return "";
}

int protobuf_util::GetLunMax(PbDeviceType type)
{
return type == SAHD ? 2 : 32;
}

string protobuf_util::ListDevices(const vector<PbDevice> &devices)
{
if (devices.empty()) {
return "No devices currently attached\n";
}

vector<PbDevice> sorted_devices(devices);
ranges::sort(sorted_devices, [](const auto &a, const auto &b) {return a.id() < b.id() || a.unit() < b.unit();});

string s = "+--------+------+-------------------------------------------\n"
"| ID:LUN | Type | Image File/Device File/Description\n"
"+--------+------+-------------------------------------------\n";

for (const auto &device : sorted_devices) {
s += fmt::format("| {0}:{1:<2} | {2} | {3}{4}\n", device.id(), device.unit(),
PbDeviceType_Name(device.type()), device.file().name(),
!device.status().removed() && (device.properties().read_only() || device.status().protected_()) ?
" (READ-ONLY)" : "");
}

s += "+--------+------+-------------------------------------------\n";

return s;
}

// Serialize/Deserialize protobuf message: Length followed by the actual data.
// A little endian platform is assumed.
void protobuf_util::SerializeMessage(int fd, const google::protobuf::Message &message)
Expand Down
42 changes: 1 addition & 41 deletions cpp/protobuf/protobuf_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,16 @@
#pragma once

#include <span>
#include <unordered_map>
#include <vector>
#include "generated/target_api.pb.h"
#include <google/protobuf/message.h>

using namespace std;
using namespace s2p_interface;

namespace protobuf_util
{

static constexpr char KEY_VALUE_SEPARATOR = '=';

string GetParam(const auto &item, const string &key)
{
const auto &it = item.params().find(key);
return it != item.params().end() ? it->second : "";
}

void SetParam(auto &item, const string &key, string_view value)
{
if (!key.empty() && !value.empty()) {
auto &map = *item.mutable_params();
map[key] = value;
}
}

PbDeviceType ParseDeviceType(const string&);
PbCachingMode ParseCachingMode(const string&);
void ParseParameters(PbDeviceDefinition&, const string&);
string SetCommandParams(PbCommand&, const string&);
string SetFromGenericParams(PbCommand&, const string&);
void SetProductData(PbDeviceDefinition&, const string&);
string SetIdAndLun(PbDeviceDefinition&, const string&);
int GetLunMax(PbDeviceType);

string ListDevices(const vector<PbDevice>&);

void SerializeMessage(int, const google::protobuf::Message&);
void DeserializeMessage(int, google::protobuf::Message&);
size_t ReadBytes(int, span<byte>);
size_t WriteBytes(int, span<uint8_t>);

inline static const unordered_map<int, PbDeviceType> DEVICE_TYPES = {
{ 'c', SCCD },
{ 'd', SCDP },
{ 'h', SCHD },
{ 'l', SCLP },
{ 'm', SCMO },
{ 'r', SCRM },
{ 's', SCHS },
{ 't', SCTP }
};
}
Loading

0 comments on commit 9f87802

Please sign in to comment.