Mantid
Loading...
Searching...
No Matches
BitStream.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2022 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7// BitStream.h
8// Helper to read bytewise and bitwise information from a binary file.
9// @author Joachim Coenen, Thomas Mueller Jülich Centre for Neutron Science
10// @date 2022-01-10
11#ifndef MANTID_DATAHANDLING_BIT_STREAM_H_
12#define MANTID_DATAHANDLING_BIT_STREAM_H_
13
14#include <boost/endian/conversion.hpp>
15#include <fstream>
16#include <sys/stat.h>
17#include <vector>
18
20public:
21 explicit FileByteStream(const std::string &filename)
22 : stream_(filename, std::ios_base::binary), fileSize_(static_cast<size_t>(getFileSize(filename))) {
23 stream_.exceptions(std::ifstream::eofbit);
24 }
25
26private:
27 std::ifstream stream_;
28 const uint64_t fileSize_;
29
30 long getFileSize(std::string filename) {
31 struct stat stat_buf;
32 int rc = stat(filename.c_str(), &stat_buf);
33 return rc == 0 ? stat_buf.st_size : -1;
34 }
35
36 template <typename T> inline char *getResultPointer(T *const result, const std::size_t &bytecount) const {
37 return reinterpret_cast<char *>(result) + sizeof(T) - std::min(sizeof(T), bytecount);
38 }
39
40public:
41 template <typename T> inline FileByteStream &readRaw(T &result, const std::size_t &bytecount) {
42 stream_.read(getResultPointer(&result, bytecount), bytecount);
43 return *this;
44 }
45
46 template <std::size_t bytecount, typename T> inline FileByteStream &readRaw(T &result) {
47 static_assert(sizeof(T) >= bytecount, "byte count of result needs to be greater or equal to bytecount");
48 stream_.read(getResultPointer(&result, bytecount), bytecount);
49 return *this;
50 }
51
52 template <typename T> inline FileByteStream &readRaw(T &result) { return readRaw<sizeof(T)>(result); }
53
54 template <typename T> inline T readRaw(T &&result) {
55 readRaw<sizeof(result)>(result);
56 return result;
57 }
58
59 inline uint8_t peek() { return static_cast<uint8_t>(stream_.peek()); }
60
61 bool eof() const { return stream_.eof(); }
62
63 template <size_t bytecount> inline FileByteStream &skip() {
64 stream_.ignore(bytecount);
65 return *this;
66 }
67
68 std::streamsize gcount() const { return stream_.gcount(); }
69 template <typename T> FileByteStream &operator>>(T &val) { return read(val); }
70
71 uint64_t fileSize() const { return fileSize_; }
72};
73
75public:
76 explicit VectorByteStream(const std::vector<uint8_t> &vector) : pos(vector.begin()), end(vector.end()) {}
77
78private:
79 typename std::vector<uint8_t>::const_iterator pos;
80 typename std::vector<uint8_t>::const_iterator end;
81
82 template <typename T> inline char *getResultPointer(T *const result, const std::size_t &bytecount) const {
83 return reinterpret_cast<char *>(result) + sizeof(T) - bytecount;
84 }
85
86 inline void streamread(char *dest, const std::size_t &bytecount) {
87 std::copy(pos, pos + static_cast<long>(bytecount), dest);
88 pos += static_cast<long>(bytecount);
89 }
90
91 inline void streamignore(const std::size_t &bytecount) { pos += static_cast<long>(bytecount); }
92
93 inline unsigned streampeek() const { return *pos; }
94
95 inline bool streameof() const { return pos >= end; }
96
97public:
98 template <typename T> inline VectorByteStream &readRaw(T &result, const std::size_t &bytecount) {
99
100 streamread(getResultPointer(&result, bytecount), bytecount);
101 return *this;
102 }
103
104 template <std::size_t bytecount, typename T> inline VectorByteStream &readRaw(T &result) {
105 static_assert(sizeof(T) >= bytecount, "byte count of result needs to be greater or equal to bytecount");
106 streamread(getResultPointer(&result, bytecount), bytecount);
107 return *this;
108 }
109
110 template <typename T> inline VectorByteStream &readRaw(T &result) { return readRaw<sizeof(T)>(result); }
111
112 template <typename T> inline T readRaw(T &&result) {
113 readRaw<sizeof(result)>(result);
114 return result;
115 }
116
117 template <std::size_t bytecount, typename T> inline VectorByteStream &read(T &result) {
118 readRaw<bytecount>(result);
119 result = boost::endian::conditional_reverse<boost::endian::order::big, boost::endian::order::native>(result);
120 return *this;
121 }
122
123 inline uint8_t peek() { return static_cast<uint8_t>(streampeek()); }
124
125 bool eof() const { return streameof(); }
126
127 template <size_t bytecount> inline VectorByteStream &skip() {
128 streamignore(bytecount);
129 return *this;
130 }
131
132 template <typename T> VectorByteStream &operator>>(T &val) { return read(val); }
133};
134
135#endif /* MANTID_DATAHANDLING_BIT_STREAM_H_ */
FileByteStream & skip()
Definition: BitStream.h:63
bool eof() const
Definition: BitStream.h:61
uint8_t peek()
Definition: BitStream.h:59
std::ifstream stream_
Definition: BitStream.h:27
FileByteStream & operator>>(T &val)
Definition: BitStream.h:69
FileByteStream & readRaw(T &result, const std::size_t &bytecount)
Definition: BitStream.h:41
uint64_t fileSize() const
Definition: BitStream.h:71
FileByteStream(const std::string &filename)
Definition: BitStream.h:21
FileByteStream & readRaw(T &result)
Definition: BitStream.h:46
FileByteStream & readRaw(T &result)
Definition: BitStream.h:52
T readRaw(T &&result)
Definition: BitStream.h:54
char * getResultPointer(T *const result, const std::size_t &bytecount) const
Definition: BitStream.h:36
const uint64_t fileSize_
Definition: BitStream.h:28
std::streamsize gcount() const
Definition: BitStream.h:68
long getFileSize(std::string filename)
Definition: BitStream.h:30
std::vector< uint8_t >::const_iterator pos
Definition: BitStream.h:79
T readRaw(T &&result)
Definition: BitStream.h:112
VectorByteStream & readRaw(T &result)
Definition: BitStream.h:110
VectorByteStream & read(T &result)
Definition: BitStream.h:117
VectorByteStream(const std::vector< uint8_t > &vector)
Definition: BitStream.h:76
unsigned streampeek() const
Definition: BitStream.h:93
uint8_t peek()
Definition: BitStream.h:123
VectorByteStream & skip()
Definition: BitStream.h:127
char * getResultPointer(T *const result, const std::size_t &bytecount) const
Definition: BitStream.h:82
VectorByteStream & readRaw(T &result, const std::size_t &bytecount)
Definition: BitStream.h:98
bool eof() const
Definition: BitStream.h:125
std::vector< uint8_t >::const_iterator end
Definition: BitStream.h:80
void streamignore(const std::size_t &bytecount)
Definition: BitStream.h:91
VectorByteStream & readRaw(T &result)
Definition: BitStream.h:104
bool streameof() const
Definition: BitStream.h:95
VectorByteStream & operator>>(T &val)
Definition: BitStream.h:132
void streamread(char *dest, const std::size_t &bytecount)
Definition: BitStream.h:86
STL namespace.