mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Merge pull request #59 from davidgiven/writer
Do some work towards better write support.
This commit is contained in:
@@ -24,6 +24,7 @@ public:
|
||||
};
|
||||
|
||||
extern void setHardwareFluxReaderRevolutions(int revolutions);
|
||||
extern void setHardwareFluxReaderDensity(bool high_density);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
#include "fluxmap.h"
|
||||
#include "usb.h"
|
||||
#include "fluxreader.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
static IntFlag revolutions(
|
||||
{ "--revolutions" },
|
||||
"read this many revolutions of the disk",
|
||||
1);
|
||||
|
||||
static SettableFlag highDensity(
|
||||
{ "--high-density", "--hd" },
|
||||
"sets the drive to high density mode");
|
||||
static bool high_density = false;
|
||||
|
||||
void setHardwareFluxReaderDensity(bool high_density)
|
||||
{
|
||||
::high_density = high_density;
|
||||
}
|
||||
|
||||
class HardwareFluxReader : public FluxReader
|
||||
{
|
||||
@@ -29,14 +31,11 @@ public:
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> readFlux(int track, int side)
|
||||
{
|
||||
usbSetDrive(_drive, highDensity);
|
||||
usbSetDrive(_drive, high_density);
|
||||
usbSeek(track);
|
||||
Bytes crunched = usbRead(side, revolutions);
|
||||
std::cout << fmt::format("({} bytes crunched) ", crunched.size());
|
||||
|
||||
Bytes uncrunched = crunched.uncrunch();
|
||||
auto fluxmap = std::make_unique<Fluxmap>();
|
||||
fluxmap->appendBytes(uncrunched);
|
||||
fluxmap->appendBytes(crunched.uncrunch());
|
||||
return fluxmap;
|
||||
}
|
||||
|
||||
@@ -52,6 +51,7 @@ public:
|
||||
|
||||
private:
|
||||
unsigned _drive;
|
||||
unsigned _revolutions;
|
||||
};
|
||||
|
||||
void setHardwareFluxReaderRevolutions(int revolutions)
|
||||
|
||||
24
lib/fluxwriter/fluxwriter.cc
Normal file
24
lib/fluxwriter/fluxwriter.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxwriter.h"
|
||||
|
||||
static bool ends_with(const std::string& value, const std::string& ending)
|
||||
{
|
||||
if (ending.size() > value.size())
|
||||
return false;
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
std::unique_ptr<FluxWriter> FluxWriter::create(const DataSpec& spec)
|
||||
{
|
||||
const auto& filename = spec.filename;
|
||||
|
||||
if (filename.empty())
|
||||
return createHardwareFluxWriter(spec.drive);
|
||||
else if (ends_with(filename, ".flux"))
|
||||
return createSqliteFluxWriter(filename);
|
||||
|
||||
Error() << "unrecognised flux filename extension";
|
||||
return std::unique_ptr<FluxWriter>();
|
||||
}
|
||||
26
lib/fluxwriter/fluxwriter.h
Normal file
26
lib/fluxwriter/fluxwriter.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef FLUXWRITER_H
|
||||
#define FLUXWRITER_H
|
||||
|
||||
class Fluxmap;
|
||||
class DataSpec;
|
||||
|
||||
class FluxWriter
|
||||
{
|
||||
public:
|
||||
virtual ~FluxWriter() {}
|
||||
|
||||
private:
|
||||
static std::unique_ptr<FluxWriter> createSqliteFluxWriter(const std::string& filename);
|
||||
static std::unique_ptr<FluxWriter> createHardwareFluxWriter(unsigned drive);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<FluxWriter> create(const DataSpec& spec);
|
||||
|
||||
public:
|
||||
virtual void writeFlux(int track, int side, Fluxmap& fluxmap) = 0;
|
||||
};
|
||||
|
||||
extern void setHardwareFluxWriterDensity(bool high_density);
|
||||
|
||||
#endif
|
||||
|
||||
46
lib/fluxwriter/hardwarefluxwriter.cc
Normal file
46
lib/fluxwriter/hardwarefluxwriter.cc
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "fluxmap.h"
|
||||
#include "usb.h"
|
||||
#include "fluxwriter.h"
|
||||
|
||||
static bool high_density = false;
|
||||
|
||||
void setHardwareFluxWriterDensity(bool high_density)
|
||||
{
|
||||
::high_density = high_density;
|
||||
}
|
||||
|
||||
class HardwareFluxWriter : public FluxWriter
|
||||
{
|
||||
public:
|
||||
HardwareFluxWriter(unsigned drive):
|
||||
_drive(drive)
|
||||
{
|
||||
}
|
||||
|
||||
~HardwareFluxWriter()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
void writeFlux(int track, int side, Fluxmap& fluxmap)
|
||||
{
|
||||
usbSetDrive(_drive, high_density);
|
||||
usbSeek(track);
|
||||
|
||||
Bytes crunched = fluxmap.rawBytes().crunch();
|
||||
return usbWrite(side, crunched);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned _drive;
|
||||
};
|
||||
|
||||
std::unique_ptr<FluxWriter> FluxWriter::createHardwareFluxWriter(unsigned drive)
|
||||
{
|
||||
return std::unique_ptr<FluxWriter>(new HardwareFluxWriter(drive));
|
||||
}
|
||||
|
||||
|
||||
|
||||
47
lib/fluxwriter/sqlitefluxwriter.cc
Normal file
47
lib/fluxwriter/sqlitefluxwriter.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "globals.h"
|
||||
#include "fluxmap.h"
|
||||
#include "sql.h"
|
||||
#include "fluxwriter.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
class SqliteFluxWriter : public FluxWriter
|
||||
{
|
||||
public:
|
||||
SqliteFluxWriter(const std::string& filename)
|
||||
{
|
||||
_outdb = sqlOpen(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
int oldVersion = sqlReadIntProperty(_outdb, "version");
|
||||
if ((oldVersion != 0) && (oldVersion != FLUX_VERSION_CURRENT))
|
||||
Error() << fmt::format("that flux file is version {}, but this client is for version {}",
|
||||
oldVersion, FLUX_VERSION_CURRENT);
|
||||
|
||||
sqlPrepareFlux(_outdb);
|
||||
sqlStmt(_outdb, "BEGIN;");
|
||||
sqlWriteIntProperty(_outdb, "version", FLUX_VERSION_CURRENT);
|
||||
}
|
||||
|
||||
~SqliteFluxWriter()
|
||||
{
|
||||
if (_outdb)
|
||||
{
|
||||
sqlStmt(_outdb, "COMMIT;");
|
||||
sqlClose(_outdb);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void writeFlux(int track, int side, Fluxmap& fluxmap)
|
||||
{
|
||||
return sqlWriteFlux(_outdb, track, side, fluxmap);
|
||||
}
|
||||
|
||||
private:
|
||||
sqlite3* _outdb;
|
||||
};
|
||||
|
||||
std::unique_ptr<FluxWriter> FluxWriter::createSqliteFluxWriter(const std::string& filename)
|
||||
{
|
||||
return std::unique_ptr<FluxWriter>(new SqliteFluxWriter(filename));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ SectorVector AbstractIbmDecoder::decodeToSectors(const RawRecordVector& rawRecor
|
||||
for (auto& rawrecord : rawRecords)
|
||||
{
|
||||
const Bytes bytes = decodeFmMfm(rawrecord->data);
|
||||
int headerSize = skipHeaderBytes();
|
||||
unsigned headerSize = skipHeaderBytes();
|
||||
if (bytes.size() < (headerSize + 1))
|
||||
continue;
|
||||
Bytes data = bytes.slice(headerSize, bytes.size() - headerSize);
|
||||
|
||||
@@ -38,6 +38,10 @@ static IntFlag retries(
|
||||
"How many times to retry each track in the event of a read failure.",
|
||||
5);
|
||||
|
||||
static SettableFlag highDensityFlag(
|
||||
{ "--high-density", "-H" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
static sqlite3* outdb;
|
||||
|
||||
void setReaderDefaultSource(const std::string& source)
|
||||
@@ -79,6 +83,8 @@ std::vector<std::unique_ptr<Track>> readTracks()
|
||||
|
||||
std::cout << "Reading from: " << dataSpec << std::endl;
|
||||
|
||||
setHardwareFluxReaderDensity(highDensityFlag);
|
||||
|
||||
if (!destination.value.empty())
|
||||
{
|
||||
outdb = sqlOpen(destination, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "protocol.h"
|
||||
#include "usb.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxreader.h"
|
||||
#include "fluxwriter.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
static DataSpecFlag dest(
|
||||
@@ -13,6 +15,10 @@ static DataSpecFlag dest(
|
||||
"destination for data",
|
||||
":d=0:t=0-79:s=0-1");
|
||||
|
||||
static SettableFlag highDensityFlag(
|
||||
{ "--high-density", "-H" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
static sqlite3* outdb;
|
||||
|
||||
void setWriterDefaultDest(const std::string& dest)
|
||||
@@ -27,6 +33,9 @@ void writeTracks(
|
||||
|
||||
std::cout << "Writing to: " << spec << std::endl;
|
||||
|
||||
setHardwareFluxReaderDensity(highDensityFlag);
|
||||
setHardwareFluxWriterDensity(highDensityFlag);
|
||||
|
||||
if (!spec.filename.empty())
|
||||
{
|
||||
outdb = sqlOpen(spec.filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
||||
|
||||
16
meson.build
16
meson.build
@@ -72,6 +72,20 @@ fluxreaderlib = declare_dependency(
|
||||
include_directories('lib/fluxreader')
|
||||
)
|
||||
|
||||
fluxwriterlib = declare_dependency(
|
||||
link_with:
|
||||
shared_library('fluxwriterlib',
|
||||
[
|
||||
'lib/fluxwriter/fluxwriter.cc',
|
||||
'lib/fluxwriter/sqlitefluxwriter.cc',
|
||||
'lib/fluxwriter/hardwarefluxwriter.cc',
|
||||
],
|
||||
dependencies: [fmtlib, felib, sqllib, sqlite]
|
||||
),
|
||||
include_directories:
|
||||
include_directories('lib/fluxwriter')
|
||||
)
|
||||
|
||||
decoderlib = declare_dependency(
|
||||
link_with:
|
||||
shared_library('decoderlib',
|
||||
@@ -96,7 +110,7 @@ writerlib = declare_dependency(
|
||||
link_with:
|
||||
shared_library('writerlib',
|
||||
['lib/writer.cc'],
|
||||
dependencies: [fmtlib, felib, sqllib, sqlite]
|
||||
dependencies: [fmtlib, felib, sqllib, fluxreaderlib, fluxwriterlib, sqlite]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user