mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Refactor dataspecs to allow them to be used for other things too.
This commit is contained in:
@@ -74,28 +74,54 @@ void DataSpec::set(const std::string& spec)
|
||||
filename = words[0];
|
||||
if (words.size() > 1)
|
||||
{
|
||||
locations.clear();
|
||||
|
||||
for (size_t i = 1; i < words.size(); i++)
|
||||
{
|
||||
auto mod = parseMod(words[i]);
|
||||
if ((mod.name != "t") && (mod.name != "s") && (mod.name != "d"))
|
||||
Error() << fmt::format("unknown data modifier '{}'", mod.name);
|
||||
modifiers[mod.name] = mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto& drives = modifiers["d"].data;
|
||||
FluxSpec::FluxSpec(const DataSpec& spec)
|
||||
{
|
||||
filename = spec.filename;
|
||||
|
||||
locations.clear();
|
||||
|
||||
const auto& drives = spec.modifiers.at("d").data;
|
||||
if (drives.size() != 1)
|
||||
Error() << "you must specify exactly one drive";
|
||||
drive = *drives.begin();
|
||||
|
||||
const auto& tracks = modifiers["t"].data;
|
||||
const auto& sides = modifiers["s"].data;
|
||||
const auto& tracks = spec.modifiers.at("t").data;
|
||||
const auto& sides = spec.modifiers.at("s").data;
|
||||
for (auto track : tracks)
|
||||
{
|
||||
for (auto side : sides)
|
||||
locations.push_back({ drive, track, side });
|
||||
}
|
||||
|
||||
for (const auto& e : spec.modifiers)
|
||||
{
|
||||
const auto name = e.second.name;
|
||||
if ((name != "t") && (name != "s") && (name != "d"))
|
||||
Error() << fmt::format("unknown fluxspec modifier '{}'", name);
|
||||
}
|
||||
}
|
||||
|
||||
ImageSpec::ImageSpec(const DataSpec& spec)
|
||||
{
|
||||
filename = spec.filename;
|
||||
|
||||
tracks = spec.modifiers.at("t").only();
|
||||
heads = spec.modifiers.at("h").only();
|
||||
sectors = spec.modifiers.at("s").only();
|
||||
|
||||
for (const auto& e : spec.modifiers)
|
||||
{
|
||||
const auto name = e.second.name;
|
||||
if ((name != "t") && (name != "h") && (name != "s"))
|
||||
Error() << fmt::format("unknown fluxspec modifier '{}'", name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,6 @@
|
||||
class DataSpec
|
||||
{
|
||||
public:
|
||||
struct Location
|
||||
{
|
||||
unsigned drive;
|
||||
unsigned track;
|
||||
unsigned side;
|
||||
|
||||
bool operator == (const Location& other) const
|
||||
{ return (drive == other.drive) && (track == other.track) && (side == other.side); }
|
||||
|
||||
bool operator != (const Location& other) const
|
||||
{ return (drive != other.drive) || (track != other.track) || (side != other.side); }
|
||||
};
|
||||
|
||||
struct Modifier
|
||||
{
|
||||
std::string name;
|
||||
@@ -28,6 +15,13 @@ public:
|
||||
|
||||
bool operator != (const Modifier& other) const
|
||||
{ return (name != other.name) || (data != other.data); }
|
||||
|
||||
unsigned only() const
|
||||
{
|
||||
if (data.size() != 1)
|
||||
Error() << "modifier " << name << " can only have one value";
|
||||
return *(data.begin());
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -44,9 +38,43 @@ public:
|
||||
|
||||
std::string filename;
|
||||
std::map<std::string, Modifier> modifiers;
|
||||
};
|
||||
|
||||
class FluxSpec
|
||||
{
|
||||
public:
|
||||
struct Location
|
||||
{
|
||||
unsigned drive;
|
||||
unsigned track;
|
||||
unsigned side;
|
||||
|
||||
bool operator == (const Location& other) const
|
||||
{ return (drive == other.drive) && (track == other.track) && (side == other.side); }
|
||||
|
||||
bool operator != (const Location& other) const
|
||||
{ return (drive != other.drive) || (track != other.track) || (side != other.side); }
|
||||
};
|
||||
|
||||
public:
|
||||
FluxSpec(const DataSpec& dataspec);
|
||||
|
||||
public:
|
||||
std::string filename;
|
||||
std::vector<Location> locations;
|
||||
unsigned drive;
|
||||
unsigned revolutions;
|
||||
};
|
||||
|
||||
class ImageSpec
|
||||
{
|
||||
public:
|
||||
ImageSpec(const DataSpec& dataspec);
|
||||
|
||||
public:
|
||||
std::string filename;
|
||||
unsigned tracks;
|
||||
unsigned heads;
|
||||
unsigned sectors;
|
||||
};
|
||||
|
||||
static inline std::ostream& operator << (std::ostream& os, const DataSpec& dataSpec)
|
||||
|
||||
@@ -10,7 +10,7 @@ static bool ends_with(const std::string& value, const std::string& ending)
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
std::unique_ptr<FluxSink> FluxSink::create(const DataSpec& spec)
|
||||
std::unique_ptr<FluxSink> FluxSink::create(const FluxSpec& spec)
|
||||
{
|
||||
const auto& filename = spec.filename;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define FLUXSINK_H
|
||||
|
||||
class Fluxmap;
|
||||
class DataSpec;
|
||||
class FluxSpec;
|
||||
|
||||
class FluxSink
|
||||
{
|
||||
@@ -14,7 +14,7 @@ private:
|
||||
static std::unique_ptr<FluxSink> createHardwareFluxSink(unsigned drive);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<FluxSink> create(const DataSpec& spec);
|
||||
static std::unique_ptr<FluxSink> create(const FluxSpec& spec);
|
||||
|
||||
public:
|
||||
virtual void writeFlux(int track, int side, Fluxmap& fluxmap) = 0;
|
||||
|
||||
@@ -10,7 +10,7 @@ static bool ends_with(const std::string& value, const std::string& ending)
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
std::unique_ptr<FluxSource> FluxSource::create(const DataSpec& spec)
|
||||
std::unique_ptr<FluxSource> FluxSource::create(const FluxSpec& spec)
|
||||
{
|
||||
const auto& filename = spec.filename;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
extern FlagGroup hardwareFluxSourceFlags;
|
||||
|
||||
class Fluxmap;
|
||||
class DataSpec;
|
||||
class FluxSpec;
|
||||
|
||||
class FluxSource
|
||||
{
|
||||
@@ -19,7 +19,7 @@ private:
|
||||
static std::unique_ptr<FluxSource> createStreamFluxSource(const std::string& path);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<FluxSource> create(const DataSpec& spec);
|
||||
static std::unique_ptr<FluxSource> create(const FluxSpec& spec);
|
||||
|
||||
public:
|
||||
virtual std::unique_ptr<Fluxmap> readFlux(int track, int side) = 0;
|
||||
|
||||
@@ -71,9 +71,9 @@ void Track::readFluxmap()
|
||||
|
||||
std::vector<std::unique_ptr<Track>> readTracks()
|
||||
{
|
||||
const DataSpec& dataSpec = source;
|
||||
const FluxSpec spec(source);
|
||||
|
||||
std::cout << "Reading from: " << dataSpec << std::endl;
|
||||
std::cout << "Reading from: " << source << std::endl;
|
||||
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
|
||||
@@ -92,10 +92,10 @@ std::vector<std::unique_ptr<Track>> readTracks()
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<FluxSource> fluxSource = FluxSource::create(dataSpec);
|
||||
std::shared_ptr<FluxSource> fluxSource = FluxSource::create(spec);
|
||||
|
||||
std::vector<std::unique_ptr<Track>> tracks;
|
||||
for (const auto& location : dataSpec.locations)
|
||||
for (const auto& location : spec.locations)
|
||||
{
|
||||
auto track = std::make_unique<Track>(location.track, location.side);
|
||||
track->fluxsource = fluxSource;
|
||||
|
||||
@@ -36,9 +36,9 @@ void setWriterDefaultDest(const std::string& dest)
|
||||
void writeTracks(
|
||||
const std::function<std::unique_ptr<Fluxmap>(int track, int side)> producer)
|
||||
{
|
||||
const DataSpec& spec = dest;
|
||||
const FluxSpec spec(dest);
|
||||
|
||||
std::cout << "Writing to: " << spec << std::endl;
|
||||
std::cout << "Writing to: " << dest << std::endl;
|
||||
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
setHardwareFluxSinkDensity(highDensityFlag);
|
||||
|
||||
@@ -34,14 +34,15 @@ int mainConvertFluxToAu(int argc, const char* argv[])
|
||||
{
|
||||
flags.parseFlags(argc, argv);
|
||||
|
||||
const auto& locations = source.get().locations;
|
||||
FluxSpec spec(source);
|
||||
const auto& locations = spec.locations;
|
||||
if (locations.size() != 1)
|
||||
Error() << "the source dataspec must contain exactly one track (two sides count as two tracks)";
|
||||
const auto& location = *(locations.begin());
|
||||
|
||||
std::cerr << "Reading source flux...\n";
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(source);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(spec);
|
||||
const auto& fluxmap = fluxsource->readFlux(location.track, location.side);
|
||||
unsigned totalTicks = fluxmap->ticks() + 2;
|
||||
unsigned channels = withIndex ? 2 : 1;
|
||||
|
||||
@@ -30,14 +30,15 @@ int mainConvertFluxToVcd(int argc, const char* argv[])
|
||||
{
|
||||
flags.parseFlags(argc, argv);
|
||||
|
||||
const auto& locations = source.get().locations;
|
||||
const FluxSpec spec(source);
|
||||
const auto& locations = spec.locations;
|
||||
if (locations.size() != 1)
|
||||
Error() << "the source dataspec must contain exactly one track (two sides count as two tracks)";
|
||||
const auto& location = *(locations.begin());
|
||||
|
||||
std::cerr << "Reading source flux...\n";
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(source);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(spec);
|
||||
const auto& fluxmap = fluxsource->readFlux(location.track, location.side);
|
||||
|
||||
std::cerr << "Writing destination VCD...\n";
|
||||
|
||||
@@ -14,7 +14,8 @@ int mainRpm(int argc, const char* argv[])
|
||||
{
|
||||
flags.parseFlags(argc, argv);
|
||||
|
||||
usbSetDrive(source.get().drive, false);
|
||||
FluxSpec spec(source);
|
||||
usbSetDrive(spec.drive, false);
|
||||
nanoseconds_t period = usbGetRotationalPeriod();
|
||||
std::cout << "Rotational period is " << period/1000 << " ms (" << 60e6/period << " rpm)" << std::endl;
|
||||
|
||||
|
||||
@@ -33,48 +33,78 @@ static void test_parsemod(void)
|
||||
== (DataSpec::Modifier{"x", {2, 4, 9}}));
|
||||
}
|
||||
|
||||
static void test_dataspec(void)
|
||||
static void test_fluxspec(void)
|
||||
{
|
||||
DataSpec spec("foo:t=0-2:s=0-1:d=0");
|
||||
assert(spec.filename == "foo");
|
||||
assert((spec.locations
|
||||
== std::vector<DataSpec::Location>
|
||||
|
||||
{
|
||||
FluxSpec fspec(spec);
|
||||
assert(fspec.filename == "foo");
|
||||
assert((fspec.locations
|
||||
== std::vector<FluxSpec::Location>
|
||||
{{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 2, 0}, {0, 2, 1}}));
|
||||
assert((std::string)spec == "foo:d=0:s=0-1:t=0-2");
|
||||
}
|
||||
|
||||
spec.set("bar");
|
||||
assert(spec.filename == "bar");
|
||||
assert((spec.locations
|
||||
== std::vector<DataSpec::Location>
|
||||
{
|
||||
FluxSpec fspec(spec);
|
||||
assert(fspec.filename == "bar");
|
||||
assert((fspec.locations
|
||||
== std::vector<FluxSpec::Location>
|
||||
{{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 2, 0}, {0, 2, 1}}));
|
||||
assert((std::string)spec == "bar:d=0:s=0-1:t=0-2");
|
||||
}
|
||||
|
||||
spec.set(":t=0");
|
||||
assert(spec.filename.empty());
|
||||
assert((spec.locations
|
||||
== std::vector<DataSpec::Location>
|
||||
{
|
||||
FluxSpec fspec(spec);
|
||||
assert(fspec.filename.empty());
|
||||
assert((fspec.locations
|
||||
== std::vector<FluxSpec::Location>
|
||||
{{0, 0, 0}, {0, 0, 1}}));
|
||||
assert((std::string)spec == ":d=0:s=0-1:t=0");
|
||||
}
|
||||
|
||||
spec.set(":s=1");
|
||||
assert(spec.filename.empty());
|
||||
assert((spec.locations
|
||||
== std::vector<DataSpec::Location>
|
||||
{
|
||||
FluxSpec fspec(spec);
|
||||
assert(fspec.filename.empty());
|
||||
assert((fspec.locations
|
||||
== std::vector<FluxSpec::Location>
|
||||
{{0, 0, 1}}));
|
||||
assert((std::string)spec == ":d=0:s=1:t=0");
|
||||
}
|
||||
|
||||
spec.set(":t=9:d=1");
|
||||
assert(spec.filename.empty());
|
||||
assert((spec.locations
|
||||
== std::vector<DataSpec::Location>
|
||||
{
|
||||
FluxSpec fspec(spec);
|
||||
assert(fspec.filename.empty());
|
||||
assert((fspec.locations
|
||||
== std::vector<FluxSpec::Location>
|
||||
{{1, 9, 1}}));
|
||||
assert((std::string)spec == ":d=1:s=1:t=9");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_imagespec(void)
|
||||
{
|
||||
DataSpec spec("foo:t=9:h=2:s=99");
|
||||
|
||||
{
|
||||
ImageSpec ispec(spec);
|
||||
assert(ispec.filename == "foo");
|
||||
assert(ispec.tracks == 9);
|
||||
assert(ispec.heads == 2);
|
||||
assert(ispec.sectors == 99);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
test_split();
|
||||
test_parsemod();
|
||||
test_dataspec();
|
||||
test_fluxspec();
|
||||
test_imagespec();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user