harfang3d/harfang/foundation/data.h
2022-12-07 09:51:01 +01:00

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