Skip to content

Commit 55fa6a9

Browse files
committed
Changed the C file interface to C++ generic stream buffer interface.
Note that this is a major change.
1 parent 3fbdb6e commit 55fa6a9

File tree

125 files changed

+2546
-1682
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2546
-1682
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ if((CMAKE_BUILD_TYPE MATCHES "^[Rr]elease") AND MDF_BUILD_DOC)
8787
set(DOXYGEN_RECURSIVE NO)
8888
set(DOXYGEN_REPEAT_BRIEF NO)
8989
set(DOXYGEN_PROJECT_NAME "MDF Lib")
90-
set(DOXYGEN_PROJECT_NUMBER "2.2")
90+
set(DOXYGEN_PROJECT_NUMBER "2.3")
9191
set(DOXYGEN_HTML_EXTRA_STYLESHEET doxygen/utillib.css)
9292
set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs/manual)
9393
doxygen_add_docs(

include/mdf/ichannel.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ class IChannel : public IBlock {
480480
static bool GetVirtualSample(uint64_t sample, V& value) {
481481
// No need for array index here. Array is weird usage for virtual channels
482482
// as the channel value = sample.
483-
value = static_cast<V>(sample);
483+
value = static_cast<V>( static_cast<size_t>(sample) );
484484
return true;
485485
}
486486

include/mdf/idatagroup.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class IDataGroup : public IBlock {
8282
/** \brief Detaches all observers from the measurement. */
8383
void DetachAllSampleObservers() const;
8484
/** \brief Notifies the observer that a new sample record have been read.*/
85-
bool NotifySampleObservers(size_t sample, uint64_t record_id,
85+
bool NotifySampleObservers(uint64_t sample, uint64_t record_id,
8686
const std::vector<uint8_t>& record) const;
8787

8888
/** \brief Clear all temporary sample and data buffers.

include/mdf/itimestamp.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ class LocalTimestamp : public ITimestamp {
7979
[[nodiscard]] uint64_t GetUtcTimeNs() const override;
8080

8181
private:
82-
uint64_t local_timestamp_; ///< The local timestamp in nanoseconds, with
83-
///< timezone and DST offset.
82+
uint64_t local_timestamp_; ///< The local timestamp in nanoseconds, with timezone and DST offset.
8483
int16_t timezone_offset_min_ = 0; ///< The timezone offset in minutes.
8584
int16_t dst_offset_min_ = 0; ///< The daylight saving time offset in minutes.
8685
};

include/mdf/mdffactory.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ class MdfFactory {
5151
public:
5252
/** \brief Creates an MDF writer object. */
5353
static std::unique_ptr<MdfWriter> CreateMdfWriter(MdfWriterType type);
54-
/** \brief Create an MDF reader object.*/
54+
/** \brief Create an MDF file object.*/
5555
static std::unique_ptr<MdfFile> CreateMdfFile(MdfFileType type);
5656

5757
/** \brief Creates an MDF writer object. */
5858
static MdfWriter* CreateMdfWriterEx(MdfWriterType type);
59-
/** \brief Create an MDF reader object.*/
59+
/** \brief Create an MDF file object.*/
6060
static MdfFile* CreateMdfFileEx(MdfFileType type);
6161

6262
/** \brief Sets the log function. */

include/mdf/mdffile.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class MdfFile {
143143
* read in any other information as measurement information.
144144
* @param file Pointer to an opened file.
145145
*/
146-
virtual void ReadHeader(std::FILE* file) = 0;
146+
virtual void ReadHeader(std::streambuf& buffer) = 0;
147147

148148
/** \brief Reads the measurement information about the file.
149149
*
@@ -154,7 +154,7 @@ class MdfFile {
154154
*
155155
* @param file Pointer to an opened file.
156156
*/
157-
virtual void ReadMeasurementInfo(std::FILE* file) = 0;
157+
virtual void ReadMeasurementInfo(std::streambuf& buffer) = 0;
158158

159159
/** \brief Reads in all expect raw data from the file.
160160
*
@@ -167,7 +167,7 @@ class MdfFile {
167167
* @param file Pointer to an opened file.
168168
*/
169169
virtual void
170-
ReadEverythingButData(std::FILE* file) = 0;
170+
ReadEverythingButData(std::streambuf& buffer) = 0;
171171

172172
/** \brief Saves all blocks onto the file.
173173
*
@@ -178,7 +178,7 @@ class MdfFile {
178178
* @param file Pointer to an open file.
179179
* @return True on success.
180180
*/
181-
virtual bool Write(std::FILE* file) = 0;
181+
virtual bool Write(std::streambuf& buffer) = 0;
182182

183183
/** \brief Display name of the file.
184184
*
@@ -211,7 +211,7 @@ class MdfFile {
211211
void FileName(const std::string& filename);
212212

213213
/** \brief Sets the finalize state for the file. */
214-
virtual void IsFinalized(bool finalized, std::FILE* file,
214+
virtual void IsFinalized(bool finalized, std::streambuf& buffer,
215215
uint16_t standard_flags, uint16_t custom_flags) = 0;
216216
/** \brief Returns true if the file is finalized. */
217217
[[nodiscard]] virtual bool IsFinalized(uint16_t& standard_flags,

include/mdf/mdfreader.h

+36-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <string>
1010
#include <functional>
1111
#include <vector>
12+
#include <fstream>
1213

1314
#include "mdf/ichannelobserver.h"
1415
#include "mdf/mdffile.h"
@@ -67,9 +68,18 @@ void CreateChannelObserverForDataGroup(const IDataGroup& data_group,
6768
*/
6869
class MdfReader {
6970
public:
70-
explicit MdfReader(
71-
const std::string& filename); ///< Constructor that opens the file and
72-
///< read ID and HD block.
71+
/** \brief Constructor for readers using an external file.
72+
*
73+
* This constructor is used when reading from an external file. The other
74+
* way of reading from a C++ stream buffer. The latter is more complicated
75+
* but more generic as it support environment without a file block
76+
* storage.
77+
*
78+
* @param filename Full file path to the input file.
79+
*/
80+
explicit MdfReader(std::string filename);
81+
82+
explicit MdfReader(std::shared_ptr<std::streambuf>& buffer);
7383
virtual ~MdfReader(); ///< Destructor that close any open file and destructs.
7484

7585
MdfReader() = delete;
@@ -118,14 +128,21 @@ class MdfReader {
118128
[[nodiscard]] std::string ShortName()
119129
const; ///< Returns the file name without paths.
120130

121-
bool Open(); ///< Opens the file stream for reading.
131+
/** \brief Opens the internal stream buffer.
132+
*
133+
* Normally the stream buffer is an ordinary file but the use may also
134+
* attach a generic C++ stream
135+
* @return True if the stream was opened.
136+
*/
137+
[[nodiscard]] bool Open();
138+
[[nodiscard]] bool IsOpen() const;
122139
void Close(); ///< Closes the file stream.
123140

124141
bool ReadHeader(); ///< Reads the ID and the HD block.
125142
bool ReadMeasurementInfo(); ///< Reads everything but not CG and raw data.
126143
bool ReadEverythingButData(); ///< Reads all blocks but not raw data.
127144

128-
/** \brief Export the attachment data to a detination file. */
145+
/** \brief Export the attachment data to a destination file. */
129146
bool ExportAttachmentData(const IAttachment& attachment,
130147
const std::string& dest_file);
131148

@@ -184,7 +201,7 @@ class MdfReader {
184201
* bytes typical a video stream. These files tends to be huge so the
185202
* application runs out of memory.
186203
*
187-
* This function reads in VLSD stored data in smaller batcher. The
204+
* This function reads in VLSD stored data in smaller batches. The
188205
* application first reads in all offsets to the raw data. Using these offsets
189206
* the application can read in typically one sample (offset) at a time. This
190207
* tactic saves primary memory.
@@ -203,11 +220,23 @@ class MdfReader {
203220

204221

205222
private:
206-
std::FILE* file_ = nullptr; ///< Pointer to the file stream.
223+
/** \brief Internal pointer to the active stream buffer.
224+
*
225+
* Shared pointer to the C++ stream buffer. This buffer is either
226+
* created by this class (file streams) or outside the
227+
*/
228+
std::shared_ptr<std::streambuf> file_;
229+
207230
std::string filename_; ///< The file name with full path.
208231
std::unique_ptr<MdfFile> instance_; ///< Pointer to the MDF file object.
209232
int64_t index_ = 0; ///< Unique (database) file index that can be used to
210233
///< identify a file instead of its path.
234+
235+
/** \brief Reads in the
236+
*
237+
*/
238+
void VerifyMdfFile();
239+
211240
};
212241

213242
} // namespace mdf

include/mdf/mdfwriter.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ class MdfWriter {
309309

310310
virtual void CreateMdfFile() = 0; ///< Creates an MDF file
311311
virtual bool PrepareForWriting() = 0; ///< Prepare for writing.
312-
virtual void SetDataPosition(std::FILE* file); ///< Set the data position.
313-
virtual bool WriteSignalData(std::FILE* file); ///< Write an SD block.
312+
virtual void SetDataPosition(std::streambuf& file); ///< Set the data position.
313+
virtual bool WriteSignalData(std::streambuf& file); ///< Write an SD block.
314314

315315
void StopWorkThread(); ///< Stops the worker thread
316316
void WorkThread(); ///< Worker thread function
@@ -323,7 +323,7 @@ class MdfWriter {
323323
/** \brief Increment the sample counter. */
324324
void IncrementNofSamples(uint64_t record_id) const;
325325
/** \brief Set the last file position. */
326-
virtual void SetLastPosition(std::FILE* file) = 0;
326+
virtual void SetLastPosition(std::streambuf& buffer) = 0;
327327

328328

329329
private:

include/mdf/zlibutil.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ using ByteArray = std::vector<uint8_t>; ///< Defines a dynamic byte array
2323
* @param out Pointer to the output file stream.
2424
* @return True on success.
2525
*/
26-
bool Deflate(std::FILE* in, std::FILE* out); ///< Compress file to file.
26+
bool Deflate(std::streambuf& in, std::streambuf& out); ///< Compress file to file.
2727

2828
/**
2929
* Compress a byte array directly to another array.
@@ -55,13 +55,13 @@ bool Deflate(const ByteArray& buf_in,
5555
bool Deflate(const std::string& filename,
5656
ByteArray& buf_out); ///< Compress array to array.
5757

58-
bool Inflate(std::FILE* in, std::FILE* out); ///< Decompress file to file.
59-
bool Inflate(std::FILE* in, std::FILE* out,
58+
bool Inflate(std::streambuf& in, std::streambuf& out); ///< Decompress file to file.
59+
bool Inflate(std::streambuf& in, std::streambuf& out,
6060
uint64_t nof_bytes); ///< Decompress part of file to file
6161
bool Inflate(const ByteArray& in,
6262
ByteArray& out); ///< Decompress array to array.
6363
bool Inflate(const ByteArray& in,
64-
std::FILE* out); ///< Decompress array to file.
64+
std::streambuf& out); ///< Decompress array to file.
6565

6666
void Transpose(ByteArray& data,
6767
size_t record_size); ///< Transpose of an array.

mdflib/src/at4block.cpp

+44-44
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <cerrno>
88
#include <sstream>
9+
#include <fstream>
910

1011
#include "mdf/cryptoutil.h"
1112
#include "mdf/mdfhelper.h"
@@ -46,15 +47,11 @@ std::string MakeFlagString(uint16_t flag) {
4647
return s.str();
4748
}
4849

49-
bool CopyBytes(std::FILE* source, std::FILE* dest, uint64_t nof_bytes) {
50+
bool CopyBytes(std::streambuf& source, std::streambuf& dest, uint64_t nof_bytes) {
5051
uint8_t temp = 0;
5152
for (uint64_t ii = 0; ii < nof_bytes; ++ii) {
52-
if (fread(&temp, 1, 1, source) != 1) {
53-
return false;
54-
}
55-
if (fwrite(&temp, 1, 1, dest) != 1) {
56-
return false;
57-
}
53+
temp = source.sbumpc();
54+
dest.sputc(static_cast<char>(temp));
5855
}
5956
return true;
6057
}
@@ -144,27 +141,27 @@ void At4Block::GetBlockProperty(BlockPropertyList& dest) const {
144141
}
145142
}
146143

147-
size_t At4Block::Read(std::FILE* file) {
148-
size_t bytes = ReadHeader4(file);
149-
bytes += ReadNumber(file, flags_);
150-
bytes += ReadNumber(file, creator_index_);
144+
uint64_t At4Block::Read(std::streambuf& buffer) {
145+
uint64_t bytes = ReadHeader4(buffer);
146+
bytes += ReadNumber(buffer, flags_);
147+
bytes += ReadNumber(buffer, creator_index_);
151148
std::vector<uint8_t> reserved;
152-
bytes += ReadByte(file, reserved, 4);
153-
bytes += ReadByte(file, md5_, 16);
154-
bytes += ReadNumber(file, original_size_);
155-
bytes += ReadNumber(file, nof_bytes_);
149+
bytes += ReadByte(buffer, reserved, 4);
150+
bytes += ReadByte(buffer, md5_, 16);
151+
bytes += ReadNumber(buffer, original_size_);
152+
bytes += ReadNumber(buffer, nof_bytes_);
156153
// Do not read in the data BLOB at this point but store the file position for
157154
// that data, so it is fast to get the data later
158-
data_position_ = GetFilePosition(file);
155+
data_position_ = GetFilePosition(buffer);
159156

160-
filename_ = ReadTx4(file, kIndexFilename);
161-
file_type_ = ReadTx4(file, kIndexType);
162-
ReadMdComment(file, kIndexMd);
157+
filename_ = ReadTx4(buffer, kIndexFilename);
158+
file_type_ = ReadTx4(buffer, kIndexType);
159+
ReadMdComment(buffer, kIndexMd);
163160

164161
return bytes;
165162
}
166163

167-
size_t At4Block::Write(std::FILE* file) {
164+
uint64_t At4Block::Write(std::streambuf& buffer) {
168165
const bool update = FilePosition() > 0;
169166
if (update) {
170167
return block_size_;
@@ -190,8 +187,8 @@ size_t At4Block::Write(std::FILE* file) {
190187
return 0;
191188
}
192189
} else if (IsEmbedded()) {
193-
const auto buffer = FileToBuffer(filename_, data_buffer);
194-
if (!buffer) {
190+
const auto read = FileToBuffer(filename_, data_buffer);
191+
if (!read) {
195192
MDF_ERROR() << "File to buffer failure. File: " << filename;
196193
return 0;
197194
}
@@ -209,44 +206,47 @@ size_t At4Block::Write(std::FILE* file) {
209206
block_length_ = 24 + (4 * 8) + 2 + 2 + 4 + 16 + 8 + 8 + nof_bytes_;
210207
link_list_.resize(4, 0);
211208

212-
WriteTx4(file, kIndexFilename, filename_);
213-
WriteTx4(file, kIndexType, file_type_);
214-
WriteMdComment(file, kIndexMd);
209+
WriteTx4(buffer, kIndexFilename, filename_);
210+
WriteTx4(buffer, kIndexType, file_type_);
211+
WriteMdComment(buffer, kIndexMd);
215212

216-
auto bytes = MdfBlock::Write(file);
217-
bytes += WriteNumber(file, flags_);
218-
bytes += WriteNumber(file, creator_index_);
219-
bytes += WriteBytes(file, 4);
213+
uint64_t bytes = MdfBlock::Write(buffer);
214+
bytes += WriteNumber(buffer, flags_);
215+
bytes += WriteNumber(buffer, creator_index_);
216+
bytes += WriteBytes(buffer, 4);
220217
if (md5_.size() == 16) {
221-
bytes += WriteByte(file, md5_);
218+
bytes += WriteByte(buffer, md5_);
222219
} else {
223-
bytes += WriteBytes(file, 16);
220+
bytes += WriteBytes(buffer, 16);
224221
}
225-
bytes += WriteNumber(file, original_size_);
226-
bytes += WriteNumber(file, nof_bytes_);
222+
bytes += WriteNumber(buffer, original_size_);
223+
bytes += WriteNumber(buffer, nof_bytes_);
227224
data_position_ = FilePosition();
228225
if (nof_bytes_ > 0) {
229-
bytes += WriteByte(file, data_buffer);
226+
bytes += WriteByte(buffer, data_buffer);
230227
}
231-
UpdateBlockSize(file, bytes);
228+
UpdateBlockSize(buffer, bytes);
232229

233230
return bytes;
234231
}
235232

236-
void At4Block::ReadData(std::FILE* file, const std::string& dest_file) const {
237-
if (file == nullptr || data_position_ <= 0) {
233+
void At4Block::ReadData(std::streambuf& buffer,
234+
const std::string& dest_file) const {
235+
if (data_position_ <= 0) {
238236
throw std::invalid_argument("File is not opened or data position not read");
239237
}
240-
SetFilePosition(file, data_position_);
238+
SetFilePosition(buffer, data_position_);
241239
if (IsEmbedded()) {
242-
FILE* dest = nullptr;
243-
Platform::fileopen(&dest, dest_file.c_str(), "wb");
244-
if (dest == nullptr) {
240+
std::filebuf dest;
241+
dest.open( dest_file,
242+
std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
243+
if (!dest.is_open()) {
245244
throw std::ios_base::failure("Failed to open the destination file");
246245
}
247-
const bool error = IsCompressed() ? !Inflate(file, dest, nof_bytes_)
248-
: !CopyBytes(file, dest, nof_bytes_);
249-
if (const int close = fclose(dest); error || close != 0) {
246+
const bool error = IsCompressed() ? !Inflate(buffer, dest, nof_bytes_)
247+
: !CopyBytes(buffer, dest, nof_bytes_);
248+
dest.close();
249+
if ( error ) {
250250
throw std::ios_base::failure("Failed to copy correct number of bytes");
251251
}
252252
} else {

mdflib/src/at4block.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ class At4Block : public MdfBlock, public IAttachment {
5151
[[nodiscard]] bool IsCompressed() const override;
5252

5353
void GetBlockProperty(BlockPropertyList& dest) const override;
54-
size_t Read(std::FILE* file) override;
54+
uint64_t Read(std::streambuf& buffer) override;
5555

56-
void ReadData(std::FILE* file, const std::string& dest_file) const;
56+
void ReadData(std::streambuf& buffer, const std::string& dest_file) const;
5757

58-
size_t Write(std::FILE* file) override;
58+
uint64_t Write(std::streambuf& buffer) override;
5959
[[nodiscard]] std::optional<std::string> Md5() const override;
6060

6161
private:

0 commit comments

Comments
 (0)