mirror of
https://github.com/RGBCube/serenity
synced 2025-06-03 00:18:12 +00:00
AK: Don't swap endianness when writing endian wrappers to stream.
This commit is contained in:
parent
054638c355
commit
e68b158a52
3 changed files with 55 additions and 26 deletions
25
AK/Endian.h
25
AK/Endian.h
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Forward.h>
|
||||||
#include <AK/Platform.h>
|
#include <AK/Platform.h>
|
||||||
|
|
||||||
namespace AK {
|
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);
|
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>
|
template<typename T>
|
||||||
class [[gnu::packed]] LittleEndian
|
class [[gnu::packed]] LittleEndian
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
friend InputStream& operator>><T>(InputStream&, LittleEndian<T>&);
|
||||||
|
friend OutputStream& operator<<<T>(OutputStream&, LittleEndian<T>);
|
||||||
|
|
||||||
LittleEndian() { }
|
LittleEndian() { }
|
||||||
|
|
||||||
LittleEndian(T value)
|
LittleEndian(T value)
|
||||||
|
@ -87,10 +100,22 @@ private:
|
||||||
T m_value { 0 };
|
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>
|
template<typename T>
|
||||||
class [[gnu::packed]] BigEndian
|
class [[gnu::packed]] BigEndian
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
friend InputStream& operator>><T>(InputStream&, BigEndian<T>&);
|
||||||
|
friend OutputStream& operator<<<T>(OutputStream&, BigEndian<T>);
|
||||||
|
|
||||||
BigEndian() { }
|
BigEndian() { }
|
||||||
|
|
||||||
BigEndian(T value)
|
BigEndian(T value)
|
||||||
|
|
43
AK/Stream.h
43
AK/Stream.h
|
@ -76,33 +76,36 @@ class DuplexStream
|
||||||
, public OutputStream {
|
, 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>
|
template<typename T>
|
||||||
InputStream& operator>>(InputStream& stream, LittleEndian<T>& value)
|
InputStream& operator>>(InputStream& stream, LittleEndian<T>& value)
|
||||||
{
|
{
|
||||||
T temporary;
|
return stream >> Bytes { &value.m_value, sizeof(value.m_value) };
|
||||||
stream >> temporary;
|
|
||||||
value = temporary;
|
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
InputStream& operator<<(InputStream& stream, LittleEndian<T> value)
|
OutputStream& operator<<(OutputStream& stream, LittleEndian<T> value)
|
||||||
{
|
{
|
||||||
stream << static_cast<T>(value);
|
return stream << ReadonlyBytes { &value.m_value, sizeof(value.m_value) };
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
InputStream& operator>>(InputStream& stream, BigEndian<T>& value)
|
InputStream& operator>>(InputStream& stream, BigEndian<T>& value)
|
||||||
{
|
{
|
||||||
T temporary;
|
return stream >> Bytes { &value.m_value, sizeof(value.m_value) };
|
||||||
stream >> temporary;
|
|
||||||
value = temporary;
|
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
InputStream& operator<<(InputStream& stream, BigEndian<T> value)
|
OutputStream& operator<<(OutputStream& stream, BigEndian<T> value)
|
||||||
{
|
{
|
||||||
stream << static_cast<T>(value);
|
return stream << ReadonlyBytes { &value.m_value, sizeof(value.m_value) };
|
||||||
return stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -177,18 +180,6 @@ inline OutputStream& operator<<(OutputStream& stream, bool value)
|
||||||
return stream;
|
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 {
|
class InputMemoryStream final : public InputStream {
|
||||||
friend InputMemoryStream& operator>>(InputMemoryStream& stream, String& string);
|
friend InputMemoryStream& operator>>(InputMemoryStream& stream, String& string);
|
||||||
|
|
||||||
|
|
|
@ -181,4 +181,17 @@ TEST_CASE(duplex_wild_seeking)
|
||||||
EXPECT(stream.eof());
|
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)
|
TEST_MAIN(Stream)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue