C_runtime/blob.cpp
author Edouard Tisserant <edouard@beremiz.fr>
Mon, 30 Sep 2024 16:21:11 +0200
changeset 4023 b344393859df
parent 3940 934bd46a7500
permissions -rw-r--r--
MQTT: Add status global variable MQTT_STATUS_n, one per MQTT client
3940
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     1
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     2
#include <stdlib.h>
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     3
#include <errno.h>
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     4
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     5
#include "blob.hpp"
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     6
#include <unistd.h>
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     7
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     8
Blob::Blob(uint8_t *seedData, size_t seedLength)
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     9
{
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    10
    // Create a temporary file to store blob data
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    11
    // not using tmpfile() because we need to know the filename
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    12
    // for later renaming and avoid deletion on close
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    13
    
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    14
    // Assume that a tmp directory exists in the current directory
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    15
    uint8_t template_name[] = "tmp/blobXXXXXX";
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    16
    int fd = mkstemp((char *)template_name);
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    17
    if (fd == -1) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    18
        throw errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    19
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    20
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    21
    // Open file for stdlib I/O
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    22
    m_file = fdopen(fd, "w+");
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    23
    if (m_file == NULL) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    24
        throw errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    25
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    26
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    27
    // Save a copy of the filename
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    28
    m_filename = (char *)template_name;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    29
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    30
    // Seed the MD5 hash with the seed data
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    31
    md5.update(seedData, seedLength);
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    32
}
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    33
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    34
Blob::~Blob() {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    35
    if (m_file != NULL) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    36
        std::fclose(m_file);
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    37
        std::remove(m_filename.c_str());
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    38
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    39
}
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    40
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    41
MD5::digest_t Blob::digest() {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    42
    return md5.digest();
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    43
}
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    44
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    45
uint32_t Blob::appendChunk(uint8_t *data, size_t length) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    46
    // Write data to file
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    47
    if (std::fwrite(data, 1, length, m_file) != length) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    48
        return errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    49
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    50
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    51
    // Update MD5 hash
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    52
    md5.update(data, length);
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    53
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    54
    return 0;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    55
}
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    56
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    57
uint32_t Blob::asFile(std::filesystem::path &filename)
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    58
{
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    59
    // Flush file
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    60
    if (std::fflush(m_file) != 0) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    61
        return errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    62
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    63
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    64
    // Sync file to disk
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    65
    if (fsync(fileno(m_file)) != 0) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    66
        return errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    67
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    68
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    69
    // Close file
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    70
    if (std::fclose(m_file) != 0) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    71
        return errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    72
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    73
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    74
    m_file = NULL;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    75
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    76
    // Rename temp file to final file
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    77
    if (std::rename(m_filename.c_str(), filename.c_str()) != 0) {
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    78
        return errno;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    79
    }
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    80
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    81
    return 0;
934bd46a7500 C++ runtime: WIP: untested PLCObject implementation. Still missing tracing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    82
}