forked from ixchow/15-466-f18-base0
-
Notifications
You must be signed in to change notification settings - Fork 0
/
read_chunk.hpp
36 lines (30 loc) · 982 Bytes
/
read_chunk.hpp
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
#pragma once
#include <iostream>
#include <vector>
#include <stdexcept>
#include <cassert>
template< typename T >
void read_chunk(std::istream &from, std::string const &magic, std::vector< T > *_to) {
assert(_to);
assert(magic.length() == 4);
auto &to = *_to;
struct ChunkHeader {
char magic[4] = {'\0', '\0', '\0', '\0'};
uint32_t size = 0;
};
static_assert(sizeof(ChunkHeader) == 8, "header is packed");
ChunkHeader header;
if (!from.read(reinterpret_cast< char * >(&header), sizeof(header))) {
throw std::runtime_error("Failed to read chunk header");
}
if (std::string(header.magic,4) != magic) {
throw std::runtime_error("Unexpected magic number in chunk");
}
if (header.size % sizeof(T) != 0) {
throw std::runtime_error("Size of chunk not divisible by element size");
}
to.resize(header.size / sizeof(T));
if (!from.read(reinterpret_cast< char * >(&to[0]), to.size() * sizeof(T))) {
throw std::runtime_error("Failed to read chunk data.");
}
}