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 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<char>());
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<char>(dataIn),
std::istreambuf_iterator<char>());
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;

View File

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