mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	More config machinery: the reader now reads (but can't put the resulting image
anywhere).
This commit is contained in:
		| @@ -10,6 +10,13 @@ extend google.protobuf.FieldOptions { | |||||||
|   optional string help = 50000; |   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 Config { | ||||||
| 	message InputFile { | 	message InputFile { | ||||||
| 		optional string filename = 1; | 		optional string filename = 1; | ||||||
| @@ -19,10 +26,13 @@ message Config { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	message InputDisk { | 	message InputDisk { | ||||||
| 		optional int32 drive = 1; | 		oneof source { | ||||||
|  | 			string fluxfile = 1; | ||||||
|  | 			int32 drive = 2 [default = 0]; | ||||||
|  | 		} | ||||||
| 		oneof format { | 		oneof format { | ||||||
| 			IBMInput ibm = 2; | 			IBMInput ibm = 3; | ||||||
| 			BrotherInput brother = 3; | 			BrotherInput brother = 4; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -34,10 +44,13 @@ message Config { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	message OutputDisk { | 	message OutputDisk { | ||||||
| 		optional int32 drive = 1; | 		oneof dest { | ||||||
|  | 			string fluxfile = 1; | ||||||
|  | 			int32 drive = 2; | ||||||
|  | 		} | ||||||
| 		oneof format { | 		oneof format { | ||||||
| 			IBMOutput ibm = 2; | 			IBMOutput ibm = 3; | ||||||
| 			BrotherOutput brother = 3; | 			BrotherOutput brother = 4; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -58,5 +71,8 @@ message Config { | |||||||
| 	optional Input input = 1; | 	optional Input input = 1; | ||||||
| 	optional Output output = 2; | 	optional Output output = 2; | ||||||
| 	optional Decoder decoder = 3; | 	optional Decoder decoder = 3; | ||||||
|  |  | ||||||
|  | 	optional Range cylinders = 4; | ||||||
|  | 	optional Range sides = 5; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| #include "flags.h" | #include "flags.h" | ||||||
| #include "dataspec.h" | #include "dataspec.h" | ||||||
| #include "fluxsource/fluxsource.h" | #include "fluxsource/fluxsource.h" | ||||||
|  | #include "lib/config.pb.h" | ||||||
|  |  | ||||||
| static bool ends_with(const std::string& value, const std::string& ending) | static bool ends_with(const std::string& value, const std::string& ending) | ||||||
| { | { | ||||||
| @@ -24,3 +25,15 @@ std::unique_ptr<FluxSource> FluxSource::create(const FluxSpec& spec) | |||||||
|     Error() << "unrecognised flux filename extension"; |     Error() << "unrecognised flux filename extension"; | ||||||
|     return std::unique_ptr<FluxSource>(); |     return std::unique_ptr<FluxSource>(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::unique_ptr<FluxSource> 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<FluxSource>(); | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ extern FlagGroup hardwareFluxSourceFlags; | |||||||
|  |  | ||||||
| class Fluxmap; | class Fluxmap; | ||||||
| class FluxSpec; | class FluxSpec; | ||||||
|  | class Config_InputDisk; | ||||||
|  |  | ||||||
| class FluxSource | class FluxSource | ||||||
| { | { | ||||||
| @@ -20,6 +21,7 @@ private: | |||||||
|  |  | ||||||
| public: | public: | ||||||
|     static std::unique_ptr<FluxSource> create(const FluxSpec& spec); |     static std::unique_ptr<FluxSource> create(const FluxSpec& spec); | ||||||
|  |     static std::unique_ptr<FluxSource> create(const Config_InputDisk& spec); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     virtual std::unique_ptr<Fluxmap> readFlux(int track, int side) = 0; |     virtual std::unique_ptr<Fluxmap> readFlux(int track, int side) = 0; | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								lib/proto.cc
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								lib/proto.cc
									
									
									
									
									
								
							| @@ -100,3 +100,15 @@ void setProtoByString(google::protobuf::Message* message, const std::string& pat | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::set<int> iterate(const Range& range) | ||||||
|  | { | ||||||
|  | 	std::set<int> 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; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ | |||||||
|  |  | ||||||
| extern void setProtoByString(google::protobuf::Message* message, const std::string& path, const std::string& value); | extern void setProtoByString(google::protobuf::Message* message, const std::string& path, const std::string& value); | ||||||
|  |  | ||||||
|  | extern std::set<int> iterate(const Range& range); | ||||||
|  |  | ||||||
| extern Config config; | extern Config config; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "track.h" | #include "track.h" | ||||||
| #include "imagewriter/imagewriter.h" | #include "imagewriter/imagewriter.h" | ||||||
| #include "fmt/format.h" | #include "fmt/format.h" | ||||||
|  | #include "proto.h" | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <fstream> | #include <fstream> | ||||||
|  |  | ||||||
| @@ -26,15 +27,15 @@ FlagGroup readerFlags | |||||||
| 	&fluxmapReaderFlags, | 	&fluxmapReaderFlags, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static DataSpecFlag source( | //static DataSpecFlag source( | ||||||
|     { "--source", "-s" }, | //    { "--source", "-s" }, | ||||||
|     "source for data", | //    "source for data", | ||||||
|     ":t=0-79:s=0-1:d=0"); | //    ":t=0-79:s=0-1:d=0"); | ||||||
|  | // | ||||||
| static DataSpecFlag output( | //static DataSpecFlag output( | ||||||
| 	{ "--output", "-o" }, | //	{ "--output", "-o" }, | ||||||
| 	"output image file to write to", | //	"output image file to write to", | ||||||
| 	""); | //	""); | ||||||
|  |  | ||||||
| static StringFlag destination( | static StringFlag destination( | ||||||
|     { "--write-flux", "-f" }, |     { "--write-flux", "-f" }, | ||||||
| @@ -65,26 +66,6 @@ static StringFlag csvFile( | |||||||
|  |  | ||||||
| static std::unique_ptr<FluxSink> outputFluxSink; | static std::unique_ptr<FluxSink> 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) | static void writeSectorsToFile(const SectorSet& sectors, const ImageSpec& spec) | ||||||
| { | { | ||||||
| 	std::unique_ptr<ImageWriter> writer(ImageWriter::create(sectors, spec)); | 	std::unique_ptr<ImageWriter> writer(ImageWriter::create(sectors, spec)); | ||||||
| @@ -107,7 +88,8 @@ void Track::readFluxmap() | |||||||
| 		outputFluxSink->writeFlux(physicalTrack, physicalSide, *fluxmap); | 		outputFluxSink->writeFlux(physicalTrack, physicalSide, *fluxmap); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<std::unique_ptr<Track>> readTracks() | #if 0 | ||||||
|  | std::vector<std::unique_ptr<Track>> readTracks(FluxSource& fluxSource) | ||||||
| { | { | ||||||
|     const FluxSpec spec(source); |     const FluxSpec spec(source); | ||||||
|  |  | ||||||
| @@ -140,6 +122,7 @@ std::vector<std::unique_ptr<Track>> readTracks() | |||||||
|  |  | ||||||
| 	return tracks; | 	return tracks; | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| static bool conflictable(Sector::Status status) | static bool conflictable(Sector::Status status) | ||||||
| { | { | ||||||
| @@ -167,16 +150,27 @@ static void replace_sector(std::unique_ptr<Sector>& 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; | 	bool failures = false; | ||||||
| 	SectorSet allSectors; | 	SectorSet allSectors; | ||||||
| 	auto tracks = readTracks(); | 	for (int cylinder : iterate(config.cylinders())) | ||||||
|     for (const auto& track : tracks) |  | ||||||
| 	{ | 	{ | ||||||
|  | 		for (int side : iterate(config.sides())) | ||||||
|  | 		{ | ||||||
|  | #if 0 | ||||||
|  | 		auto track = std::make_unique<Track>(location | ||||||
|  | 	std::vector<std::unique_ptr<Track>> tracks; | ||||||
|  |     for (const auto& location : spec.locations) | ||||||
|  | 	{ | ||||||
|  | 		auto track = std::make_unique<Track>(location.track, location.side); | ||||||
|  | 		track->fluxsource = fluxSource; | ||||||
|  | 		tracks.push_back(std::move(track)); | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  | 		auto track = std::make_unique<Track>(cylinder, side); | ||||||
|  | 		track->fluxsource = &fluxsource; | ||||||
|  |  | ||||||
| 		std::map<int, std::unique_ptr<Sector>> readSectors; | 		std::map<int, std::unique_ptr<Sector>> readSectors; | ||||||
| 		for (int retry = ::retries; retry >= 0; retry--) | 		for (int retry = ::retries; retry >= 0; retry--) | ||||||
| 		{ | 		{ | ||||||
| @@ -284,9 +278,11 @@ void readDiskCommand(AbstractDecoder& decoder) | |||||||
| 			} | 			} | ||||||
|         } |         } | ||||||
|         std::cout << size << " bytes decoded." << std::endl; |         std::cout << size << " bytes decoded." << std::endl; | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     writeSectorsToFile(allSectors, outputSpec); | 	Error() << "write to image not done"; | ||||||
|  |     //writeSectorsToFile(allSectors, outputSpec); | ||||||
| 	if (failures) | 	if (failures) | ||||||
| 		std::cerr << "Warning: some sectors could not be decoded." << std::endl; | 		std::cerr << "Warning: some sectors could not be decoded." << std::endl; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,9 +3,10 @@ | |||||||
|  |  | ||||||
| #include "flags.h" | #include "flags.h" | ||||||
|  |  | ||||||
| class Fluxmap; |  | ||||||
| class FluxSource; |  | ||||||
| class AbstractDecoder; | class AbstractDecoder; | ||||||
|  | class FluxSource; | ||||||
|  | class Fluxmap; | ||||||
|  | class ImageWriter; | ||||||
| class Track; | class Track; | ||||||
|  |  | ||||||
| extern FlagGroup readerFlags; | extern FlagGroup readerFlags; | ||||||
| @@ -17,6 +18,6 @@ extern void setReaderHardSectorCount(int sectorCount); | |||||||
|  |  | ||||||
| extern std::vector<std::unique_ptr<Track>> readTracks(); | extern std::vector<std::unique_ptr<Track>> readTracks(); | ||||||
|  |  | ||||||
| extern void readDiskCommand(AbstractDecoder& decoder); | extern void readDiskCommand(FluxSource& source, AbstractDecoder& decoder, ImageWriter& writer); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ public: | |||||||
| public: | public: | ||||||
|     unsigned physicalTrack; |     unsigned physicalTrack; | ||||||
|     unsigned physicalSide; |     unsigned physicalSide; | ||||||
|     std::shared_ptr<FluxSource> fluxsource; | 	FluxSource* fluxsource; | ||||||
|     std::unique_ptr<Fluxmap> fluxmap; |     std::unique_ptr<Fluxmap> fluxmap; | ||||||
|  |  | ||||||
|     std::vector<RawRecord> rawrecords; |     std::vector<RawRecord> rawrecords; | ||||||
|   | |||||||
| @@ -182,6 +182,7 @@ int mainInspect(int argc, const char* argv[]) | |||||||
| { | { | ||||||
|     flags.parseFlags(argc, argv); |     flags.parseFlags(argc, argv); | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| 	const auto& tracks = readTracks(); | 	const auto& tracks = readTracks(); | ||||||
| 	if (tracks.size() != 1) | 	if (tracks.size() != 1) | ||||||
| 		Error() << "the source dataspec must contain exactly one track (two sides count as two tracks)"; | 		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(); |         const auto& bytes = track->fluxmap->rawBytes(); | ||||||
|         hexdump(std::cout, bytes); |         hexdump(std::cout, bytes); | ||||||
|     } |     } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								src/fe-read.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/fe-read.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <google/protobuf/text_format.h> | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
|  | 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(FluxSource::create(config.input().disk())); | ||||||
|  |  | ||||||
|  | 	std::unique_ptr<AbstractDecoder> decoder; | ||||||
|  | 	if (config.input().disk().has_brother()) | ||||||
|  | 		decoder.reset(new BrotherDecoder()); | ||||||
|  | 	else | ||||||
|  | 		Error() << "no input disk format specified"; | ||||||
|  |  | ||||||
|  | 	std::unique_ptr<ImageWriter> writer; | ||||||
|  | //	if (config.output().file().has_img()) | ||||||
|  | //		write.reset(new ImgImageWriter()); | ||||||
|  | //	else | ||||||
|  | //		Error() << "no output image format specified"; | ||||||
|  |  | ||||||
|  | 	readDiskCommand(*fluxSource, *decoder, *writer); | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -14,6 +14,7 @@ static FlagGroup flags { &writerFlags }; | |||||||
|  |  | ||||||
| int mainWriteFlux(int argc, const char* argv[]) | int mainWriteFlux(int argc, const char* argv[]) | ||||||
| { | { | ||||||
|  | 	#if 0 | ||||||
|     setReaderDefaultSource(":t=0-81:h=0-1"); |     setReaderDefaultSource(":t=0-81:h=0-1"); | ||||||
|     setWriterDefaultDest(":t=0-81:s=0-1"); |     setWriterDefaultDest(":t=0-81:s=0-1"); | ||||||
|     flags.parseFlags(argc, argv); |     flags.parseFlags(argc, argv); | ||||||
| @@ -41,6 +42,7 @@ int mainWriteFlux(int argc, const char* argv[]) | |||||||
|             throw "unreachable"; |             throw "unreachable"; | ||||||
|         } |         } | ||||||
|     ); |     ); | ||||||
|  | 	#endif | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,3 +4,20 @@ input { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | output { | ||||||
|  | 	file { | ||||||
|  | 		filename: "brother.img" | ||||||
|  | 		img {} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cylinders { | ||||||
|  | 	start: 0 | ||||||
|  | 	end: 81 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sides { | ||||||
|  | 	start: 0 | ||||||
|  | 	end: 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -73,8 +73,30 @@ static void test_load(void) | |||||||
| 	std::string s; | 	std::string s; | ||||||
| 	google::protobuf::TextFormat::PrintToString(proto, &s); | 	google::protobuf::TextFormat::PrintToString(proto, &s); | ||||||
| 	s = cleanup(s); | 	s = cleanup(s); | ||||||
| 	AssertThat(s, Equals("u64: 42")); | 	AssertThat(s, Equals("u64: 42 r { } secondoption { }")); | ||||||
| 	AssertThat(r, Equals(true)); | 	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<int>{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<int>{1, 5})); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| int main(int argc, const char* argv[]) | int main(int argc, const char* argv[]) | ||||||
| @@ -82,6 +104,7 @@ int main(int argc, const char* argv[]) | |||||||
| 	test_setting(); | 	test_setting(); | ||||||
| 	test_config(); | 	test_config(); | ||||||
| 	test_load(); | 	test_load(); | ||||||
|  | 	test_range(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,5 +12,10 @@ message TestProto { | |||||||
| 	optional double d = 5; | 	optional double d = 5; | ||||||
| 	optional SubMessage m = 6; | 	optional SubMessage m = 6; | ||||||
| 	repeated SubMessage r = 7; | 	repeated SubMessage r = 7; | ||||||
|  |  | ||||||
|  | 	oneof alt { | ||||||
|  | 		SubMessage firstoption = 8; | ||||||
|  | 		SubMessage secondoption = 9; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,2 +1,4 @@ | |||||||
| u64: 42 | u64: 42 | ||||||
|  | r {} | ||||||
|  | secondoption {} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user