diff --git a/lib/config.proto b/lib/config.proto index f3bdc687..ebbc9c7a 100644 --- a/lib/config.proto +++ b/lib/config.proto @@ -10,6 +10,13 @@ extend google.protobuf.FieldOptions { optional string help = 50000; } +message Range { + optional int32 start = 1; + optional int32 step = 2 [default = 1]; + optional int32 end = 3; + repeated int32 also = 4; +} + message Config { message InputFile { optional string filename = 1; @@ -19,10 +26,13 @@ message Config { } message InputDisk { - optional int32 drive = 1; + oneof source { + string fluxfile = 1; + int32 drive = 2 [default = 0]; + } oneof format { - IBMInput ibm = 2; - BrotherInput brother = 3; + IBMInput ibm = 3; + BrotherInput brother = 4; } } @@ -34,10 +44,13 @@ message Config { } message OutputDisk { - optional int32 drive = 1; + oneof dest { + string fluxfile = 1; + int32 drive = 2; + } oneof format { - IBMOutput ibm = 2; - BrotherOutput brother = 3; + IBMOutput ibm = 3; + BrotherOutput brother = 4; } } @@ -58,5 +71,8 @@ message Config { optional Input input = 1; optional Output output = 2; optional Decoder decoder = 3; + + optional Range cylinders = 4; + optional Range sides = 5; } diff --git a/lib/fluxsource/fluxsource.cc b/lib/fluxsource/fluxsource.cc index f8551fe4..68fa619d 100644 --- a/lib/fluxsource/fluxsource.cc +++ b/lib/fluxsource/fluxsource.cc @@ -2,6 +2,7 @@ #include "flags.h" #include "dataspec.h" #include "fluxsource/fluxsource.h" +#include "lib/config.pb.h" static bool ends_with(const std::string& value, const std::string& ending) { @@ -24,3 +25,15 @@ std::unique_ptr FluxSource::create(const FluxSpec& spec) Error() << "unrecognised flux filename extension"; return std::unique_ptr(); } + +std::unique_ptr FluxSource::create(const Config_InputDisk& config) +{ + if (config.has_fluxfile()) + return createSqliteFluxSource(config.fluxfile()); + else + return createHardwareFluxSource(config.drive()); + + Error() << "bad input disk configuration"; + return std::unique_ptr(); +} + diff --git a/lib/fluxsource/fluxsource.h b/lib/fluxsource/fluxsource.h index 2b2876df..6a8947a5 100644 --- a/lib/fluxsource/fluxsource.h +++ b/lib/fluxsource/fluxsource.h @@ -7,6 +7,7 @@ extern FlagGroup hardwareFluxSourceFlags; class Fluxmap; class FluxSpec; +class Config_InputDisk; class FluxSource { @@ -20,6 +21,7 @@ private: public: static std::unique_ptr create(const FluxSpec& spec); + static std::unique_ptr create(const Config_InputDisk& spec); public: virtual std::unique_ptr readFlux(int track, int side) = 0; diff --git a/lib/proto.cc b/lib/proto.cc index 9344364d..5e7ad232 100644 --- a/lib/proto.cc +++ b/lib/proto.cc @@ -100,3 +100,15 @@ void setProtoByString(google::protobuf::Message* message, const std::string& pat } } +std::set iterate(const Range& range) +{ + std::set set; + for (int i=range.start(); i<=range.end(); i+=range.step()) + set.insert(i); + + for (const int i : range.also()) + set.insert(i); + + return set; +} + diff --git a/lib/proto.h b/lib/proto.h index e09bc87c..5c891296 100644 --- a/lib/proto.h +++ b/lib/proto.h @@ -6,6 +6,8 @@ extern void setProtoByString(google::protobuf::Message* message, const std::string& path, const std::string& value); +extern std::set iterate(const Range& range); + extern Config config; #endif diff --git a/lib/reader.cc b/lib/reader.cc index 3bba8422..ec7d6672 100644 --- a/lib/reader.cc +++ b/lib/reader.cc @@ -16,6 +16,7 @@ #include "track.h" #include "imagewriter/imagewriter.h" #include "fmt/format.h" +#include "proto.h" #include #include @@ -26,15 +27,15 @@ FlagGroup readerFlags &fluxmapReaderFlags, }; -static DataSpecFlag source( - { "--source", "-s" }, - "source for data", - ":t=0-79:s=0-1:d=0"); - -static DataSpecFlag output( - { "--output", "-o" }, - "output image file to write to", - ""); +//static DataSpecFlag source( +// { "--source", "-s" }, +// "source for data", +// ":t=0-79:s=0-1:d=0"); +// +//static DataSpecFlag output( +// { "--output", "-o" }, +// "output image file to write to", +// ""); static StringFlag destination( { "--write-flux", "-f" }, @@ -65,26 +66,6 @@ static StringFlag csvFile( static std::unique_ptr outputFluxSink; -void setReaderDefaultSource(const std::string& source) -{ - ::source.set(source); -} - -void setReaderDefaultOutput(const std::string& output) -{ - ::output.set(output); -} - -void setReaderRevolutions(int revolutions) -{ - setHardwareFluxSourceRevolutions(revolutions); -} - -void setReaderHardSectorCount(int sectorCount) -{ - setHardwareFluxSourceHardSectorCount(sectorCount); -} - static void writeSectorsToFile(const SectorSet& sectors, const ImageSpec& spec) { std::unique_ptr writer(ImageWriter::create(sectors, spec)); @@ -107,7 +88,8 @@ void Track::readFluxmap() outputFluxSink->writeFlux(physicalTrack, physicalSide, *fluxmap); } -std::vector> readTracks() +#if 0 +std::vector> readTracks(FluxSource& fluxSource) { const FluxSpec spec(source); @@ -140,6 +122,7 @@ std::vector> readTracks() return tracks; } +#endif static bool conflictable(Sector::Status status) { @@ -167,16 +150,27 @@ static void replace_sector(std::unique_ptr& replacing, Sector& replaceme } } -void readDiskCommand(AbstractDecoder& decoder) +void readDiskCommand(FluxSource& fluxsource, AbstractDecoder& decoder, ImageWriter& writer) { - const ImageSpec outputSpec(output); - ImageWriter::verifyImageSpec(outputSpec); - bool failures = false; SectorSet allSectors; - auto tracks = readTracks(); - for (const auto& track : tracks) + for (int cylinder : iterate(config.cylinders())) { + for (int side : iterate(config.sides())) + { +#if 0 + auto track = std::make_unique(location + std::vector> tracks; + for (const auto& location : spec.locations) + { + auto track = std::make_unique(location.track, location.side); + track->fluxsource = fluxSource; + tracks.push_back(std::move(track)); + } +#endif + auto track = std::make_unique(cylinder, side); + track->fluxsource = &fluxsource; + std::map> readSectors; for (int retry = ::retries; retry >= 0; retry--) { @@ -284,9 +278,11 @@ void readDiskCommand(AbstractDecoder& decoder) } } std::cout << size << " bytes decoded." << std::endl; + } } - writeSectorsToFile(allSectors, outputSpec); + Error() << "write to image not done"; + //writeSectorsToFile(allSectors, outputSpec); if (failures) std::cerr << "Warning: some sectors could not be decoded." << std::endl; } diff --git a/lib/reader.h b/lib/reader.h index 1b7f61e9..5c2e5252 100644 --- a/lib/reader.h +++ b/lib/reader.h @@ -3,9 +3,10 @@ #include "flags.h" -class Fluxmap; -class FluxSource; class AbstractDecoder; +class FluxSource; +class Fluxmap; +class ImageWriter; class Track; extern FlagGroup readerFlags; @@ -17,6 +18,6 @@ extern void setReaderHardSectorCount(int sectorCount); extern std::vector> readTracks(); -extern void readDiskCommand(AbstractDecoder& decoder); +extern void readDiskCommand(FluxSource& source, AbstractDecoder& decoder, ImageWriter& writer); #endif diff --git a/lib/track.h b/lib/track.h index 88e001a5..b0d53bea 100644 --- a/lib/track.h +++ b/lib/track.h @@ -18,7 +18,7 @@ public: public: unsigned physicalTrack; unsigned physicalSide; - std::shared_ptr fluxsource; + FluxSource* fluxsource; std::unique_ptr fluxmap; std::vector rawrecords; diff --git a/src/fe-inspect.cc b/src/fe-inspect.cc index 012de083..acb6a2cd 100644 --- a/src/fe-inspect.cc +++ b/src/fe-inspect.cc @@ -182,6 +182,7 @@ int mainInspect(int argc, const char* argv[]) { flags.parseFlags(argc, argv); +#if 0 const auto& tracks = readTracks(); if (tracks.size() != 1) Error() << "the source dataspec must contain exactly one track (two sides count as two tracks)"; @@ -287,6 +288,7 @@ int mainInspect(int argc, const char* argv[]) const auto& bytes = track->fluxmap->rawBytes(); hexdump(std::cout, bytes); } +#endif return 0; } diff --git a/src/fe-read.cc b/src/fe-read.cc new file mode 100644 index 00000000..e654bc39 --- /dev/null +++ b/src/fe-read.cc @@ -0,0 +1,53 @@ +#include "globals.h" +#include "flags.h" +#include "reader.h" +#include "fluxmap.h" +#include "decoders/decoders.h" +#include "macintosh/macintosh.h" +#include "sector.h" +#include "sectorset.h" +#include "record.h" +#include "proto.h" +#include "dataspec.h" +#include "fluxsource/fluxsource.h" +#include "arch/brother/brother.h" +#include "imagewriter/imagewriter.h" +#include "fmt/format.h" +#include +#include + +static FlagGroup flags { &readerFlags }; + +extern const char readables_brother_pb[]; +extern const int readables_brother_pb_size; + +int mainRead(int argc, const char* argv[]) +{ + flags.parseFlags(argc, argv); + + if (!config.ParseFromString(std::string(readables_brother_pb, readables_brother_pb_size))) + Error() << "couldn't load config proto"; + + std::string s; + google::protobuf::TextFormat::PrintToString(config, &s); + std::cout << s << '\n'; + + std::unique_ptr fluxSource(FluxSource::create(config.input().disk())); + + std::unique_ptr decoder; + if (config.input().disk().has_brother()) + decoder.reset(new BrotherDecoder()); + else + Error() << "no input disk format specified"; + + std::unique_ptr writer; +// if (config.output().file().has_img()) +// write.reset(new ImgImageWriter()); +// else +// Error() << "no output image format specified"; + + readDiskCommand(*fluxSource, *decoder, *writer); + + return 0; +} + diff --git a/src/fe-writeflux.cc b/src/fe-writeflux.cc index de680e0b..a380354d 100644 --- a/src/fe-writeflux.cc +++ b/src/fe-writeflux.cc @@ -14,6 +14,7 @@ static FlagGroup flags { &writerFlags }; int mainWriteFlux(int argc, const char* argv[]) { + #if 0 setReaderDefaultSource(":t=0-81:h=0-1"); setWriterDefaultDest(":t=0-81:s=0-1"); flags.parseFlags(argc, argv); @@ -41,6 +42,7 @@ int mainWriteFlux(int argc, const char* argv[]) throw "unreachable"; } ); + #endif return 0; } diff --git a/src/readables/brother.textpb b/src/readables/brother.textpb index 68c5fe98..4679e97d 100644 --- a/src/readables/brother.textpb +++ b/src/readables/brother.textpb @@ -4,3 +4,20 @@ input { } } +output { + file { + filename: "brother.img" + img {} + } +} + +cylinders { + start: 0 + end: 81 +} + +sides { + start: 0 + end: 0 +} + diff --git a/tests/proto.cc b/tests/proto.cc index 925fb1f9..f3a20290 100644 --- a/tests/proto.cc +++ b/tests/proto.cc @@ -73,8 +73,30 @@ static void test_load(void) std::string s; google::protobuf::TextFormat::PrintToString(proto, &s); s = cleanup(s); - AssertThat(s, Equals("u64: 42")); + AssertThat(s, Equals("u64: 42 r { } secondoption { }")); AssertThat(r, Equals(true)); + AssertThat(proto.has_secondoption(), Equals(true)); +} + +static void test_range(void) +{ + { + Range r; + r.set_start(0); + r.set_end(3); + r.add_also(5); + + AssertThat(iterate(r), Equals(std::set{0, 1, 2, 3, 5})); + } + + { + Range r; + r.set_start(1); + r.set_end(1); + r.add_also(5); + + AssertThat(iterate(r), Equals(std::set{1, 5})); + } } int main(int argc, const char* argv[]) @@ -82,6 +104,7 @@ int main(int argc, const char* argv[]) test_setting(); test_config(); test_load(); + test_range(); return 0; } diff --git a/tests/testproto.proto b/tests/testproto.proto index 8c7a8a55..1a0e67cf 100644 --- a/tests/testproto.proto +++ b/tests/testproto.proto @@ -12,5 +12,10 @@ message TestProto { optional double d = 5; optional SubMessage m = 6; repeated SubMessage r = 7; + + oneof alt { + SubMessage firstoption = 8; + SubMessage secondoption = 9; + } } diff --git a/tests/testproto.textpb b/tests/testproto.textpb index 37c390a0..d2a146e5 100644 --- a/tests/testproto.textpb +++ b/tests/testproto.textpb @@ -1,2 +1,4 @@ u64: 42 +r {} +secondoption {}