From 9a683e24f9fbde40276a0fb6f9716fbe37e7aa5d Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sat, 8 Nov 2014 00:53:36 +0100 Subject: [PATCH] read/write support for AppleSingle files --- ResourceFiles/ResourceFile.cc | 102 ++++++++++++++++++++++++++++++---- ResourceFiles/ResourceFile.h | 1 + 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/ResourceFiles/ResourceFile.cc b/ResourceFiles/ResourceFile.cc index 46c3d51777..f72d6e5068 100644 --- a/ResourceFiles/ResourceFile.cc +++ b/ResourceFiles/ResourceFile.cc @@ -132,24 +132,39 @@ bool ResourceFile::assign(std::string pathstring, ResourceFile::Format f) fs::path rsrcPath = path.parent_path() / ".rsrc" / path.filename(); fs::path finfPath = path.parent_path() / ".finf" / path.filename(); - if(f == Format::autodetect) + format = f; + if(format == Format::autodetect) { if(path.extension() == ".bin") format = Format::macbin; else if(path.extension() == ".dsk" || path.extension() == ".img") format = Format::diskimage; - else if(fs::exists(rsrcPath)) - format = Format::basilisk; + //else if(fs::exists(rsrcPath)) + // format = Format::basilisk; + else + { + fs::ifstream in(path); + if(in) + { + int magic1 = longword(in); + if(in && magic1 == 0x00051600) + { + int magic2 = longword(in); + if(in && magic2 == 0x00020000) + format = Format::applesingle; + } + } + } + } + if(format == Format::autodetect) + { #ifdef __APPLE__ - else - format = Format::real; + format = Format::real; #else - else - format = Format::basilisk; + format = Format::basilisk; #endif } - else - format = f; + std::cout << "assigned: " << pathstring << " format " << (int)format << "\n"; return true; } @@ -166,7 +181,7 @@ bool ResourceFile::read() std::istreambuf_iterator()); fs::ifstream rsrcIn(path.parent_path() / ".rsrc" / path.filename()); - resources.addResources(Resources(rsrcIn)); + resources = Resources(rsrcIn); fs::ifstream finfIn(path.parent_path() / ".finf" / path.filename()); type = ostype(finfIn); creator = ostype(finfIn); @@ -179,7 +194,7 @@ bool ResourceFile::read() data = std::string(std::istreambuf_iterator(dataIn), std::istreambuf_iterator()); fs::ifstream rsrcIn(path / "..namedfork" / "rsrc"); - resources.addResources(Resources(rsrcIn)); + resources = Resources(rsrcIn); char finf[32]; int n = getxattr(path.c_str(), XATTR_FINDERINFO_NAME, @@ -191,6 +206,39 @@ bool ResourceFile::read() } break; #endif + case Format::applesingle: + { + fs::ifstream in(path); + if(longword(in) != 0x00051600) + return false; + if(longword(in) != 0x00020000) + return false; + in.seekg(24); + int n = word(in); + for(int i = 0; i < n; i++) + { + in.seekg(26 + i * 12); + int what = longword(in); + int off = longword(in); + //int len = longword(in); + in.seekg(off); + switch(what) + { + case 1: + // ### + break; + case 2: + resources = Resources(in); + break; + case 9: + type = ostype(in); + creator = ostype(in); + break; + } + } + } + break; + default: return false; } @@ -246,6 +294,38 @@ bool ResourceFile::write() writeMacBinary(out, path.stem().string(), type, creator, resources, data); } break; + case Format::applesingle: + { + fs::ofstream out(path); + longword(out, 0x00051600); + longword(out, 0x00020000); + for(int i = 0; i < 16; i++) + byte(out, 0); + word(out, 3); + std::streampos entries = out.tellp(); + for(int i = 0; i < 3*3; i++) + longword(out, 0); + std::streampos dataStart = out.tellp(); + out << data; + std::streampos rsrcStart = out.tellp(); + resources.writeFork(out); + std::streampos finfStart = out.tellp(); + ostype(out, type); + ostype(out, creator); + for(int i = 8; i < 32; i++) + byte(out, 0); + out.seekp(entries); + longword(out, 1); + longword(out, dataStart); + longword(out, rsrcStart - dataStart); + longword(out, 2); + longword(out, rsrcStart); + longword(out, finfStart - rsrcStart); + longword(out, 3); + longword(out, finfStart); + longword(out, 32); + } + break; case Format::diskimage: { std::ostringstream rsrcOut; diff --git a/ResourceFiles/ResourceFile.h b/ResourceFiles/ResourceFile.h index 1021db2562..415710efb2 100644 --- a/ResourceFiles/ResourceFile.h +++ b/ResourceFiles/ResourceFile.h @@ -17,6 +17,7 @@ public: macbin, diskimage, basilisk, + applesingle, //underscore_ad, //appledouble };