diff --git a/cameraserver/src/main/native/cpp/cameraserver/CameraServer.cpp b/cameraserver/src/main/native/cpp/cameraserver/CameraServer.cpp index 1a4d42a2f6..afeff62ead 100644 --- a/cameraserver/src/main/native/cpp/cameraserver/CameraServer.cpp +++ b/cameraserver/src/main/native/cpp/cameraserver/CameraServer.cpp @@ -450,9 +450,9 @@ Instance::Instance() { entry.SetString(VideoModeToString(sourceIt->second.GetVideoMode())); return; } else if (wpi::starts_with(relativeKey, "Property/")) { - propName = relativeKey.substr(9); + propName = wpi::substr(relativeKey, 9); } else if (wpi::starts_with(relativeKey, "RawProperty/")) { - propName = relativeKey.substr(12); + propName = wpi::substr(relativeKey, 12); } else { return; // ignore } diff --git a/cscore/src/main/native/cpp/HttpCameraImpl.cpp b/cscore/src/main/native/cpp/HttpCameraImpl.cpp index 068393b88f..9756a5dbe3 100644 --- a/cscore/src/main/native/cpp/HttpCameraImpl.cpp +++ b/cscore/src/main/native/cpp/HttpCameraImpl.cpp @@ -208,7 +208,7 @@ wpi::HttpConnection* HttpCameraImpl::DeviceStreamConnect( if (wpi::trim(key) == "boundary") { value = wpi::trim(wpi::trim(value), '"'); // value may be quoted if (wpi::starts_with(value, "--")) { - value = value.substr(2); + value = wpi::substr(value, 2); } boundary.append(value.begin(), value.end()); } diff --git a/cscore/src/main/native/cpp/JpegUtil.cpp b/cscore/src/main/native/cpp/JpegUtil.cpp index 2e66338974..1abc01979c 100644 --- a/cscore/src/main/native/cpp/JpegUtil.cpp +++ b/cscore/src/main/native/cpp/JpegUtil.cpp @@ -4,6 +4,7 @@ #include "JpegUtil.h" +#include #include namespace cs { @@ -64,7 +65,7 @@ bool GetJpegSize(std::string_view data, int* width, int* height) { return false; } - data = data.substr(2); // Get to the first block + data = wpi::substr(data, 2); // Get to the first block for (;;) { if (data.size() < 4) { return false; // EOF @@ -89,7 +90,7 @@ bool GetJpegSize(std::string_view data, int* width, int* height) { return true; } // Go to the next block - data = data.substr(bytes[2] * 256 + bytes[3] + 2); + data = wpi::substr(data, bytes[2] * 256 + bytes[3] + 2); } } @@ -102,7 +103,7 @@ bool JpegNeedsDHT(const char* data, size_t* size, size_t* locSOF) { *locSOF = *size; // Search until SOS for DHT tag - sdata = sdata.substr(2); // Get to the first block + sdata = wpi::substr(sdata, 2); // Get to the first block for (;;) { if (sdata.size() < 4) { return false; // EOF @@ -121,7 +122,7 @@ bool JpegNeedsDHT(const char* data, size_t* size, size_t* locSOF) { *locSOF = sdata.data() - data; // SOF } // Go to the next block - sdata = sdata.substr(bytes[2] * 256 + bytes[3] + 2); + sdata = wpi::substr(sdata, bytes[2] * 256 + bytes[3] + 2); } // Only add DHT if we also found SOF (insertion point) diff --git a/cscore/src/main/native/cpp/MjpegServerImpl.cpp b/cscore/src/main/native/cpp/MjpegServerImpl.cpp index 92c23fff5e..6a8cd2b602 100644 --- a/cscore/src/main/native/cpp/MjpegServerImpl.cpp +++ b/cscore/src/main/native/cpp/MjpegServerImpl.cpp @@ -797,14 +797,14 @@ void MjpegServerImpl::ConnThread::ProcessRequest() { // compatibility, others are for Axis camera compatibility. if ((pos = req.find("POST /stream")) != std::string_view::npos) { kind = kStream; - parameters = req.substr(req.find('?', pos + 12)).substr(1); + parameters = wpi::substr(wpi::substr(req, req.find('?', pos + 12)), 1); } else if ((pos = req.find("GET /?action=stream")) != std::string_view::npos) { kind = kStream; - parameters = req.substr(req.find('&', pos + 19)).substr(1); + parameters = wpi::substr(wpi::substr(req, req.find('&', pos + 19)), 1); } else if ((pos = req.find("GET /stream.mjpg")) != std::string_view::npos) { kind = kStream; - parameters = req.substr(req.find('?', pos + 16)).substr(1); + parameters = wpi::substr(wpi::substr(req, req.find('?', pos + 16)), 1); } else if (req.find("GET /settings") != std::string_view::npos && req.find(".json") != std::string_view::npos) { kind = kGetSettings; @@ -820,7 +820,7 @@ void MjpegServerImpl::ConnThread::ProcessRequest() { } else if ((pos = req.find("GET /?action=command")) != std::string_view::npos) { kind = kCommand; - parameters = req.substr(req.find('&', pos + 20)).substr(1); + parameters = wpi::substr(wpi::substr(req, req.find('&', pos + 20)), 1); } else if (req.find("GET / ") != std::string_view::npos || req == "GET /\n") { kind = kRootPage; } else { @@ -833,7 +833,7 @@ void MjpegServerImpl::ConnThread::ProcessRequest() { pos = parameters.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_" "-=&1234567890%./"); - parameters = parameters.substr(0, pos); + parameters = wpi::substr(parameters, 0, pos); SDEBUG("command parameters: \"{}\"", parameters); // Read the rest of the HTTP request. diff --git a/cscore/src/main/native/linux/UsbCameraImpl.cpp b/cscore/src/main/native/linux/UsbCameraImpl.cpp index a08fbbc7a5..b49a93d9fe 100644 --- a/cscore/src/main/native/linux/UsbCameraImpl.cpp +++ b/cscore/src/main/native/linux/UsbCameraImpl.cpp @@ -107,7 +107,7 @@ static __u32 FromPixelFormat(VideoMode::PixelFormat pixelFormat) { static bool IsPercentageProperty(std::string_view name) { if (wpi::starts_with(name, "raw_")) { - name = name.substr(4); + name = wpi::substr(name, 4); } return name == "brightness" || name == "contrast" || name == "saturation" || name == "hue" || name == "sharpness" || name == "gain" || @@ -181,13 +181,13 @@ static bool GetVendorProduct(int dev, int* vendor, int* product) { } std::string_view readStr{readBuf}; if (auto v = wpi::parse_integer( - readStr.substr(readStr.find('v')).substr(1, 4), 16)) { + wpi::substr(wpi::substr(readStr, readStr.find('v')), 1, 4), 16)) { *vendor = v.value(); } else { return false; } if (auto v = wpi::parse_integer( - readStr.substr(readStr.find('p')).substr(1, 4), 16)) { + wpi::substr(wpi::substr(readStr, readStr.find('p')), 1, 4), 16)) { *product = v.value(); } else { return false; @@ -236,8 +236,8 @@ static bool GetDescriptionIoctl(const char* cpath, std::string* desc) { std::optional vendor; std::optional product; if (wpi::starts_with(card, "UVC Camera (") && - (vendor = wpi::parse_integer(card.substr(12, 4), 16)) && - (product = wpi::parse_integer(card.substr(17, 4), 16))) { + (vendor = wpi::parse_integer(wpi::substr(card, 12, 4), 16)) && + (product = wpi::parse_integer(wpi::substr(card, 17, 4), 16))) { std::string card2 = GetUsbNameFromId(vendor.value(), product.value()); if (!card2.empty()) { *desc = std::move(card2); @@ -283,7 +283,7 @@ static int GetDeviceNum(const char* cpath) { if (!wpi::starts_with(fn, "video")) { return -1; } - if (auto dev = wpi::parse_integer(fn.substr(5), 10)) { + if (auto dev = wpi::parse_integer(wpi::substr(fn, 5), 10)) { return dev.value(); } return -1; @@ -1635,7 +1635,8 @@ std::vector EnumerateUsbCameras(CS_Status* status) { } unsigned int dev = 0; - if (auto v = wpi::parse_integer(fname.substr(5), 10)) { + if (auto v = + wpi::parse_integer(wpi::substr(fname, 5), 10)) { dev = v.value(); } else { continue; @@ -1686,7 +1687,8 @@ std::vector EnumerateUsbCameras(CS_Status* status) { std::string fname = fs::path{target}.filename(); std::optional dev; if (wpi::starts_with(fname, "video") && - (dev = wpi::parse_integer(fname.substr(5), 10)) && + (dev = wpi::parse_integer(wpi::substr(fname, 5), + 10)) && dev.value() < retval.size()) { retval[dev.value()].otherPaths.emplace_back(path.str()); } diff --git a/cscore/src/main/native/linux/UsbCameraProperty.cpp b/cscore/src/main/native/linux/UsbCameraProperty.cpp index 149ca1b979..d6bb9804f6 100644 --- a/cscore/src/main/native/linux/UsbCameraProperty.cpp +++ b/cscore/src/main/native/linux/UsbCameraProperty.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "UsbUtil.h" @@ -93,7 +94,7 @@ static int GetStringCtrlIoctl(int fd, int id, int maximum, std::string* value) { static int SetStringCtrlIoctl(int fd, int id, int maximum, std::string_view value) { - wpi::SmallString<64> str{value.substr(0, maximum)}; + wpi::SmallString<64> str{wpi::substr(value, 0, maximum)}; struct v4l2_ext_control ctrl; struct v4l2_ext_controls ctrls; diff --git a/cscore/src/main/native/linux/UsbUtil.cpp b/cscore/src/main/native/linux/UsbUtil.cpp index afe3e4218d..7d22054c83 100644 --- a/cscore/src/main/native/linux/UsbUtil.cpp +++ b/cscore/src/main/native/linux/UsbUtil.cpp @@ -49,7 +49,7 @@ static std::string GetUsbNameFromFile(int vendor, int product) { // look for vendor at start of line if (wpi::starts_with(line, vendorStr)) { foundVendor = true; - buf += wpi::trim(line.substr(5)); + buf += wpi::trim(wpi::substr(line, 5)); buf += ' '; continue; } @@ -62,8 +62,8 @@ static std::string GetUsbNameFromFile(int vendor, int product) { } // look for product - if (wpi::starts_with(line.substr(1), productStr)) { - buf += wpi::trim(line.substr(6)); + if (wpi::starts_with(wpi::substr(line, 1), productStr)) { + buf += wpi::trim(wpi::substr(line, 6)); return buf; } } diff --git a/cscore/src/main/native/windows/UsbCameraImpl.cpp b/cscore/src/main/native/windows/UsbCameraImpl.cpp index 1a3b23044a..bf517160c0 100644 --- a/cscore/src/main/native/windows/UsbCameraImpl.cpp +++ b/cscore/src/main/native/windows/UsbCameraImpl.cpp @@ -269,7 +269,7 @@ void UsbCameraImpl::DeviceDisconnect() { static bool IsPercentageProperty(std::string_view name) { if (wpi::starts_with(name, "raw_")) - name = name.substr(4); + name = wpi::substr(name, 4); return name == "Brightness" || name == "Contrast" || name == "Saturation" || name == "Hue" || name == "Sharpness" || name == "Gain" || name == "Exposure"; diff --git a/ntcore/src/main/native/cpp/Storage_load.cpp b/ntcore/src/main/native/cpp/Storage_load.cpp index 11bbb0ed78..98046e7677 100644 --- a/ntcore/src/main/native/cpp/Storage_load.cpp +++ b/ntcore/src/main/native/cpp/Storage_load.cpp @@ -87,7 +87,7 @@ static std::pair ReadStringToken( break; } } - return {wpi::slice(source, 0, pos), source.substr(pos)}; + return {wpi::slice(source, 0, pos), wpi::substr(source, pos)}; } static int fromxdigit(char ch) { diff --git a/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp index cc519f5bad..0c28dd4b6f 100644 --- a/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp +++ b/ntcore/src/main/native/cpp/networktables/NetworkTable.cpp @@ -22,7 +22,7 @@ std::string_view NetworkTable::BasenameKey(std::string_view key) { if (slash == std::string_view::npos) { return key; } - return key.substr(slash + 1); + return wpi::substr(key, slash + 1); } std::string NetworkTable::NormalizeKey(std::string_view key, @@ -105,7 +105,7 @@ NT_EntryListener NetworkTable::AddEntryListener(TableEntryListener listener, return nt::AddEntryListener( m_inst, fmt::format("{}/", m_path), [=](const EntryNotification& event) { - auto relative_key = std::string_view{event.name}.substr(prefix_len); + auto relative_key = wpi::substr(event.name, prefix_len); if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) { return; } @@ -124,8 +124,8 @@ NT_EntryListener NetworkTable::AddEntryListener(std::string_view key, entry.GetHandle(), [=](const EntryNotification& event) { listener(const_cast(this), - std::string_view{event.name}.substr(prefix_len), entry, - event.value, event.flags); + wpi::substr(event.name, prefix_len), entry, event.value, + event.flags); }, flags); } @@ -149,12 +149,12 @@ NT_EntryListener NetworkTable::AddSubTableListener(TableListener listener, NT_EntryListener id = nt::AddEntryListener( m_inst, fmt::format("{}/", m_path), [=](const EntryNotification& event) { - auto relative_key = std::string_view{event.name}.substr(prefix_len); + auto relative_key = wpi::substr(event.name, prefix_len); auto end_sub_table = relative_key.find(PATH_SEPARATOR_CHAR); if (end_sub_table == std::string_view::npos) { return; } - auto sub_table_key = relative_key.substr(0, end_sub_table); + auto sub_table_key = wpi::substr(relative_key, 0, end_sub_table); if (notified_tables->find(sub_table_key) == notified_tables->end()) { return; } @@ -196,7 +196,7 @@ std::vector NetworkTable::GetKeys(int types) const { auto infos = GetEntryInfo(m_inst, fmt::format("{}/", m_path), types); std::scoped_lock lock(m_mutex); for (auto& info : infos) { - auto relative_key = std::string_view{info.name}.substr(prefix_len); + auto relative_key = wpi::substr(info.name, prefix_len); if (relative_key.find(PATH_SEPARATOR_CHAR) != std::string_view::npos) { continue; } @@ -210,12 +210,12 @@ std::vector NetworkTable::GetSubTables() const { std::vector keys; size_t prefix_len = m_path.size() + 1; for (auto& entry : GetEntryInfo(m_inst, fmt::format("{}/", m_path), 0)) { - auto relative_key = std::string_view{entry.name}.substr(prefix_len); + auto relative_key = wpi::substr(entry.name, prefix_len); size_t end_subtable = relative_key.find(PATH_SEPARATOR_CHAR); if (end_subtable == std::string_view::npos) { continue; } - keys.emplace_back(relative_key.substr(0, end_subtable)); + keys.emplace_back(wpi::substr(relative_key, 0, end_subtable)); } return keys; } diff --git a/ntcore/src/test/native/cpp/WireEncoderTest.cpp b/ntcore/src/test/native/cpp/WireEncoderTest.cpp index b7141127d1..b0cc664b8c 100644 --- a/ntcore/src/test/native/cpp/WireEncoderTest.cpp +++ b/ntcore/src/test/native/cpp/WireEncoderTest.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include "TestPrinters.h" #include "WireEncoder.h" #include "gtest/gtest.h" @@ -84,7 +86,7 @@ TEST_F(WireEncoderTest, Write8) { e.Write8(0x101u); // should be truncated e.Write8(0u); ASSERT_EQ(3u, e.size() - off); - ASSERT_EQ("\x05\x01\x00"sv, std::string_view(e.data(), e.size()).substr(off)); + ASSERT_EQ("\x05\x01\x00"sv, wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, Write16) { @@ -99,7 +101,7 @@ TEST_F(WireEncoderTest, Write16) { e.Write16(0u); ASSERT_EQ(8u, e.size() - off); ASSERT_EQ("\x00\x05\x00\x01\x45\x67\x00\x00"sv, - std::string_view(e.data(), e.size()).substr(off)); + wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, Write32) { @@ -117,7 +119,7 @@ TEST_F(WireEncoderTest, Write32) { ASSERT_EQ(std::string_view("\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\xab\xcd" "\x12\x34\x56\x78\x00\x00\x00\x00", 20), - std::string_view(e.data(), e.size()).substr(off)); + wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, WriteDouble) { @@ -140,7 +142,7 @@ TEST_F(WireEncoderTest, WriteDouble) { "\x00\x10\x00\x00\x00\x00\x00\x00" "\x7f\xef\xff\xff\xff\xff\xff\xff", 40), - std::string_view(e.data(), e.size()).substr(off)); + wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, WriteUleb128) { @@ -153,8 +155,7 @@ TEST_F(WireEncoderTest, WriteUleb128) { e.WriteUleb128(0x7ful); e.WriteUleb128(0x80ul); ASSERT_EQ(4u, e.size() - off); - ASSERT_EQ("\x00\x7f\x80\x01"sv, - std::string_view(e.data(), e.size()).substr(off)); + ASSERT_EQ("\x00\x7f\x80\x01"sv, wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, WriteType) { @@ -174,7 +175,7 @@ TEST_F(WireEncoderTest, WriteType) { ASSERT_EQ(nullptr, e.error()); ASSERT_EQ(8u, e.size() - off); ASSERT_EQ("\x00\x01\x02\x03\x10\x11\x12\x20"sv, - std::string_view(e.data(), e.size()).substr(off)); + wpi::substr({e.data(), e.size()}, off)); } TEST_F(WireEncoderTest, WriteTypeError) { diff --git a/wpiutil/src/main/native/cpp/HttpUtil.cpp b/wpiutil/src/main/native/cpp/HttpUtil.cpp index afce3a6e34..b8b7cc88cd 100644 --- a/wpiutil/src/main/native/cpp/HttpUtil.cpp +++ b/wpiutil/src/main/native/cpp/HttpUtil.cpp @@ -232,7 +232,7 @@ bool FindMultipartBoundary(raw_istream& is, std::string_view boundary, // Did we find the boundary? if (searchBuf[0] == '-' && searchBuf[1] == '-' && - searchBuf.substr(2) == boundary) { + wpi::substr(searchBuf, 2) == boundary) { return true; } diff --git a/wpiutil/src/main/native/cpp/MimeTypes.cpp b/wpiutil/src/main/native/cpp/MimeTypes.cpp index 082dab140c..5f5bf592ef 100644 --- a/wpiutil/src/main/native/cpp/MimeTypes.cpp +++ b/wpiutil/src/main/native/cpp/MimeTypes.cpp @@ -4,6 +4,7 @@ #include "wpi/MimeTypes.h" +#include "wpi/StringExtras.h" #include "wpi/StringMap.h" namespace wpi { @@ -53,11 +54,11 @@ std::string_view MimeTypeFromPath(std::string_view path) { auto pos = path.find_last_of("/"); if (pos != std::string_view::npos) { - path = path.substr(pos + 1); + path = wpi::substr(path, pos + 1); } auto dot_pos = path.find_last_of("."); if (dot_pos > 0 && dot_pos != std::string_view::npos) { - auto type = mimeTypes.find(path.substr(dot_pos + 1)); + auto type = mimeTypes.find(wpi::substr(path, dot_pos + 1)); if (type != mimeTypes.end()) { return type->getValue(); } diff --git a/wpiutil/src/main/native/cpp/StringExtras.cpp b/wpiutil/src/main/native/cpp/StringExtras.cpp index 45d23ea1b7..968ffc3638 100644 --- a/wpiutil/src/main/native/cpp/StringExtras.cpp +++ b/wpiutil/src/main/native/cpp/StringExtras.cpp @@ -65,7 +65,7 @@ std::string_view::size_type wpi::find_lower( std::string_view::size_type wpi::find_lower( std::string_view str, std::string_view other, std::string_view::size_type from) noexcept { - auto s = str.substr(from); + auto s = substr(str, from); while (s.size() >= other.size()) { if (starts_with_lower(s, other)) { return from; @@ -98,7 +98,7 @@ std::string_view::size_type wpi::rfind_lower(std::string_view str, } for (size_t i = str.size() - n + 1, e = 0; i != e;) { --i; - if (equals_lower(str.substr(i, n), other)) { + if (equals_lower(substr(str, i, n), other)) { return i; } } diff --git a/wpiutil/src/main/native/include/wpi/SmallString.h b/wpiutil/src/main/native/include/wpi/SmallString.h index 1d44f24ea6..da4b2e4b4e 100644 --- a/wpiutil/src/main/native/include/wpi/SmallString.h +++ b/wpiutil/src/main/native/include/wpi/SmallString.h @@ -181,21 +181,6 @@ public: } /// @} - /// @name Substring Operations - /// @{ - - /// Return a reference to the substring from [Start, Start + N). - /// - /// \param Start The index of the starting character in the substring; if - /// the index is npos or greater than the length of the string then the - /// empty substring will be returned. - /// - /// \param N The number of characters to included in the substring. If \p N - /// exceeds the number of characters remaining in the string, the string - /// suffix (starting with \p Start) will be returned. - std::string_view substr(size_t Start, size_t N = std::string_view::npos) const { - return str().substr(Start, N); - } // Extra methods. diff --git a/wpiutil/src/main/native/include/wpi/StringExtras.h b/wpiutil/src/main/native/include/wpi/StringExtras.h index 74874ffb50..9e70f525e6 100644 --- a/wpiutil/src/main/native/include/wpi/StringExtras.h +++ b/wpiutil/src/main/native/include/wpi/StringExtras.h @@ -207,12 +207,31 @@ inline std::string_view::size_type rfind_lower(std::string_view str, return rfind_lower(str, std::string_view{other}); } +/** + * Returns the substring of @p str from [start, start + n). + * + * @param start The index of the starting character in the substring; if + * the index is npos or greater than the length of the string then the + * empty substring will be returned. + * + * @param n The number of characters to included in the substring. If n + * exceeds the number of characters remaining in the string, the string + * suffix (starting with @p start) will be returned. + */ +constexpr std::string_view substr( + std::string_view str, std::string_view::size_type start, + std::string_view::size_type n = std::string_view::npos) noexcept { + auto length = str.size(); + start = (std::min)(start, length); + return {str.data() + start, (std::min)(n, length - start)}; +} + /** * Checks if @p str starts with the given @p prefix. */ constexpr bool starts_with(std::string_view str, std::string_view prefix) noexcept { - return str.substr(0, prefix.size()) == prefix; + return substr(str, 0, prefix.size()) == prefix; } /** @@ -354,6 +373,34 @@ constexpr std::string_view drop_back( return str; } +/** + * Returns a view equal to @p str but with only the first @p n + * elements remaining. If @p n is greater than the length of the + * string, the entire string is returned. + */ +constexpr std::string_view take_front( + std::string_view str, std::string_view::size_type n = 1) noexcept { + auto length = str.size(); + if (n >= length) { + return str; + } + return drop_back(str, length - n); +} + +/** + * Returns a view equal to @p str but with only the last @p n + * elements remaining. If @p n is greater than the length of the + * string, the entire string is returned. + */ +constexpr std::string_view take_back( + std::string_view str, std::string_view::size_type n = 1) noexcept { + auto length = str.size(); + if (n >= length) { + return str; + } + return drop_front(str, length - n); +} + /** * Returns a reference to the substring of @p str from [start, end). * diff --git a/wpiutil/src/main/native/include/wpi/UrlParser.h b/wpiutil/src/main/native/include/wpi/UrlParser.h index 3b6107bcdf..1932c3ef0a 100644 --- a/wpiutil/src/main/native/include/wpi/UrlParser.h +++ b/wpiutil/src/main/native/include/wpi/UrlParser.h @@ -7,6 +7,7 @@ #include +#include "wpi/StringExtras.h" #include "wpi/http_parser.h" namespace wpi { @@ -52,35 +53,35 @@ class UrlParser { } std::string_view GetSchema() const { - return m_data.substr(m_url.field_data[UF_SCHEMA].off, - m_url.field_data[UF_SCHEMA].len); + return wpi::substr(m_data, m_url.field_data[UF_SCHEMA].off, + m_url.field_data[UF_SCHEMA].len); } std::string_view GetHost() const { - return m_data.substr(m_url.field_data[UF_HOST].off, - m_url.field_data[UF_HOST].len); + return wpi::substr(m_data, m_url.field_data[UF_HOST].off, + m_url.field_data[UF_HOST].len); } unsigned int GetPort() const { return m_url.port; } std::string_view GetPath() const { - return m_data.substr(m_url.field_data[UF_PATH].off, - m_url.field_data[UF_PATH].len); + return wpi::substr(m_data, m_url.field_data[UF_PATH].off, + m_url.field_data[UF_PATH].len); } std::string_view GetQuery() const { - return m_data.substr(m_url.field_data[UF_QUERY].off, - m_url.field_data[UF_QUERY].len); + return wpi::substr(m_data, m_url.field_data[UF_QUERY].off, + m_url.field_data[UF_QUERY].len); } std::string_view GetFragment() const { - return m_data.substr(m_url.field_data[UF_FRAGMENT].off, - m_url.field_data[UF_FRAGMENT].len); + return wpi::substr(m_data, m_url.field_data[UF_FRAGMENT].off, + m_url.field_data[UF_FRAGMENT].len); } std::string_view GetUserInfo() const { - return m_data.substr(m_url.field_data[UF_USERINFO].off, - m_url.field_data[UF_USERINFO].len); + return wpi::substr(m_data, m_url.field_data[UF_USERINFO].off, + m_url.field_data[UF_USERINFO].len); } private: diff --git a/wpiutil/src/main/native/linux/MulticastServiceResolver.cpp b/wpiutil/src/main/native/linux/MulticastServiceResolver.cpp index 129fd67304..6585443e4b 100644 --- a/wpiutil/src/main/native/linux/MulticastServiceResolver.cpp +++ b/wpiutil/src/main/native/linux/MulticastServiceResolver.cpp @@ -6,6 +6,7 @@ #include "AvahiClient.h" #include "wpi/SmallString.h" +#include "wpi/StringExtras.h" #include "wpi/mutex.h" using namespace wpi; @@ -61,8 +62,9 @@ static void ResolveCallback(AvahiServiceResolver* r, AvahiIfIndex interface, // Todo make this just do key continue; } - std::string_view key = value.substr(0, splitIndex); - value = value.substr(splitIndex + 1, value.size() - splitIndex - 1); + std::string_view key = wpi::substr(value, 0, splitIndex); + value = + wpi::substr(value, splitIndex + 1, value.size() - splitIndex - 1); data.txt.emplace_back(std::pair{key, value}); } wpi::SmallString<256> outputHostName;