mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-09 18:45:22 +02:00
refactoring
This commit is contained in:
134
core/src/utils/riff.cpp
Normal file
134
core/src/utils/riff.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "riff.h"
|
||||
#include <string.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace riff {
|
||||
const char* RIFF_SIGNATURE = "RIFF";
|
||||
const char* LIST_SIGNATURE = "LIST";
|
||||
const size_t RIFF_LABEL_SIZE = 4;
|
||||
|
||||
bool Writer::open(std::string path, const char form[4]) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Open file
|
||||
file = std::ofstream(path, std::ios::out | std::ios::binary);
|
||||
if (!file.is_open()) { return false; }
|
||||
|
||||
// Begin RIFF chunk
|
||||
beginRIFF(form);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Writer::isOpen() {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
return file.is_open();
|
||||
}
|
||||
|
||||
void Writer::close() {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (!isOpen()) { return; }
|
||||
|
||||
// Finalize RIFF chunk
|
||||
endRIFF();
|
||||
|
||||
// Close file
|
||||
file.close();
|
||||
}
|
||||
|
||||
void Writer::beginList(const char id[4]) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Create chunk with the LIST ID and write id
|
||||
beginChunk(LIST_SIGNATURE);
|
||||
write((uint8_t*)id, RIFF_LABEL_SIZE);
|
||||
}
|
||||
|
||||
void Writer::endList() {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (chunks.empty()) {
|
||||
throw std::runtime_error("No chunk to end");
|
||||
}
|
||||
if (memcmp(chunks.top().hdr.id, LIST_SIGNATURE, RIFF_LABEL_SIZE)) {
|
||||
throw std::runtime_error("Top chunk not LIST chunk");
|
||||
}
|
||||
|
||||
endChunk();
|
||||
}
|
||||
|
||||
void Writer::beginChunk(const char id[4]) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Create and write header
|
||||
ChunkDesc desc;
|
||||
desc.pos = file.tellp();
|
||||
memcpy(desc.hdr.id, id, sizeof(desc.hdr.id));
|
||||
desc.hdr.size = 0;
|
||||
file.write((char*)&desc.hdr, sizeof(ChunkHeader));
|
||||
|
||||
// Save descriptor
|
||||
chunks.push(desc);
|
||||
}
|
||||
|
||||
void Writer::endChunk() {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (chunks.empty()) {
|
||||
throw std::runtime_error("No chunk to end");
|
||||
}
|
||||
|
||||
// Get descriptor
|
||||
ChunkDesc desc = chunks.top();
|
||||
chunks.pop();
|
||||
|
||||
// Write size
|
||||
auto pos = file.tellp();
|
||||
auto npos = desc.pos;
|
||||
npos += 4;
|
||||
file.seekp(npos);
|
||||
file.write((char*)&desc.hdr.size, sizeof(desc.hdr.size));
|
||||
file.seekp(pos);
|
||||
|
||||
// If parent chunk, increment its size
|
||||
if (!chunks.empty()) {
|
||||
chunks.top().hdr.size += desc.hdr.size;
|
||||
}
|
||||
}
|
||||
|
||||
void Writer::write(const uint8_t* data, size_t len) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (chunks.empty()) {
|
||||
throw std::runtime_error("No chunk to write into");
|
||||
}
|
||||
file.write((char*)data, len);
|
||||
chunks.top().hdr.size += len;
|
||||
}
|
||||
|
||||
void Writer::beginRIFF(const char form[4]) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (!chunks.empty()) {
|
||||
throw std::runtime_error("Can't create RIFF chunk on an existing RIFF file");
|
||||
}
|
||||
|
||||
// Create chunk with RIFF ID and write form
|
||||
beginChunk(RIFF_SIGNATURE);
|
||||
write((uint8_t*)form, RIFF_LABEL_SIZE);
|
||||
}
|
||||
|
||||
void Writer::endRIFF() {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
if (chunks.empty()) {
|
||||
throw std::runtime_error("No chunk to end");
|
||||
}
|
||||
if (memcmp(chunks.top().hdr.id, RIFF_SIGNATURE, RIFF_LABEL_SIZE)) {
|
||||
throw std::runtime_error("Top chunk not RIFF chunk");
|
||||
}
|
||||
|
||||
endChunk();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user