blob: 5e77cb50d03514b792492796daedbef9ee6777d4 [file] [log] [blame]
#include <systemd/sd-bus.h>
#include <sdbusplus/message/native_types.hpp>
#include <sdbusplus/utility/memory.hpp>
#include <array>
namespace sdbusplus
{
namespace message
{
namespace details
{
std::string string_path_wrapper::filename() const
{
size_t firstIndex = str.rfind('/');
// Dbus paths must start with /, if we don't find one, it's an error
if (firstIndex == std::string::npos)
{
return "";
}
firstIndex++;
// If we don't see that this was encoded by sdbusplus, return the naive
// version of the filename path.
const char* filename = str.c_str() + firstIndex;
if (*filename != '_')
{
return std::string(filename);
}
_cleanup_free_ char* out = nullptr;
int r = sd_bus_path_decode_many(filename, "%", &out);
if (r <= 0)
{
return "";
}
return std::string(out);
}
string_path_wrapper string_path_wrapper::parent_path() const
{
auto index = str.rfind('/');
if (index == std::string::npos)
{
return string_path_wrapper("/");
}
if (index <= 1)
{
return string_path_wrapper("/");
}
return str.substr(0, index);
}
string_path_wrapper string_path_wrapper::operator/(const char* extId) const
{
string_path_wrapper out;
_cleanup_free_ char* encOut = nullptr;
int ret = sd_bus_path_encode(str.c_str(), extId, &encOut);
if (ret < 0)
{
return out;
}
out.str = encOut;
size_t firstIndex = str.size();
if (str != "/")
{
firstIndex++;
}
// Attempt to encode the first character of the path. This allows the
// filename() method to "detect" that this is a path that's been encoded
// and to decode it properly. This was needed to support a number of
// paths that currently dont' have any encoding, and utilize underscores
// Ideally this, and the equivalent code in filename() would go away
// when all paths are being encoded per systemds methods.
if (out.str[firstIndex] == '_')
{
return out;
}
constexpr std::array<char, 16> hex{'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
uint8_t firstChar = static_cast<uint8_t>(*extId);
out.str[firstIndex] = '_';
std::array<char, 2> encoded{hex[(firstChar >> 4) & 0xF],
hex[firstChar & 0xF]};
out.str.insert(out.str.begin() + firstIndex + 1, encoded.begin(),
encoded.end());
return out;
}
string_path_wrapper& string_path_wrapper::operator/=(const char* extId)
{
string_path_wrapper out = this->operator/(extId);
this->str = std::move(out.str);
return *this;
}
} // namespace details
} // namespace message
} // namespace sdbusplus