read/write support for AppleSingle files

This commit is contained in:
Wolfgang Thaller 2014-11-08 00:53:36 +01:00
parent 1eda57de45
commit 9a683e24f9
2 changed files with 92 additions and 11 deletions

View File

@ -132,24 +132,39 @@ bool ResourceFile::assign(std::string pathstring, ResourceFile::Format f)
fs::path rsrcPath = path.parent_path() / ".rsrc" / path.filename(); fs::path rsrcPath = path.parent_path() / ".rsrc" / path.filename();
fs::path finfPath = path.parent_path() / ".finf" / 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") if(path.extension() == ".bin")
format = Format::macbin; format = Format::macbin;
else if(path.extension() == ".dsk" || path.extension() == ".img") else if(path.extension() == ".dsk" || path.extension() == ".img")
format = Format::diskimage; format = Format::diskimage;
else if(fs::exists(rsrcPath)) //else if(fs::exists(rsrcPath))
format = Format::basilisk; // format = Format::basilisk;
#ifdef __APPLE__
else 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__
format = Format::real; format = Format::real;
#else #else
else
format = Format::basilisk; format = Format::basilisk;
#endif #endif
} }
else std::cout << "assigned: " << pathstring << " format " << (int)format << "\n";
format = f;
return true; return true;
} }
@ -166,7 +181,7 @@ bool ResourceFile::read()
std::istreambuf_iterator<char>()); std::istreambuf_iterator<char>());
fs::ifstream rsrcIn(path.parent_path() / ".rsrc" / path.filename()); 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()); fs::ifstream finfIn(path.parent_path() / ".finf" / path.filename());
type = ostype(finfIn); type = ostype(finfIn);
creator = ostype(finfIn); creator = ostype(finfIn);
@ -179,7 +194,7 @@ bool ResourceFile::read()
data = std::string(std::istreambuf_iterator<char>(dataIn), data = std::string(std::istreambuf_iterator<char>(dataIn),
std::istreambuf_iterator<char>()); std::istreambuf_iterator<char>());
fs::ifstream rsrcIn(path / "..namedfork" / "rsrc"); fs::ifstream rsrcIn(path / "..namedfork" / "rsrc");
resources.addResources(Resources(rsrcIn)); resources = Resources(rsrcIn);
char finf[32]; char finf[32];
int n = getxattr(path.c_str(), XATTR_FINDERINFO_NAME, int n = getxattr(path.c_str(), XATTR_FINDERINFO_NAME,
@ -191,6 +206,39 @@ bool ResourceFile::read()
} }
break; break;
#endif #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: default:
return false; return false;
} }
@ -246,6 +294,38 @@ bool ResourceFile::write()
writeMacBinary(out, path.stem().string(), type, creator, resources, data); writeMacBinary(out, path.stem().string(), type, creator, resources, data);
} }
break; 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: case Format::diskimage:
{ {
std::ostringstream rsrcOut; std::ostringstream rsrcOut;

View File

@ -17,6 +17,7 @@ public:
macbin, macbin,
diskimage, diskimage,
basilisk, basilisk,
applesingle,
//underscore_ad, //underscore_ad,
//appledouble //appledouble
}; };