10 #include "llvm/Support/Endian.h"
11 #include "llvm/Support/Error.h"
18 return llvm::make_error<llvm::StringError>(Msg,
19 llvm::inconvertibleErrorCode());
22 llvm::Expected<Chunk>
readChunk(llvm::StringRef &Stream) {
23 if (Stream.size() < 8)
24 return makeError(
"incomplete chunk header: " + llvm::Twine(Stream.size()) +
27 std::copy(Stream.begin(), Stream.begin() + 4, C.
ID.begin());
28 Stream = Stream.drop_front(4);
29 uint32_t Len = llvm::support::endian::read32le(Stream.take_front(4).begin());
30 Stream = Stream.drop_front(4);
31 if (Stream.size() < Len)
32 return makeError(
"truncated chunk: want " + llvm::Twine(Len) +
", got " +
33 llvm::Twine(Stream.size()));
34 C.
Data = Stream.take_front(Len);
35 Stream = Stream.drop_front(Len);
36 if (Len % 2 & !Stream.empty()) {
39 Stream = Stream.drop_front();
45 OS.write(C.
ID.data(), C.
ID.size());
47 llvm::support::endian::write32le(Size, C.
Data.size());
48 OS.write(Size,
sizeof(Size));
50 if (C.
Data.size() % 2)
55 llvm::Expected<File>
readFile(llvm::StringRef Stream) {
58 return RIFF.takeError();
61 if (
RIFF->Data.size() < 4)
64 std::copy(
RIFF->Data.begin(),
RIFF->Data.begin() + 4, F.Type.begin());
65 for (llvm::StringRef Body =
RIFF->Data.drop_front(4); !Body.empty();)
67 F.Chunks.push_back(*
Chunk);
69 return Chunk.takeError();
76 for (
const auto &C : F.Chunks)
77 DataLen += 4 + 4 + C.Data.size() + (C.Data.size() % 2);
80 llvm::support::endian::write32le(Size, DataLen);
81 OS.write(Size,
sizeof(Size));
82 OS.write(F.Type.data(), F.Type.size());
83 for (
const auto &C : F.Chunks)