Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
5.3 kB · 162 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163#include "ResourceFork.h"#include "BinaryIO.h"
#include <iostream>#include <map>#include <vector>
void Resources::addResources(const Resources& res){ for(auto& rr : res.resources) addResource(rr.second);}
void Resources::writeFork(std::ostream& out) const{ std::streampos start = out.tellp(); longword(out,0x100); longword(out,0); longword(out,0); longword(out,0); for(int i = 0; i < 0x100 - 16; i++) byte(out, 0);
std::map< ResType, std::map<int, int> > resourceInfos; std::streampos datastart = out.tellp(); for(auto& rr : resources) { const Resource& r = rr.second; const std::string& data = r.getData(); unsigned offset = out.tellp() - datastart; offset = (r.getAttr() << 24) | (offset & 0xFFFFFF); resourceInfos[ r.getType() ][ r.getID() ] = (int)offset; longword(out, data.size()); out << data; } std::streampos dataend = out.tellp();// while(out.tellp() % 0x100)// out.put(0); std::streampos resmap = out.tellp(); for(int i = 0; i < 16+4+2+2; i++) byte(out, 0); word(out,16+4+2+2+2+2); // offset to resource type list std::streampos resnameOffset = out.tellp(); word(out,0); std::streampos typelist = out.tellp(); word(out,resourceInfos.size() - 1); for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); p != resourceInfos.end(); ++p) { if(p->second.size()) { ostype(out,p->first); word(out,p->second.size()-1); word(out,0); // replaced later } } int typeIndex = 0; int nameOffset = 0; for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); p != resourceInfos.end(); ++p) { if(p->second.size()) { std::streampos pos = out.tellp(); out.seekp((int)typelist + 2 + 8 * typeIndex + 6); word(out, pos - typelist); out.seekp(pos); typeIndex++;
for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q) { std::string name = resources.find(ResRef(p->first, q->first))->second.getName(); word(out,q->first); if(name.size() == 0) word(out,-1); else { word(out, nameOffset); nameOffset += (name.size() > 255 ? 255 : name.size()) + 1; } longword(out,q->second); longword(out,0); } } } std::streampos resnames = out.tellp(); out.seekp(resnameOffset); word(out, resnames - resmap); out.seekp(resnames);
for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); p != resourceInfos.end(); ++p) { for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q) { std::string name = resources.find(ResRef(p->first, q->first))->second.getName(); if(name.size() > 0) { int sz = name.size() > 255 ? 255 : name.size(); byte(out, sz); for(int i = 0; i < sz; i++) byte(out, name[i]); } } }
std::streampos end = out.tellp(); out.seekp(start + std::streampos(4)); longword(out, resmap - start); longword(out, dataend - start - std::streampos(0x100)); longword(out, end - resmap); out.seekp(end);}
Resources::Resources(std::istream &in){ std::streampos start = in.tellg(); int resdataOffset = longword(in); int resmapOffset = longword(in);
in.seekg(start + std::streampos(resmapOffset + 16 + 4 + 2 + 2)); int typeListOffset = word(in); int nameListOffset = word(in); int nTypes = (word(in) + 1) & 0xFFFF;
for(int i = 0; i < nTypes; i++) { in.seekg(start + std::streampos(resmapOffset + typeListOffset + 2 + i * 8)); std::string type = ostype(in); int nRes = (word(in) + 1) & 0xFFFF; int refListOffset = word(in);
for(int j = 0; j < nRes; j++) { in.seekg(start + std::streampos(resmapOffset + typeListOffset + refListOffset + j * 12)); int id = (short) word(in); int nameOffset = word(in); int attr = byte(in); int off1 = byte(in); int off2 = byte(in); int off3 = byte(in); int offset = (off1 << 16) | (off2 << 8) | off3; std::string name; if(nameOffset != 0xFFFF) { in.seekg(start + std::streampos(resmapOffset + nameListOffset + nameOffset)); int nameLen = byte(in); char buf[256]; in.read(buf, nameLen); name = std::string(buf, nameLen); }
in.seekg(start + std::streampos(resdataOffset + offset)); int size = longword(in); std::vector<char> tmp(size); in.read(tmp.data(), size); std::string data(tmp.data(), size);
addResource(Resource(type, id, data, name, attr)); } }}