this repo has no description
at fixPythonPipStalling 162 lines 5.3 kB view raw
1#include "ResourceFork.h" 2#include "BinaryIO.h" 3 4#include <iostream> 5#include <map> 6#include <vector> 7 8void Resources::addResources(const Resources& res) 9{ 10 for(auto& rr : res.resources) 11 addResource(rr.second); 12} 13 14void Resources::writeFork(std::ostream& out) const 15{ 16 std::streampos start = out.tellp(); 17 longword(out,0x100); 18 longword(out,0); 19 longword(out,0); 20 longword(out,0); 21 for(int i = 0; i < 0x100 - 16; i++) 22 byte(out, 0); 23 24 std::map< ResType, std::map<int, int> > resourceInfos; 25 std::streampos datastart = out.tellp(); 26 for(auto& rr : resources) 27 { 28 const Resource& r = rr.second; 29 const std::string& data = r.getData(); 30 unsigned offset = out.tellp() - datastart; 31 offset = (r.getAttr() << 24) | (offset & 0xFFFFFF); 32 resourceInfos[ r.getType() ][ r.getID() ] = (int)offset; 33 longword(out, data.size()); 34 out << data; 35 } 36 std::streampos dataend = out.tellp(); 37// while(out.tellp() % 0x100) 38// out.put(0); 39 std::streampos resmap = out.tellp(); 40 for(int i = 0; i < 16+4+2+2; i++) 41 byte(out, 0); 42 word(out,16+4+2+2+2+2); // offset to resource type list 43 std::streampos resnameOffset = out.tellp(); 44 word(out,0); 45 std::streampos typelist = out.tellp(); 46 word(out,resourceInfos.size() - 1); 47 for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); 48 p != resourceInfos.end(); ++p) 49 { 50 if(p->second.size()) 51 { 52 ostype(out,p->first); 53 word(out,p->second.size()-1); 54 word(out,0); // replaced later 55 } 56 } 57 int typeIndex = 0; 58 int nameOffset = 0; 59 for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); 60 p != resourceInfos.end(); ++p) 61 { 62 if(p->second.size()) 63 { 64 std::streampos pos = out.tellp(); 65 out.seekp((int)typelist + 2 + 8 * typeIndex + 6); 66 word(out, pos - typelist); 67 out.seekp(pos); 68 typeIndex++; 69 70 for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q) 71 { 72 std::string name = resources.find(ResRef(p->first, q->first))->second.getName(); 73 word(out,q->first); 74 if(name.size() == 0) 75 word(out,-1); 76 else 77 { 78 word(out, nameOffset); 79 nameOffset += (name.size() > 255 ? 255 : name.size()) + 1; 80 } 81 longword(out,q->second); 82 longword(out,0); 83 } 84 } 85 } 86 std::streampos resnames = out.tellp(); 87 out.seekp(resnameOffset); 88 word(out, resnames - resmap); 89 out.seekp(resnames); 90 91 for(std::map< ResType, std::map<int, int> >::iterator p = resourceInfos.begin(); 92 p != resourceInfos.end(); ++p) 93 { 94 for(std::map<int,int>::iterator q = p->second.begin(); q != p->second.end(); ++q) 95 { 96 std::string name = resources.find(ResRef(p->first, q->first))->second.getName(); 97 if(name.size() > 0) 98 { 99 int sz = name.size() > 255 ? 255 : name.size(); 100 byte(out, sz); 101 for(int i = 0; i < sz; i++) 102 byte(out, name[i]); 103 } 104 } 105 } 106 107 std::streampos end = out.tellp(); 108 out.seekp(start + std::streampos(4)); 109 longword(out, resmap - start); 110 longword(out, dataend - start - std::streampos(0x100)); 111 longword(out, end - resmap); 112 out.seekp(end); 113} 114 115Resources::Resources(std::istream &in) 116{ 117 std::streampos start = in.tellg(); 118 int resdataOffset = longword(in); 119 int resmapOffset = longword(in); 120 121 in.seekg(start + std::streampos(resmapOffset + 16 + 4 + 2 + 2)); 122 int typeListOffset = word(in); 123 int nameListOffset = word(in); 124 int nTypes = (word(in) + 1) & 0xFFFF; 125 126 for(int i = 0; i < nTypes; i++) 127 { 128 in.seekg(start + std::streampos(resmapOffset + typeListOffset + 2 + i * 8)); 129 std::string type = ostype(in); 130 int nRes = (word(in) + 1) & 0xFFFF; 131 int refListOffset = word(in); 132 133 for(int j = 0; j < nRes; j++) 134 { 135 in.seekg(start + std::streampos(resmapOffset + typeListOffset + refListOffset + j * 12)); 136 int id = (short) word(in); 137 int nameOffset = word(in); 138 int attr = byte(in); 139 int off1 = byte(in); 140 int off2 = byte(in); 141 int off3 = byte(in); 142 int offset = (off1 << 16) | (off2 << 8) | off3; 143 std::string name; 144 if(nameOffset != 0xFFFF) 145 { 146 in.seekg(start + std::streampos(resmapOffset + nameListOffset + nameOffset)); 147 int nameLen = byte(in); 148 char buf[256]; 149 in.read(buf, nameLen); 150 name = std::string(buf, nameLen); 151 } 152 153 in.seekg(start + std::streampos(resdataOffset + offset)); 154 int size = longword(in); 155 std::vector<char> tmp(size); 156 in.read(tmp.data(), size); 157 std::string data(tmp.data(), size); 158 159 addResource(Resource(type, id, data, name, attr)); 160 } 161 } 162}