Turns out that, if we don't use functions that ensure reading until the
very end of the buffer, we only end up getting the very beginning of
samples and fill the rest with uninitialized data.
While at it, make sure that we read the data that is little endian as a
LittleEndian.
For example, consider cases where we want to propagate errors only in
specific instances:
auto result = read_data(); // something like ErrorOr<ByteBuffer>
if (result.is_error() && result.error().code() != EINTR)
continue;
auto bytes = TRY(result);
The TRY invocation will currently copy the byte buffer when the
expression (in this case, just a local variable) is stored into
_temporary_result.
This patch binds the expression to a reference to prevent such copies.
In less trival invocations (such as TRY(some_function()), this will
incur only temporary lifetime extensions, i.e. no functional change.
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
If USING_AK_GLOBALLY is not defined, the name IsLvalueReference might
not be available in the global namespace. Follow the pattern established
in LibTest to fully qualify AK types in macros to avoid this problem.
Especially if buffered streams are involved, not filling the span
completely can also mean that we just ran out of filled buffer space and
we need to refill it on the beginning of the next read call.
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so
let's rename it to A) match the name of DeprecatedString, B) write a new
FlyString class that is tied to String.
These instances were detected by searching for files that include
AK/Format.h, but don't match the regex:
\\b(CheckedFormatString|critical_dmesgln|dbgln|dbgln_if|dmesgln|FormatBu
ilder|__FormatIfSupported|FormatIfSupported|FormatParser|FormatString|Fo
rmattable|Formatter|__format_value|HasFormatter|max_format_arguments|out
|outln|set_debug_enabled|StandardFormatter|TypeErasedFormatParams|TypeEr
asedParameter|VariadicFormatParams|v_critical_dmesgln|vdbgln|vdmesgln|vf
ormat|vout|warn|warnln|warnln_if)\\b
(Without the linebreaks.)
This regex is pessimistic, so there might be more files that don't
actually use any formatting functions.
Observe that this revealed that Userland/Libraries/LibC/signal.cpp is
missing an include.
In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
The `UserSampleQueue::remaining_samples` calculates the result by
subtracting two unsigned int numbers. That can lead to integer overflow.
Add an assert to verify that the minuend is greater or equal to the
subtrahend.
Previously, trying to load a wav file in aplay or SoundPlayer with a
sample rate less than 44100 would crash in an assertion failure trying
to unchecked_append to a vector that was not resized properly.
This is to differentiate between the upcoming `AllocatingMemoryStream`,
which automatically allocates memory as needed instead of operating on a
static memory area.
This allows us to either pass a reference, which keeps compatibility
with old code, or to pass a NonnullOwnPtr, which allows us to
comfortably chain streams as usual.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
This doesn't have any immediate uses, but this adapts the code a bit
more to `Core::Stream` conventions (as most functions there use
NonnullOwnPtr to handle streams) and it makes it a bit clearer that this
pointer isn't actually supposed to be null. In fact, MP3LoaderPlugin
and FlacLoaderPlugin apparently forgot to check for that completely
before starting to decode data.
This now prepares all the needed (fallible) components before actually
constructing a LoaderPlugin object, so we are no longer filling them in
at an arbitrary later point in time.
`Bytes` is very slim, so the memory and/or performance gains from
passing it by reference isn't that big, and it passing it by value is
more compatible with xvalues, which is handy for things like
`::try_create(buffer.bytes())`.
When the visualization is set to "Album Cover", the player will now try
to load the embedded image. On failure, it defaults to a "Cover" image
file in the directory.
In Player::play_file_path, file_name_changed now needs to be executed
after that the loader have been set, to get the correct image.
This was changed with a recent move to MutexLocker, but the exact
previous behavior is safer as it holds the lock for the minimum amount
of time in both locations. We don't want to introduce these kinds of
subtle bugs.