AK: Don't swap endianness when writing endian wrappers to stream.

This commit is contained in:
asynts 2020-08-28 18:24:00 +02:00 committed by Andreas Kling
parent 054638c355
commit e68b158a52
3 changed files with 55 additions and 26 deletions

View file

@ -26,6 +26,7 @@
#pragma once
#include <AK/Forward.h>
#include <AK/Platform.h>
namespace AK {
@ -70,10 +71,22 @@ ALWAYS_INLINE T convert_between_host_and_network_endian(T value)
return convert_between_host_and_big_endian(value);
}
template<typename T>
class LittleEndian;
template<typename T>
InputStream& operator>>(InputStream&, LittleEndian<T>&);
template<typename T>
OutputStream& operator<<(OutputStream&, LittleEndian<T>);
template<typename T>
class [[gnu::packed]] LittleEndian
{
public:
friend InputStream& operator>><T>(InputStream&, LittleEndian<T>&);
friend OutputStream& operator<<<T>(OutputStream&, LittleEndian<T>);
LittleEndian() { }
LittleEndian(T value)
@ -87,10 +100,22 @@ private:
T m_value { 0 };
};
template<typename T>
class BigEndian;
template<typename T>
InputStream& operator>>(InputStream&, BigEndian<T>&);
template<typename T>
OutputStream& operator<<(OutputStream&, BigEndian<T>);
template<typename T>
class [[gnu::packed]] BigEndian
{
public:
friend InputStream& operator>><T>(InputStream&, BigEndian<T>&);
friend OutputStream& operator<<<T>(OutputStream&, BigEndian<T>);
BigEndian() { }
BigEndian(T value)

View file

@ -76,33 +76,36 @@ class DuplexStream
, public OutputStream {
};
inline InputStream& operator>>(InputStream& stream, Bytes bytes)
{
stream.read_or_error(bytes);
return stream;
}
inline OutputStream& operator<<(OutputStream& stream, ReadonlyBytes bytes)
{
stream.write_or_error(bytes);
return stream;
}
template<typename T>
InputStream& operator>>(InputStream& stream, LittleEndian<T>& value)
{
T temporary;
stream >> temporary;
value = temporary;
return stream;
return stream >> Bytes { &value.m_value, sizeof(value.m_value) };
}
template<typename T>
InputStream& operator<<(InputStream& stream, LittleEndian<T> value)
OutputStream& operator<<(OutputStream& stream, LittleEndian<T> value)
{
stream << static_cast<T>(value);
return stream;
return stream << ReadonlyBytes { &value.m_value, sizeof(value.m_value) };
}
template<typename T>
InputStream& operator>>(InputStream& stream, BigEndian<T>& value)
{
T temporary;
stream >> temporary;
value = temporary;
return stream;
return stream >> Bytes { &value.m_value, sizeof(value.m_value) };
}
template<typename T>
InputStream& operator<<(InputStream& stream, BigEndian<T> value)
OutputStream& operator<<(OutputStream& stream, BigEndian<T> value)
{
stream << static_cast<T>(value);
return stream;
return stream << ReadonlyBytes { &value.m_value, sizeof(value.m_value) };
}
template<typename T>
@ -177,18 +180,6 @@ inline OutputStream& operator<<(OutputStream& stream, bool value)
return stream;
}
inline InputStream& operator>>(InputStream& stream, Bytes bytes)
{
stream.read_or_error(bytes);
return stream;
}
inline OutputStream& operator<<(OutputStream& stream, ReadonlyBytes bytes)
{
stream.write_or_error(bytes);
return stream;
}
class InputMemoryStream final : public InputStream {
friend InputMemoryStream& operator>>(InputMemoryStream& stream, String& string);

View file

@ -181,4 +181,17 @@ TEST_CASE(duplex_wild_seeking)
EXPECT(stream.eof());
}
TEST_CASE(read_endian_values)
{
const u8 input[] { 0, 1, 2, 3, 4, 5, 6, 7 };
InputMemoryStream stream { { input, sizeof(input) } };
LittleEndian<u32> value1;
BigEndian<u32> value2;
stream >> value1 >> value2;
EXPECT_EQ(value1, 0x03020100u);
EXPECT_EQ(value2, 0x04050607u);
}
TEST_MAIN(Stream)