Core/PacketIO: Use std::string_view to read strings from ByteBuffer

This commit is contained in:
Shauren
2024-08-03 13:40:17 +02:00
parent 2bd96253f3
commit d72e91bee2
4 changed files with 55 additions and 39 deletions

View File

@@ -21,6 +21,7 @@
#include "Log.h"
#include "Util.h"
#include <utf8.h>
#include <algorithm>
#include <sstream>
#include <cmath>
@@ -33,7 +34,7 @@ ByteBufferPositionException::ByteBufferPositionException(size_t pos, size_t size
{
}
ByteBufferInvalidValueException::ByteBufferInvalidValueException(char const* type, char const* value)
ByteBufferInvalidValueException::ByteBufferInvalidValueException(char const* type, std::string_view value)
: ByteBufferException(Trinity::StringFormat("Invalid {} value ({}) found in ByteBuffer", type, value))
{
}
@@ -54,34 +55,39 @@ ByteBuffer& ByteBuffer::operator>>(double& value)
return *this;
}
std::string ByteBuffer::ReadCString(bool requireValidUtf8 /*= true*/)
std::string_view ByteBuffer::ReadCString(bool requireValidUtf8 /*= true*/)
{
std::string value;
while (rpos() < size()) // prevent crash at wrong string format in packet
{
char c = read<char>();
if (c == 0)
break;
value += c;
}
if (_rpos >= size())
throw ByteBufferPositionException(_rpos, 1, size());
ResetBitPos();
char const* begin = reinterpret_cast<char const*>(_storage.data()) + _rpos;
char const* end = reinterpret_cast<char const*>(_storage.data()) + size();
char const* stringEnd = std::ranges::find(begin, end, '\0');
if (stringEnd == end)
throw ByteBufferPositionException(size(), 1, size());
std::string_view value(begin, stringEnd);
_rpos += value.length() + 1;
if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
throw ByteBufferInvalidValueException("string", value.c_str());
throw ByteBufferInvalidValueException("string", value);
return value;
}
std::string ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/)
std::string_view ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/)
{
if (_rpos + length > size())
throw ByteBufferPositionException(_rpos, length, size());
ResetBitPos();
if (!length)
return std::string();
return {};
std::string value(reinterpret_cast<char const*>(&_storage[_rpos]), length);
std::string_view value(reinterpret_cast<char const*>(&_storage[_rpos]), length);
_rpos += length;
if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
throw ByteBufferInvalidValueException("string", value.c_str());
throw ByteBufferInvalidValueException("string", value);
return value;
}

View File

@@ -49,7 +49,7 @@ public:
class TC_SHARED_API ByteBufferInvalidValueException : public ByteBufferException
{
public:
ByteBufferInvalidValueException(char const* type, char const* value);
ByteBufferInvalidValueException(char const* type, std::string_view value);
};
class TC_SHARED_API ByteBuffer
@@ -509,9 +509,9 @@ class TC_SHARED_API ByteBuffer
append(str, len);
}
std::string ReadCString(bool requireValidUtf8 = true);
std::string_view ReadCString(bool requireValidUtf8 = true);
std::string ReadString(uint32 length, bool requireValidUtf8 = true);
std::string_view ReadString(uint32 length, bool requireValidUtf8 = true);
uint8* contents()
{