This was weird. It turns out these class were using int indexes and
sizes despite being derived from Vector which uses size_t.
Make the universe right again by using size_t here as well.
All users of this mechanism have been switched to anonymous files and
passing file descriptors with sendfd()/recvfd().
Shbufs got us where we are today, but it's time we say good-bye to them
and welcome a much more idiomatic replacement. :^)
This is useful for collecting statistics, e.g.
Atomic<unsigned, MemoryOrder::memory_order_relaxed> would allow
using operators such as ++ to use relaxed semantics throughout
without having to explicitly call fetch_add with the memory order.
Problem:
- Building with clang is broken because of the `struct` vs `class`
mismatch between the definition and declaration.
Solution:
- Change `class` to `struct` in the forward declaration.
There are three classes avaliable that share the functionality of
BufferStream:
1. InputMemoryStream is for reading from static buffers. Example:
Bytes input = /* ... */;
InputMemoryStream stream { input };
LittleEndian<u32> little_endian_value;
input >> little_endian_value;
u32 host_endian_value;
input >> host_endian_value;
SomeComplexStruct complex_struct;
input >> Bytes { &complex_struct, sizeof(complex_struct) };
2. OutputMemoryStream is for writing to static buffers. Example:
Array<u8, 4096> buffer;
OutputMemoryStream stream;
stream << LittleEndian<u32> { 42 };
stream << ReadonlyBytes { &complex_struct, sizeof(complex_struct) };
foo(stream.bytes());
3. DuplexMemoryStream for writing to dynamic buffers, can also be used
as an intermediate buffer by reading from it directly. Example:
DuplexMemoryStream stream;
stream << NetworkOrdered<u32> { 13 };
stream << NetowkrOrdered<u64> { 22 };
NetworkOrdered<u32> value;
stream >> value;
ASSERT(value == 13);
foo(stream.copy_into_contiguous_buffer());
Unlike BufferStream these streams do not use a fixed endianness
(BufferStream used little endian) these have to be explicitly specified.
There are helper types in <AK/Endian.h>.
OutputMemoryStream was originally a proxy for DuplexMemoryStream that
did not expose any reading API.
Now I need to add another class that is like OutputMemoryStream but only
for static buffers. My first idea was to make OutputMemoryStream do that
too, but I think it's much better to have a distinct class for that.
I originally wanted to call that class FixedOutputMemoryStream but that
name is really cumbersome and it's a bit unintuitive because
InputMemoryStream is already reading from a fixed buffer.
So let's just use DuplexMemoryStream instead of OutputMemoryStream for
any dynamic stuff and create a new OutputMemoryStream for static
buffers.
This class is similar to BufferStream because it is possible to both
read and write to it. However, it differs in the following ways:
- DuplexMemoryStream keeps a history of 64KiB and discards the rest,
BufferStream always keeps everything around.
- DuplexMemoryStream tracks reading and writing seperately, the
following is valid:
DuplexMemoryStream stream;
stream << 42;
int value;
stream >> value;
For BufferStream it would read:
BufferStream stream;
stream << 42;
int value;
stream.seek(0);
stream >> value;
In the future I would like to replace all usages of BufferStream with
InputMemoryStream, OutputMemoryStream (doesn't exist yet) and
DuplexMemoryStream. For now I just add DuplexMemoryStream though.
FlyString is a flyweight string class that wraps a RefPtr<StringImpl>
known to be unique among the set of FlyStrings. The class is very
unoptimized at the moment.
When to use FlyString:
- When you want O(1) string comparison
- When you want to deduplicate a lot of identical strings
When not to use FlyString:
- For strings that don't need either of the above features
- For strings that are likely to be unique
You can now #include <AK/Forward.h> to get most of the AK types as
forward declarations.
Header dependency explosion is one of the main contributors to compile
times at the moment, so this is a step towards smaller include graphs.