Never write via structures, always write via a ByteWriter

This commit is contained in:
Jeff Epler
2022-04-22 11:03:46 -05:00
parent 00d30fe26b
commit feb5eac02e
2 changed files with 24 additions and 51 deletions

View File

@@ -6,50 +6,24 @@
// Note: The first chunk begins at byte offset 8, not 12 as given in a2r2 reference version 2.0.1
struct A2RHeader
{
char file_id[8]; // 'A2R' + FF + LF CR LF
};
#define A2R_CHUNK_INFO (0x4F464E49)
#define A2R_CHUNK_STRM (0x4D525453)
#define A2R_CHUNK_META (0x4154454D)
#define A2R_INFO_CHUNK_VERSION (1)
struct A2RChunk
{
uint32_t chunk_id_le32;
uint32_t chunk_size_le32;
uint8_t data[];
};
enum A2RDiskType {
A2R_DISK_525 = 1,
A2R_DISK_35 = 2,
};
struct A2RInfoData {
uint8_t version;
char creator[32];
uint8_t disk_type, write_protected, synchronized;
};
enum A2RCaptureType {
A2R_TIMING = 1,
A2R_BITS = 2,
A2R_XTIMING = 3,
};
struct A2RStrmData {
uint8_t location;
uint8_t capture_type;
uint32_t data_length_le32;
uint32_t estimated_loop_point_le32;
uint8_t data[];
};
extern uint8_t a2r2_fileheader[8];
extern const uint8_t a2r2_fileheader[8];
#define A2R_NS_PER_TICK (125)

View File

@@ -61,46 +61,46 @@ public:
}
private:
void writeData(const auto data, size_t size) {
_writer += Bytes(reinterpret_cast<const uint8_t*>(data), size);
}
void writeChunkAndData(uint32_t chunk_id, const auto data, size_t size) {
void writeChunkAndData(uint32_t chunk_id, const Bytes &data) {
_writer.write_le32(chunk_id);
_writer.write_le32(size);
writeData(data, size);
_writer.write_le32(data.size());
_writer += data;
}
void writeHeader() {
writeData(a2r2_fileheader, sizeof(a2r2_fileheader));
_writer += Bytes(a2r2_fileheader, sizeof(a2r2_fileheader));
}
void writeInfo() {
A2RInfoData info{
A2R_INFO_CHUNK_VERSION,
{}, // to be filled
(uint8_t)(singlesided() ? A2R_DISK_525 : A2R_DISK_35),
1,
1,
};
auto version_str_padded = fmt::format("{: <32}", "fluxengine");
assert(version_str_padded.size() == sizeof(info.creator));
memcpy(info.creator, version_str_padded.data(), sizeof(info.creator));
writeChunkAndData(A2R_CHUNK_INFO, &info, sizeof(info));
Bytes info;
auto writer = info.writer();
writer.write_8(A2R_INFO_CHUNK_VERSION);
auto version_str_padded = fmt::format("{: <32}", "Fluxengine");
assert(version_str_padded.size() == 32);
writer.append(version_str_padded);
writer.write_8(singlesided() ? A2R_DISK_525 : A2R_DISK_35);
writer.write_8(1); // write protected
writer.write_8(1); // synchronized
writeChunkAndData(A2R_CHUNK_INFO, info);
}
void writeMeta() {
std::stringstream ss;
Bytes meta;
auto writer = meta.writer();
for(auto &i : _metadata) {
ss << i.first << '\t' << i.second << '\n';
writer.append(i.first);
writer.write_8('\t');
writer.append(i.second);
writer.write_8('\n');
}
writeChunkAndData(A2R_CHUNK_META, ss.str().data(), ss.str().size());
writeChunkAndData(A2R_CHUNK_META, meta);
}
void writeStream() {
// A STRM always ends with a 255, even though this could ALSO indicate the first byte of a multi-byte sequence
_strmWriter.write_8(255);
writeChunkAndData(A2R_CHUNK_STRM, _strmBytes.cbegin(), _strmBytes.size());
writeChunkAndData(A2R_CHUNK_STRM, _strmBytes);
}
void writeFlux(int cylinder, int head, const Fluxmap& fluxmap) override
@@ -201,7 +201,6 @@ private:
private:
const A2RFluxSinkProto& _config;
A2RHeader _fileheader = {0};
Bytes _bytes;
ByteWriter _writer;
Bytes _strmBytes;
@@ -215,4 +214,4 @@ std::unique_ptr<FluxSink> FluxSink::createA2RFluxSink(const A2RFluxSinkProto& co
return std::unique_ptr<FluxSink>(new A2RFluxSink(config));
}
uint8_t a2r2_fileheader[] = {'A', '2', 'R', '2', 0xff, 0x0a, 0x0d, 0x0a };
const uint8_t a2r2_fileheader[] = {'A', '2', 'R', '2', 0xff, 0x0a, 0x0d, 0x0a };