blob: b1cf1daf951374290773ca3df4e09f5b0ad9beb5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "RIFFTypes.h"
#include <AK/Endian.h>
#include <AK/Stream.h>
#include <AK/Try.h>
#include <AK/TypeCasts.h>
namespace Audio::RIFF {
ErrorOr<ChunkID> ChunkID::read_from_stream(Stream& stream)
{
Array<u8, chunk_id_size> id;
TRY(stream.read_until_filled(id.span()));
return ChunkID { id };
}
ErrorOr<Chunk> Chunk::read_from_stream(Stream& stream)
{
auto id = TRY(stream.read_value<ChunkID>());
u32 size = TRY(stream.read_value<LittleEndian<u32>>());
auto data = TRY(FixedArray<u8>::create(size));
TRY(stream.read_until_filled(data.span()));
// RIFF chunks may have trailing padding to align to x86 "words" (i.e. 2 bytes).
if (is<SeekableStream>(stream)) {
if (!stream.is_eof()) {
auto stream_position = TRY(static_cast<SeekableStream&>(stream).tell());
if (stream_position % 2 != 0)
TRY(static_cast<SeekableStream&>(stream).seek(1, SeekMode::FromCurrentPosition));
}
} else {
dbgln("RIFF Warning: Cannot align stream to 2-byte boundary, next chunk may be bogus!");
}
return Chunk {
id,
size,
move(data),
};
}
ErrorOr<List> List::read_from_stream(Stream& stream)
{
auto type = TRY(stream.read_value<ChunkID>());
Vector<Chunk> chunks;
while (!stream.is_eof())
TRY(chunks.try_append(TRY(stream.read_value<Chunk>())));
return List {
.type = type,
.chunks = move(chunks),
};
}
StringView ChunkID::as_ascii_string() const
{
return StringView { id_data.span() };
}
bool ChunkID::operator==(StringView const& other_string) const
{
return as_ascii_string() == other_string;
}
FixedMemoryStream Chunk::data_stream()
{
return FixedMemoryStream { data.span() };
}
}
|