Blob::Blob(uint8_t *seedData, size_t seedLength)
// Create a temporary file to store blob data
// not using tmpfile() because we need to know the filename
// for later renaming and avoid deletion on close
// Assume that a tmp directory exists in the current directory
uint8_t template_name[] = "tmp/blobXXXXXX";
int fd = mkstemp((char *)template_name);
// Open file for stdlib I/O
m_file = fdopen(fd, "w+");
// Save a copy of the filename
m_filename = (char *)template_name;
// Seed the MD5 hash with the seed data
md5.update(seedData, seedLength);
std::remove(m_filename.c_str());
MD5::digest_t Blob::digest() {
uint32_t Blob::appendChunk(uint8_t *data, size_t length) {
if (std::fwrite(data, 1, length, m_file) != length) {
md5.update(data, length);
uint32_t Blob::asFile(std::filesystem::path &filename)
if (std::fflush(m_file) != 0) {
if (fsync(fileno(m_file)) != 0) {
if (std::fclose(m_file) != 0) {
// Rename temp file to final file
if (std::rename(m_filename.c_str(), filename.c_str()) != 0) {