mirror of
https://github.com/harfang3d/harfang3d.git
synced 2024-06-01 14:02:16 +00:00
107 lines
2.4 KiB
C++
107 lines
2.4 KiB
C++
// HARFANG(R) Copyright (C) 2022 NWNC. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
namespace hg {
|
|
|
|
class Data {
|
|
public:
|
|
Data() = default;
|
|
~Data();
|
|
|
|
explicit Data(size_t size) { Resize(size); }
|
|
|
|
Data(const Data &data) { *this = data; }
|
|
// Data(Data &&data) { *this = data; }
|
|
|
|
Data(const void *data, size_t size) { Write(data, size); }
|
|
Data(void *data, size_t size) : data_(reinterpret_cast<uint8_t *>(data)), size_(size) {}
|
|
|
|
Data &operator=(const Data &data);
|
|
// Data &operator=(Data &&data);
|
|
|
|
uint8_t *GetData() { return data_; }
|
|
const uint8_t *GetData() const { return data_; }
|
|
|
|
size_t GetSize() const { return size_; }
|
|
size_t GetCapacity() const { return capacity_; }
|
|
|
|
size_t GetCursor() const { return cursor; }
|
|
void SetCursor(size_t pos) { Reserve(cursor = pos); }
|
|
void Rewind() { SetCursor(0); }
|
|
|
|
void TakeOwnership() { Reserve(size_); }
|
|
|
|
uint8_t *GetCursorPtr() { return data_ + cursor; }
|
|
const uint8_t *GetCursorPtr() const { return data_ + cursor; }
|
|
|
|
void Reset() { size_ = cursor = 0; }
|
|
bool Empty() const { return size_ == 0; }
|
|
|
|
bool Reserve(size_t size);
|
|
bool Resize(size_t size);
|
|
|
|
bool Skip(size_t count);
|
|
|
|
size_t Write(const void *data, size_t size);
|
|
size_t Read(void *data, size_t size) const;
|
|
|
|
void Free();
|
|
|
|
private:
|
|
uint8_t *data_{nullptr};
|
|
size_t size_{0}, capacity_{0};
|
|
|
|
bool has_ownership{false};
|
|
mutable size_t cursor{0};
|
|
};
|
|
|
|
//
|
|
bool Read(Data &data, std::string &str);
|
|
bool Write(Data &data, const std::string &str);
|
|
|
|
//
|
|
template <typename T> bool Read(Data &data, T &v) { return data.Read(&v, sizeof(T)); }
|
|
|
|
template <typename T> T Read(Data &data) {
|
|
T v;
|
|
data.Read(&v, sizeof(T));
|
|
return v;
|
|
}
|
|
|
|
template <typename T> bool Write(Data &data, const T &v) { return data.Write(&v, sizeof(T)) == sizeof(T); }
|
|
|
|
//
|
|
template <typename T> struct DeferredDataWrite {
|
|
DeferredDataWrite(Data &data_) : data(data_) {
|
|
cursor = data.GetCursor();
|
|
data.Skip(sizeof(T)); // leave space for deferred write
|
|
}
|
|
|
|
void Commit(const T &v) {
|
|
const size_t seek_ = data.GetCursor();
|
|
|
|
data.SetCursor(cursor);
|
|
data.Write(&v, sizeof(T));
|
|
|
|
data.SetCursor(seek_);
|
|
}
|
|
|
|
void CommitAsChunkSize() {
|
|
const size_t chunk_size = data.GetCursor() - (cursor + sizeof(T));
|
|
Commit(T(chunk_size));
|
|
}
|
|
|
|
size_t cursor;
|
|
Data &data;
|
|
};
|
|
|
|
//
|
|
bool LoadDataFromFile(const char *path, Data &data);
|
|
bool SaveDataToFile(const char *path, const Data &data);
|
|
|
|
} // namespace hg
|