Showing the changes to ResourceFiles/ResourceFile.cc (1 of 133 files). Show all
Unified · Split
| @@ -17,94 +17,94 @@ namespace fs = boost::filesystem; · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | // CRC 16 table lookup array |
| 19 | 19 | static unsigned short CRC16Table[256] = |
| 20 | − {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, | |
| 21 | − 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, | |
| 22 | − 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, | |
| 23 | − 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, | |
| 24 | − 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, | |
| 25 | − 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, | |
| 26 | − 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, | |
| 27 | − 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, | |
| 28 | − 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, | |
| 29 | − 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, | |
| 30 | − 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, | |
| 31 | − 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, | |
| 32 | − 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, | |
| 33 | − 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, | |
| 34 | − 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, | |
| 35 | − 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, | |
| 36 | − 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, | |
| 37 | − 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, | |
| 38 | − 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, | |
| 39 | − 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, | |
| 40 | − 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, | |
| 41 | − 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, | |
| 42 | − 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, | |
| 43 | − 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, | |
| 44 | − 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, | |
| 45 | − 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, | |
| 46 | − 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, | |
| 47 | − 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, | |
| 48 | − 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, | |
| 49 | − 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, | |
| 50 | − 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, | |
| 51 | − 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; | |
| 20 | + {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, | |
| 21 | + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, | |
| 22 | + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, | |
| 23 | + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, | |
| 24 | + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, | |
| 25 | + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, | |
| 26 | + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, | |
| 27 | + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, | |
| 28 | + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, | |
| 29 | + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, | |
| 30 | + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, | |
| 31 | + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, | |
| 32 | + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, | |
| 33 | + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, | |
| 34 | + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, | |
| 35 | + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, | |
| 36 | + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, | |
| 37 | + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, | |
| 38 | + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, | |
| 39 | + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, | |
| 40 | + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, | |
| 41 | + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, | |
| 42 | + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, | |
| 43 | + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, | |
| 44 | + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, | |
| 45 | + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, | |
| 46 | + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, | |
| 47 | + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, | |
| 48 | + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, | |
| 49 | + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, | |
| 50 | + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, | |
| 51 | + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; | |
| 52 | 52 | |
| 53 | 53 | // CalculateCRC |
| 54 | 54 | static unsigned short CalculateCRC(unsigned short CRC, const char* dataBlock, int dataSize) |
| 55 | 55 | { |
| 56 | − while (dataSize) | |
| 57 | − { | |
| 58 | − CRC = (CRC << 8) ^ CRC16Table[((*dataBlock) ^ (CRC >> 8)) & 0x00FF]; | |
| 59 | − dataBlock++; | |
| 60 | − dataSize--; | |
| 61 | − } | |
| 62 | − | |
| 63 | − return CRC; | |
| 56 | + while (dataSize) | |
| 57 | + { | |
| 58 | + CRC = (CRC << 8) ^ CRC16Table[((*dataBlock) ^ (CRC >> 8)) & 0x00FF]; | |
| 59 | + dataBlock++; | |
| 60 | + dataSize--; | |
| 61 | + } | |
| 62 | + | |
| 63 | + return CRC; | |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | static void writeMacBinary(std::ostream& out, std::string filename, |
| 67 | − ResType type, ResType creator, | |
| 68 | − const Resources& rsrc, const std::string& data) | |
| 67 | + ResType type, ResType creator, | |
| 68 | + const Resources& rsrc, const std::string& data) | |
| 69 | 69 | { |
| 70 | 70 | |
| 71 | − std::ostringstream resstream; | |
| 72 | − rsrc.writeFork(resstream); | |
| 73 | − | |
| 74 | − const std::string& rsrcBytes = resstream.str(); | |
| 75 | − | |
| 76 | − | |
| 77 | − std::ostringstream header; | |
| 78 | − byte(header, 0); | |
| 79 | − byte(header, filename.size()); | |
| 80 | − header << filename; | |
| 81 | − while((int)header.tellp() < 65) | |
| 82 | − byte(header,0); | |
| 83 | − ostype(header, type); | |
| 84 | − ostype(header, creator); | |
| 85 | − byte(header, 0); // flags | |
| 86 | − byte(header, 0); | |
| 87 | − word(header, 0); // position.v | |
| 88 | − word(header, 0); // position.h | |
| 89 | − word(header, 0); // folder id | |
| 90 | − byte(header, 0); // protected flag | |
| 91 | − byte(header, 0); | |
| 92 | − longword(header, (int)data.size()); | |
| 93 | − longword(header, (int)rsrcBytes.size()); | |
| 94 | − longword(header, 0); // creation date | |
| 95 | − longword(header, 0); // modification date | |
| 96 | − while((int)header.tellp() < 124) | |
| 97 | − byte(header,0); | |
| 98 | − std::string headerData = header.str(); | |
| 99 | − out << headerData; | |
| 100 | − word(out, CalculateCRC(0, &headerData[0], headerData.size())); | |
| 101 | − word(out, 0); | |
| 102 | − out << data; | |
| 103 | − while((int)out.tellp() % 128) | |
| 104 | − byte(out,0); | |
| 105 | − rsrc.writeFork(out); | |
| 106 | − while((int)out.tellp() % 128) | |
| 107 | − byte(out,0); | |
| 71 | + std::ostringstream resstream; | |
| 72 | + rsrc.writeFork(resstream); | |
| 73 | + | |
| 74 | + const std::string& rsrcBytes = resstream.str(); | |
| 75 | + | |
| 76 | + | |
| 77 | + std::ostringstream header; | |
| 78 | + byte(header, 0); | |
| 79 | + byte(header, filename.size()); | |
| 80 | + header << filename; | |
| 81 | + while((int)header.tellp() < 65) | |
| 82 | + byte(header,0); | |
| 83 | + ostype(header, type); | |
| 84 | + ostype(header, creator); | |
| 85 | + byte(header, 0); // flags | |
| 86 | + byte(header, 0); | |
| 87 | + word(header, 0); // position.v | |
| 88 | + word(header, 0); // position.h | |
| 89 | + word(header, 0); // folder id | |
| 90 | + byte(header, 0); // protected flag | |
| 91 | + byte(header, 0); | |
| 92 | + longword(header, (int)data.size()); | |
| 93 | + longword(header, (int)rsrcBytes.size()); | |
| 94 | + longword(header, 0); // creation date | |
| 95 | + longword(header, 0); // modification date | |
| 96 | + while((int)header.tellp() < 124) | |
| 97 | + byte(header,0); | |
| 98 | + std::string headerData = header.str(); | |
| 99 | + out << headerData; | |
| 100 | + word(out, CalculateCRC(0, &headerData[0], headerData.size())); | |
| 101 | + word(out, 0); | |
| 102 | + out << data; | |
| 103 | + while((int)out.tellp() % 128) | |
| 104 | + byte(out,0); | |
| 105 | + rsrc.writeFork(out); | |
| 106 | + while((int)out.tellp() % 128) | |
| 107 | + byte(out,0); | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | |
| @@ -115,7 +115,7 @@ ResourceFile::ResourceFile() · 4 unmodified lines | ||
| 115 | 115 | |
| 116 | 116 | ResourceFile::ResourceFile(std::string path, ResourceFile::Format f) |
| 117 | 117 | { |
| 118 | − assign(path, f); | |
| 118 | + assign(path, f); | |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | 121 | ResourceFile::~ResourceFile() |
| @@ -125,464 +125,464 @@ ResourceFile::~ResourceFile() · 3 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | static bool CheckAppleDouble(fs::path path, std::string prefix) |
| 127 | 127 | { |
| 128 | − fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 129 | − fs::ifstream in(adPath); | |
| 130 | − if(in) | |
| 131 | − { | |
| 132 | − int magic1 = longword(in); | |
| 133 | − | |
| 134 | − if(in && magic1 == 0x00051607) | |
| 135 | − { | |
| 136 | − int magic2 = longword(in); | |
| 137 | − if(in && magic2 == 0x00020000) | |
| 138 | − return true; | |
| 139 | − } | |
| 140 | − } | |
| 141 | − return false; | |
| 128 | + fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 129 | + fs::ifstream in(adPath); | |
| 130 | + if(in) | |
| 131 | + { | |
| 132 | + int magic1 = longword(in); | |
| 133 | + | |
| 134 | + if(in && magic1 == 0x00051607) | |
| 135 | + { | |
| 136 | + int magic2 = longword(in); | |
| 137 | + if(in && magic2 == 0x00020000) | |
| 138 | + return true; | |
| 139 | + } | |
| 140 | + } | |
| 141 | + return false; | |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | bool ResourceFile::assign(std::string pathstring, ResourceFile::Format f) |
| 145 | 145 | { |
| 146 | − this->pathstring = pathstring; | |
| 147 | − fs::path path(pathstring); | |
| 148 | − | |
| 149 | − this->filename = path.stem().string(); | |
| 150 | − fs::path rsrcPath = path.parent_path() / ".rsrc" / path.filename(); | |
| 151 | − fs::path finfPath = path.parent_path() / ".finf" / path.filename(); | |
| 152 | − | |
| 153 | − format = f; | |
| 154 | − if(format == Format::autodetect) | |
| 155 | − { | |
| 156 | − if(path.extension() == ".bin") | |
| 157 | − format = Format::macbin; | |
| 158 | − else if(path.extension() == ".as") | |
| 159 | − format = Format::applesingle; | |
| 160 | − else if(path.extension() == ".dsk" || path.extension() == ".img") | |
| 161 | − format = Format::diskimage; | |
| 162 | − else if(path.filename().string().substr(0,2) == "._") | |
| 163 | − { | |
| 164 | − path = path.parent_path() / path.filename().string().substr(2); | |
| 165 | − format = Format::underscore_appledouble; | |
| 166 | − this->pathstring = path.string(); | |
| 167 | − } | |
| 168 | − else if(path.filename().string()[0] == '%') | |
| 169 | − { | |
| 170 | − path = path.parent_path() / path.filename().string().substr(1); | |
| 171 | − format = Format::percent_appledouble; | |
| 172 | − this->pathstring = path.string(); | |
| 173 | − } | |
| 174 | − //else if(fs::exists(rsrcPath)) | |
| 175 | − // format = Format::basilisk; | |
| 176 | − } | |
| 177 | − if(format == Format::autodetect) | |
| 178 | − { | |
| 179 | − if(CheckAppleDouble(path, "._")) | |
| 180 | − format = Format::underscore_appledouble; | |
| 181 | − if(CheckAppleDouble(path, "%")) | |
| 182 | − format = Format::percent_appledouble; | |
| 183 | − } | |
| 184 | − if(format == Format::autodetect) | |
| 185 | − { | |
| 186 | − fs::ifstream in(path); | |
| 187 | − if(in) | |
| 188 | − { | |
| 189 | − int magic1 = longword(in); | |
| 190 | − if(in && magic1 == 0x00051600) | |
| 191 | − { | |
| 192 | − int magic2 = longword(in); | |
| 193 | − if(in && magic2 == 0x00020000) | |
| 194 | − format = Format::applesingle; | |
| 195 | − } | |
| 196 | − } | |
| 197 | − } | |
| 198 | − if(format == Format::autodetect) | |
| 199 | − { | |
| 146 | + this->pathstring = pathstring; | |
| 147 | + fs::path path(pathstring); | |
| 148 | + | |
| 149 | + this->filename = path.stem().string(); | |
| 150 | + fs::path rsrcPath = path.parent_path() / ".rsrc" / path.filename(); | |
| 151 | + fs::path finfPath = path.parent_path() / ".finf" / path.filename(); | |
| 152 | + | |
| 153 | + format = f; | |
| 154 | + if(format == Format::autodetect) | |
| 155 | + { | |
| 156 | + if(path.extension() == ".bin") | |
| 157 | + format = Format::macbin; | |
| 158 | + else if(path.extension() == ".as") | |
| 159 | + format = Format::applesingle; | |
| 160 | + else if(path.extension() == ".dsk" || path.extension() == ".img") | |
| 161 | + format = Format::diskimage; | |
| 162 | + else if(path.filename().string().substr(0,2) == "._") | |
| 163 | + { | |
| 164 | + path = path.parent_path() / path.filename().string().substr(2); | |
| 165 | + format = Format::underscore_appledouble; | |
| 166 | + this->pathstring = path.string(); | |
| 167 | + } | |
| 168 | + else if(path.filename().string()[0] == '%') | |
| 169 | + { | |
| 170 | + path = path.parent_path() / path.filename().string().substr(1); | |
| 171 | + format = Format::percent_appledouble; | |
| 172 | + this->pathstring = path.string(); | |
| 173 | + } | |
| 174 | + //else if(fs::exists(rsrcPath)) | |
| 175 | + // format = Format::basilisk; | |
| 176 | + } | |
| 177 | + if(format == Format::autodetect) | |
| 178 | + { | |
| 179 | + if(CheckAppleDouble(path, "._")) | |
| 180 | + format = Format::underscore_appledouble; | |
| 181 | + if(CheckAppleDouble(path, "%")) | |
| 182 | + format = Format::percent_appledouble; | |
| 183 | + } | |
| 184 | + if(format == Format::autodetect) | |
| 185 | + { | |
| 186 | + fs::ifstream in(path); | |
| 187 | + if(in) | |
| 188 | + { | |
| 189 | + int magic1 = longword(in); | |
| 190 | + if(in && magic1 == 0x00051600) | |
| 191 | + { | |
| 192 | + int magic2 = longword(in); | |
| 193 | + if(in && magic2 == 0x00020000) | |
| 194 | + format = Format::applesingle; | |
| 195 | + } | |
| 196 | + } | |
| 197 | + } | |
| 198 | + if(format == Format::autodetect) | |
| 199 | + { | |
| 200 | 200 | #ifdef __APPLE__ |
| 201 | − format = Format::real; | |
| 201 | + format = Format::real; | |
| 202 | 202 | #else |
| 203 | − format = Format::basilisk; | |
| 203 | + format = Format::basilisk; | |
| 204 | 204 | #endif |
| 205 | − } | |
| 206 | −// std::cout << "assigned: " << pathstring << " format " << (int)format << "\n"; | |
| 207 | − return true; | |
| 205 | + } | |
| 206 | +// std::cout << "assigned: " << pathstring << " format " << (int)format << "\n"; | |
| 207 | + return true; | |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | 210 | bool ResourceFile::read(std::istream& in, Format f) |
| 211 | 211 | { |
| 212 | − switch(f) | |
| 213 | − { | |
| 214 | − case Format::applesingle: | |
| 215 | − { | |
| 216 | − if(longword(in) != 0x00051600) | |
| 217 | − return false; | |
| 218 | − if(longword(in) != 0x00020000) | |
| 219 | − return false; | |
| 220 | − in.seekg(24); | |
| 221 | − int n = word(in); | |
| 222 | − for(int i = 0; i < n; i++) | |
| 223 | − { | |
| 224 | − in.seekg(26 + i * 12); | |
| 225 | − int what = longword(in); | |
| 226 | − int off = longword(in); | |
| 227 | − int len = longword(in); | |
| 228 | − in.seekg(off); | |
| 229 | − switch(what) | |
| 230 | − { | |
| 231 | − case 1: | |
| 232 | − { | |
| 233 | − std::vector<char> buf(len); | |
| 234 | − in.read(buf.data(), len); | |
| 235 | − data = std::string(buf.begin(), buf.end()); | |
| 236 | − } | |
| 237 | − break; | |
| 238 | − case 2: | |
| 239 | − resources = Resources(in); | |
| 240 | − break; | |
| 241 | − case 9: | |
| 242 | − type = ostype(in); | |
| 243 | − creator = ostype(in); | |
| 244 | − break; | |
| 245 | − } | |
| 246 | − } | |
| 247 | − } | |
| 248 | − break; | |
| 249 | − case Format::macbin: | |
| 250 | − { | |
| 251 | − if(byte(in) != 0) | |
| 252 | − return false; | |
| 253 | − if(byte(in) > 63) | |
| 254 | − return false; | |
| 255 | − in.seekg(65); | |
| 256 | − type = ostype(in); | |
| 257 | − creator = ostype(in); | |
| 258 | − in.seekg(83); | |
| 259 | − int datasize = longword(in); | |
| 260 | − //int rsrcsize = longword(in); | |
| 261 | − | |
| 262 | − in.seekg(0); | |
| 263 | − char header[124]; | |
| 264 | − in.read(header, 124); | |
| 265 | − unsigned short crc = CalculateCRC(0,header,124); | |
| 266 | − if(word(in) != crc) | |
| 267 | − return false; | |
| 268 | − in.seekg(128); | |
| 269 | − std::vector<char> buf(datasize); | |
| 270 | − in.read(buf.data(), datasize); | |
| 271 | − data = std::string(buf.begin(), buf.end()); | |
| 272 | − datasize = ((int)datasize + 0x7F) & ~0x7F; | |
| 273 | − in.seekg(128 + datasize); | |
| 274 | − resources = Resources(in); | |
| 275 | − } | |
| 276 | − break; | |
| 277 | − default: | |
| 278 | − return false; | |
| 279 | − } | |
| 280 | − return true; | |
| 212 | + switch(f) | |
| 213 | + { | |
| 214 | + case Format::applesingle: | |
| 215 | + { | |
| 216 | + if(longword(in) != 0x00051600) | |
| 217 | + return false; | |
| 218 | + if(longword(in) != 0x00020000) | |
| 219 | + return false; | |
| 220 | + in.seekg(24); | |
| 221 | + int n = word(in); | |
| 222 | + for(int i = 0; i < n; i++) | |
| 223 | + { | |
| 224 | + in.seekg(26 + i * 12); | |
| 225 | + int what = longword(in); | |
| 226 | + int off = longword(in); | |
| 227 | + int len = longword(in); | |
| 228 | + in.seekg(off); | |
| 229 | + switch(what) | |
| 230 | + { | |
| 231 | + case 1: | |
| 232 | + { | |
| 233 | + std::vector<char> buf(len); | |
| 234 | + in.read(buf.data(), len); | |
| 235 | + data = std::string(buf.begin(), buf.end()); | |
| 236 | + } | |
| 237 | + break; | |
| 238 | + case 2: | |
| 239 | + resources = Resources(in); | |
| 240 | + break; | |
| 241 | + case 9: | |
| 242 | + type = ostype(in); | |
| 243 | + creator = ostype(in); | |
| 244 | + break; | |
| 245 | + } | |
| 246 | + } | |
| 247 | + } | |
| 248 | + break; | |
| 249 | + case Format::macbin: | |
| 250 | + { | |
| 251 | + if(byte(in) != 0) | |
| 252 | + return false; | |
| 253 | + if(byte(in) > 63) | |
| 254 | + return false; | |
| 255 | + in.seekg(65); | |
| 256 | + type = ostype(in); | |
| 257 | + creator = ostype(in); | |
| 258 | + in.seekg(83); | |
| 259 | + int datasize = longword(in); | |
| 260 | + //int rsrcsize = longword(in); | |
| 261 | + | |
| 262 | + in.seekg(0); | |
| 263 | + char header[124]; | |
| 264 | + in.read(header, 124); | |
| 265 | + unsigned short crc = CalculateCRC(0,header,124); | |
| 266 | + if(word(in) != crc) | |
| 267 | + return false; | |
| 268 | + in.seekg(128); | |
| 269 | + std::vector<char> buf(datasize); | |
| 270 | + in.read(buf.data(), datasize); | |
| 271 | + data = std::string(buf.begin(), buf.end()); | |
| 272 | + datasize = ((int)datasize + 0x7F) & ~0x7F; | |
| 273 | + in.seekg(128 + datasize); | |
| 274 | + resources = Resources(in); | |
| 275 | + } | |
| 276 | + break; | |
| 277 | + default: | |
| 278 | + return false; | |
| 279 | + } | |
| 280 | + return true; | |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | 283 | bool ResourceFile::read() |
| 284 | 284 | { |
| 285 | − fs::path path(pathstring); | |
| 286 | − | |
| 287 | − type = creator = 0x3F3F3F3F; | |
| 288 | − | |
| 289 | − if(isSingleFork(format)) | |
| 290 | − { | |
| 291 | − fs::ifstream in(path); | |
| 292 | − return read(in, format); | |
| 293 | − } | |
| 294 | − | |
| 295 | − switch(format) | |
| 296 | − { | |
| 297 | − case Format::basilisk: | |
| 298 | − { | |
| 299 | − fs::ifstream dataIn(path); | |
| 300 | − if(!dataIn) | |
| 301 | − return false; | |
| 302 | − data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 303 | − std::istreambuf_iterator<char>()); | |
| 304 | − | |
| 305 | − fs::ifstream rsrcIn(path.parent_path() / ".rsrc" / path.filename()); | |
| 306 | − if(rsrcIn) | |
| 307 | − resources = Resources(rsrcIn); | |
| 308 | − fs::ifstream finfIn(path.parent_path() / ".finf" / path.filename()); | |
| 309 | − if(finfIn) | |
| 310 | − { | |
| 311 | − type = ostype(finfIn); | |
| 312 | − creator = ostype(finfIn); | |
| 313 | − } | |
| 314 | − } | |
| 315 | − break; | |
| 285 | + fs::path path(pathstring); | |
| 286 | + | |
| 287 | + type = creator = 0x3F3F3F3F; | |
| 288 | + | |
| 289 | + if(isSingleFork(format)) | |
| 290 | + { | |
| 291 | + fs::ifstream in(path); | |
| 292 | + return read(in, format); | |
| 293 | + } | |
| 294 | + | |
| 295 | + switch(format) | |
| 296 | + { | |
| 297 | + case Format::basilisk: | |
| 298 | + { | |
| 299 | + fs::ifstream dataIn(path); | |
| 300 | + if(!dataIn) | |
| 301 | + return false; | |
| 302 | + data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 303 | + std::istreambuf_iterator<char>()); | |
| 304 | + | |
| 305 | + fs::ifstream rsrcIn(path.parent_path() / ".rsrc" / path.filename()); | |
| 306 | + if(rsrcIn) | |
| 307 | + resources = Resources(rsrcIn); | |
| 308 | + fs::ifstream finfIn(path.parent_path() / ".finf" / path.filename()); | |
| 309 | + if(finfIn) | |
| 310 | + { | |
| 311 | + type = ostype(finfIn); | |
| 312 | + creator = ostype(finfIn); | |
| 313 | + } | |
| 314 | + } | |
| 315 | + break; | |
| 316 | 316 | #ifdef __APPLE__ |
| 317 | − case Format::real: | |
| 318 | − { | |
| 319 | − fs::ifstream dataIn(path); | |
| 320 | − if(!dataIn) | |
| 321 | − return false; | |
| 322 | − data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 323 | − std::istreambuf_iterator<char>()); | |
| 324 | − fs::ifstream rsrcIn(path / "..namedfork" / "rsrc"); | |
| 325 | − if(rsrcIn) | |
| 326 | − resources = Resources(rsrcIn); | |
| 327 | − | |
| 328 | − char finf[32]; | |
| 329 | − int n = getxattr(path.c_str(), XATTR_FINDERINFO_NAME, | |
| 330 | − finf, 32, 0, 0); | |
| 331 | − if(n > 0) | |
| 332 | − { | |
| 333 | − std::istringstream finfIn(std::string(finf, finf+n)); | |
| 334 | − type = ostype(finfIn); | |
| 335 | − creator = ostype(finfIn); | |
| 336 | − } | |
| 337 | − } | |
| 338 | − break; | |
| 317 | + case Format::real: | |
| 318 | + { | |
| 319 | + fs::ifstream dataIn(path); | |
| 320 | + if(!dataIn) | |
| 321 | + return false; | |
| 322 | + data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 323 | + std::istreambuf_iterator<char>()); | |
| 324 | + fs::ifstream rsrcIn(path / "..namedfork" / "rsrc"); | |
| 325 | + if(rsrcIn) | |
| 326 | + resources = Resources(rsrcIn); | |
| 327 | + | |
| 328 | + char finf[32]; | |
| 329 | + int n = getxattr(path.c_str(), XATTR_FINDERINFO_NAME, | |
| 330 | + finf, 32, 0, 0); | |
| 331 | + if(n > 0) | |
| 332 | + { | |
| 333 | + std::istringstream finfIn(std::string(finf, finf+n)); | |
| 334 | + type = ostype(finfIn); | |
| 335 | + creator = ostype(finfIn); | |
| 336 | + } | |
| 337 | + } | |
| 338 | + break; | |
| 339 | 339 | #endif |
| 340 | 340 | |
| 341 | − case Format::underscore_appledouble: | |
| 342 | − case Format::percent_appledouble: | |
| 343 | − { | |
| 344 | − fs::ifstream dataIn(path); | |
| 345 | − data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 346 | − std::istreambuf_iterator<char>()); | |
| 347 | − | |
| 348 | − std::string prefix = format == Format::underscore_appledouble ? | |
| 349 | − "._" : "%"; | |
| 350 | − | |
| 351 | − fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 352 | − fs::ifstream in(adPath); | |
| 353 | − if(longword(in) != 0x00051607) | |
| 354 | − return false; | |
| 355 | − if(longword(in) != 0x00020000) | |
| 356 | − return false; | |
| 357 | − in.seekg(24); | |
| 358 | − int n = word(in); | |
| 359 | − for(int i = 0; i < n; i++) | |
| 360 | − { | |
| 361 | − in.seekg(26 + i * 12); | |
| 362 | − int what = longword(in); | |
| 363 | − int off = longword(in); | |
| 364 | − //int len = longword(in); | |
| 365 | − in.seekg(off); | |
| 366 | − switch(what) | |
| 367 | − { | |
| 368 | − case 2: | |
| 369 | − resources = Resources(in); | |
| 370 | − break; | |
| 371 | − case 9: | |
| 372 | − type = ostype(in); | |
| 373 | − creator = ostype(in); | |
| 374 | − break; | |
| 375 | − } | |
| 376 | − } | |
| 377 | − } | |
| 378 | − break; | |
| 379 | − default: | |
| 380 | − return false; | |
| 381 | − } | |
| 382 | − return true; | |
| 341 | + case Format::underscore_appledouble: | |
| 342 | + case Format::percent_appledouble: | |
| 343 | + { | |
| 344 | + fs::ifstream dataIn(path); | |
| 345 | + data = std::string(std::istreambuf_iterator<char>(dataIn), | |
| 346 | + std::istreambuf_iterator<char>()); | |
| 347 | + | |
| 348 | + std::string prefix = format == Format::underscore_appledouble ? | |
| 349 | + "._" : "%"; | |
| 350 | + | |
| 351 | + fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 352 | + fs::ifstream in(adPath); | |
| 353 | + if(longword(in) != 0x00051607) | |
| 354 | + return false; | |
| 355 | + if(longword(in) != 0x00020000) | |
| 356 | + return false; | |
| 357 | + in.seekg(24); | |
| 358 | + int n = word(in); | |
| 359 | + for(int i = 0; i < n; i++) | |
| 360 | + { | |
| 361 | + in.seekg(26 + i * 12); | |
| 362 | + int what = longword(in); | |
| 363 | + int off = longword(in); | |
| 364 | + //int len = longword(in); | |
| 365 | + in.seekg(off); | |
| 366 | + switch(what) | |
| 367 | + { | |
| 368 | + case 2: | |
| 369 | + resources = Resources(in); | |
| 370 | + break; | |
| 371 | + case 9: | |
| 372 | + type = ostype(in); | |
| 373 | + creator = ostype(in); | |
| 374 | + break; | |
| 375 | + } | |
| 376 | + } | |
| 377 | + } | |
| 378 | + break; | |
| 379 | + default: | |
| 380 | + return false; | |
| 381 | + } | |
| 382 | + return true; | |
| 383 | 383 | } |
| 384 | 384 | |
| 385 | 385 | bool ResourceFile::write(std::ostream& out, Format f) |
| 386 | 386 | { |
| 387 | − switch(f) | |
| 388 | − { | |
| 389 | − case Format::macbin: | |
| 390 | − { | |
| 391 | − writeMacBinary(out, filename, type, creator, resources, data); | |
| 392 | − } | |
| 393 | − break; | |
| 394 | − case Format::applesingle: | |
| 395 | − { | |
| 396 | − longword(out, 0x00051600); | |
| 397 | − longword(out, 0x00020000); | |
| 398 | − for(int i = 0; i < 16; i++) | |
| 399 | − byte(out, 0); | |
| 400 | − word(out, 3); | |
| 401 | − std::streampos entries = out.tellp(); | |
| 402 | − for(int i = 0; i < 3*3; i++) | |
| 403 | − longword(out, 0); | |
| 404 | − std::streampos dataStart = out.tellp(); | |
| 405 | − out << data; | |
| 406 | − std::streampos rsrcStart = out.tellp(); | |
| 407 | − resources.writeFork(out); | |
| 408 | − std::streampos finfStart = out.tellp(); | |
| 409 | − ostype(out, type); | |
| 410 | − ostype(out, creator); | |
| 411 | − for(int i = 8; i < 32; i++) | |
| 412 | − byte(out, 0); | |
| 413 | − out.seekp(entries); | |
| 414 | − longword(out, 1); | |
| 415 | − longword(out, dataStart); | |
| 416 | − longword(out, rsrcStart - dataStart); | |
| 417 | − longword(out, 2); | |
| 418 | − longword(out, rsrcStart); | |
| 419 | − longword(out, finfStart - rsrcStart); | |
| 420 | − longword(out, 9); | |
| 421 | − longword(out, finfStart); | |
| 422 | − longword(out, 32); | |
| 423 | − } | |
| 424 | − break; | |
| 425 | − default: | |
| 426 | − return false; | |
| 427 | − } | |
| 428 | − return true; | |
| 387 | + switch(f) | |
| 388 | + { | |
| 389 | + case Format::macbin: | |
| 390 | + { | |
| 391 | + writeMacBinary(out, filename, type, creator, resources, data); | |
| 392 | + } | |
| 393 | + break; | |
| 394 | + case Format::applesingle: | |
| 395 | + { | |
| 396 | + longword(out, 0x00051600); | |
| 397 | + longword(out, 0x00020000); | |
| 398 | + for(int i = 0; i < 16; i++) | |
| 399 | + byte(out, 0); | |
| 400 | + word(out, 3); | |
| 401 | + std::streampos entries = out.tellp(); | |
| 402 | + for(int i = 0; i < 3*3; i++) | |
| 403 | + longword(out, 0); | |
| 404 | + std::streampos dataStart = out.tellp(); | |
| 405 | + out << data; | |
| 406 | + std::streampos rsrcStart = out.tellp(); | |
| 407 | + resources.writeFork(out); | |
| 408 | + std::streampos finfStart = out.tellp(); | |
| 409 | + ostype(out, type); | |
| 410 | + ostype(out, creator); | |
| 411 | + for(int i = 8; i < 32; i++) | |
| 412 | + byte(out, 0); | |
| 413 | + out.seekp(entries); | |
| 414 | + longword(out, 1); | |
| 415 | + longword(out, dataStart); | |
| 416 | + longword(out, rsrcStart - dataStart); | |
| 417 | + longword(out, 2); | |
| 418 | + longword(out, rsrcStart); | |
| 419 | + longword(out, finfStart - rsrcStart); | |
| 420 | + longword(out, 9); | |
| 421 | + longword(out, finfStart); | |
| 422 | + longword(out, 32); | |
| 423 | + } | |
| 424 | + break; | |
| 425 | + default: | |
| 426 | + return false; | |
| 427 | + } | |
| 428 | + return true; | |
| 429 | 429 | } |
| 430 | 430 | |
| 431 | 431 | bool ResourceFile::write() |
| 432 | 432 | { |
| 433 | − fs::path path(pathstring); | |
| 434 | − | |
| 435 | − if(isSingleFork(format)) | |
| 436 | − { | |
| 437 | − fs::ofstream out(path); | |
| 438 | − return write(out, format); | |
| 439 | − } | |
| 440 | − | |
| 441 | − switch(format) | |
| 442 | − { | |
| 443 | − case Format::basilisk: | |
| 444 | − { | |
| 445 | − fs::create_directory(path.parent_path() / ".rsrc"); | |
| 446 | − fs::create_directory(path.parent_path() / ".finf"); | |
| 447 | − | |
| 448 | − fs::ofstream dataOut(path); | |
| 449 | − fs::ofstream rsrcOut(path.parent_path() / ".rsrc" / path.filename()); | |
| 450 | − fs::ofstream finfOut(path.parent_path() / ".finf" / path.filename()); | |
| 451 | − | |
| 452 | − dataOut << data; | |
| 453 | − resources.writeFork(rsrcOut); | |
| 454 | − | |
| 455 | − ostype(finfOut, type); | |
| 456 | − ostype(finfOut, creator); | |
| 457 | − for(int i = 8; i < 32; i++) | |
| 458 | − byte(finfOut, 0); | |
| 459 | − } | |
| 460 | − break; | |
| 433 | + fs::path path(pathstring); | |
| 434 | + | |
| 435 | + if(isSingleFork(format)) | |
| 436 | + { | |
| 437 | + fs::ofstream out(path); | |
| 438 | + return write(out, format); | |
| 439 | + } | |
| 440 | + | |
| 441 | + switch(format) | |
| 442 | + { | |
| 443 | + case Format::basilisk: | |
| 444 | + { | |
| 445 | + fs::create_directory(path.parent_path() / ".rsrc"); | |
| 446 | + fs::create_directory(path.parent_path() / ".finf"); | |
| 447 | + | |
| 448 | + fs::ofstream dataOut(path); | |
| 449 | + fs::ofstream rsrcOut(path.parent_path() / ".rsrc" / path.filename()); | |
| 450 | + fs::ofstream finfOut(path.parent_path() / ".finf" / path.filename()); | |
| 451 | + | |
| 452 | + dataOut << data; | |
| 453 | + resources.writeFork(rsrcOut); | |
| 454 | + | |
| 455 | + ostype(finfOut, type); | |
| 456 | + ostype(finfOut, creator); | |
| 457 | + for(int i = 8; i < 32; i++) | |
| 458 | + byte(finfOut, 0); | |
| 459 | + } | |
| 460 | + break; | |
| 461 | 461 | #ifdef __APPLE__ |
| 462 | − case Format::real: | |
| 463 | − { | |
| 464 | − fs::ofstream dataOut(path); | |
| 465 | − fs::ofstream rsrcOut(path / "..namedfork" / "rsrc"); | |
| 466 | − std::ostringstream finfOut; | |
| 467 | − | |
| 468 | − dataOut << data; | |
| 469 | − resources.writeFork(rsrcOut); | |
| 470 | − | |
| 471 | − ostype(finfOut, type); | |
| 472 | − ostype(finfOut, creator); | |
| 473 | − for(int i = 8; i < 32; i++) | |
| 474 | − byte(finfOut, 0); | |
| 475 | − setxattr(path.c_str(), XATTR_FINDERINFO_NAME, | |
| 476 | − finfOut.str().data(), 32, 0, 0); | |
| 477 | − } | |
| 478 | − break; | |
| 462 | + case Format::real: | |
| 463 | + { | |
| 464 | + fs::ofstream dataOut(path); | |
| 465 | + fs::ofstream rsrcOut(path / "..namedfork" / "rsrc"); | |
| 466 | + std::ostringstream finfOut; | |
| 467 | + | |
| 468 | + dataOut << data; | |
| 469 | + resources.writeFork(rsrcOut); | |
| 470 | + | |
| 471 | + ostype(finfOut, type); | |
| 472 | + ostype(finfOut, creator); | |
| 473 | + for(int i = 8; i < 32; i++) | |
| 474 | + byte(finfOut, 0); | |
| 475 | + setxattr(path.c_str(), XATTR_FINDERINFO_NAME, | |
| 476 | + finfOut.str().data(), 32, 0, 0); | |
| 477 | + } | |
| 478 | + break; | |
| 479 | 479 | #endif |
| 480 | 480 | |
| 481 | − case Format::underscore_appledouble: | |
| 482 | − case Format::percent_appledouble: | |
| 483 | − { | |
| 484 | − fs::ofstream dataOut(path); | |
| 485 | − | |
| 486 | − dataOut << data; | |
| 487 | − | |
| 488 | − std::string prefix = format == Format::underscore_appledouble ? | |
| 489 | − "._" : "%"; | |
| 490 | − | |
| 491 | − fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 492 | − | |
| 493 | − fs::ofstream out(adPath); | |
| 494 | − | |
| 495 | − longword(out, 0x00051607); | |
| 496 | − longword(out, 0x00020000); | |
| 497 | − | |
| 498 | − for(int i = 0; i < 16; i++) | |
| 499 | − byte(out, 0); | |
| 500 | − word(out, 2); | |
| 501 | − std::streampos entries = out.tellp(); | |
| 502 | − for(int i = 0; i < 2*3; i++) | |
| 503 | − longword(out, 0); | |
| 504 | − std::streampos rsrcStart = out.tellp(); | |
| 505 | − resources.writeFork(out); | |
| 506 | − std::streampos finfStart = out.tellp(); | |
| 507 | − ostype(out, type); | |
| 508 | − ostype(out, creator); | |
| 509 | − for(int i = 8; i < 32; i++) | |
| 510 | − byte(out, 0); | |
| 511 | − out.seekp(entries); | |
| 512 | − longword(out, 2); | |
| 513 | − longword(out, rsrcStart); | |
| 514 | − longword(out, finfStart - rsrcStart); | |
| 515 | − longword(out, 9); | |
| 516 | − longword(out, finfStart); | |
| 517 | − longword(out, 32); | |
| 518 | − } | |
| 519 | − break; | |
| 520 | − | |
| 521 | − case Format::diskimage: | |
| 522 | − { | |
| 523 | − std::ostringstream rsrcOut; | |
| 524 | − resources.writeFork(rsrcOut); | |
| 525 | − std::string rsrc = rsrcOut.str(); | |
| 526 | − int size = rsrc.size(); | |
| 527 | − | |
| 528 | − size += 20 * 1024; | |
| 529 | − size += 800*1024 - size % (800*1024); | |
| 530 | − | |
| 531 | − fs::ofstream(path, std::ios::binary | std::ios::trunc).seekp(size-1).put(0); | |
| 532 | − | |
| 533 | − hfs_format(pathstring.c_str(), 0, 0, path.stem().string().substr(0,27).c_str(), 0, NULL); | |
| 534 | − hfsvol *vol = hfs_mount(pathstring.c_str(), 0, HFS_MODE_RDWR); | |
| 535 | − if(!vol) | |
| 536 | − return false; | |
| 537 | − //hfs_setvol(vol, ) | |
| 538 | − hfsfile *file = hfs_create(vol, (path.stem().string().substr(0,31)).c_str(), | |
| 539 | − ((std::string)type).c_str(), ((std::string)creator).c_str()); | |
| 540 | − hfs_setfork(file, 0); | |
| 541 | − hfs_write(file, data.data(), data.size()); | |
| 542 | − hfs_setfork(file, 1); | |
| 543 | − hfs_write(file, rsrc.data(), rsrc.size()); | |
| 544 | − | |
| 545 | − hfs_close(file); | |
| 546 | − hfs_umount(vol); | |
| 547 | − | |
| 548 | − } | |
| 549 | − break; | |
| 550 | − | |
| 551 | − default: | |
| 552 | − return false; | |
| 553 | − } | |
| 554 | − return true; | |
| 481 | + case Format::underscore_appledouble: | |
| 482 | + case Format::percent_appledouble: | |
| 483 | + { | |
| 484 | + fs::ofstream dataOut(path); | |
| 485 | + | |
| 486 | + dataOut << data; | |
| 487 | + | |
| 488 | + std::string prefix = format == Format::underscore_appledouble ? | |
| 489 | + "._" : "%"; | |
| 490 | + | |
| 491 | + fs::path adPath = path.parent_path() / (prefix + path.filename().string()); | |
| 492 | + | |
| 493 | + fs::ofstream out(adPath); | |
| 494 | + | |
| 495 | + longword(out, 0x00051607); | |
| 496 | + longword(out, 0x00020000); | |
| 497 | + | |
| 498 | + for(int i = 0; i < 16; i++) | |
| 499 | + byte(out, 0); | |
| 500 | + word(out, 2); | |
| 501 | + std::streampos entries = out.tellp(); | |
| 502 | + for(int i = 0; i < 2*3; i++) | |
| 503 | + longword(out, 0); | |
| 504 | + std::streampos rsrcStart = out.tellp(); | |
| 505 | + resources.writeFork(out); | |
| 506 | + std::streampos finfStart = out.tellp(); | |
| 507 | + ostype(out, type); | |
| 508 | + ostype(out, creator); | |
| 509 | + for(int i = 8; i < 32; i++) | |
| 510 | + byte(out, 0); | |
| 511 | + out.seekp(entries); | |
| 512 | + longword(out, 2); | |
| 513 | + longword(out, rsrcStart); | |
| 514 | + longword(out, finfStart - rsrcStart); | |
| 515 | + longword(out, 9); | |
| 516 | + longword(out, finfStart); | |
| 517 | + longword(out, 32); | |
| 518 | + } | |
| 519 | + break; | |
| 520 | + | |
| 521 | + case Format::diskimage: | |
| 522 | + { | |
| 523 | + std::ostringstream rsrcOut; | |
| 524 | + resources.writeFork(rsrcOut); | |
| 525 | + std::string rsrc = rsrcOut.str(); | |
| 526 | + int size = rsrc.size(); | |
| 527 | + | |
| 528 | + size += 20 * 1024; | |
| 529 | + size += 800*1024 - size % (800*1024); | |
| 530 | + | |
| 531 | + fs::ofstream(path, std::ios::binary | std::ios::trunc).seekp(size-1).put(0); | |
| 532 | + | |
| 533 | + hfs_format(pathstring.c_str(), 0, 0, path.stem().string().substr(0,27).c_str(), 0, NULL); | |
| 534 | + hfsvol *vol = hfs_mount(pathstring.c_str(), 0, HFS_MODE_RDWR); | |
| 535 | + if(!vol) | |
| 536 | + return false; | |
| 537 | + //hfs_setvol(vol, ) | |
| 538 | + hfsfile *file = hfs_create(vol, (path.stem().string().substr(0,31)).c_str(), | |
| 539 | + ((std::string)type).c_str(), ((std::string)creator).c_str()); | |
| 540 | + hfs_setfork(file, 0); | |
| 541 | + hfs_write(file, data.data(), data.size()); | |
| 542 | + hfs_setfork(file, 1); | |
| 543 | + hfs_write(file, rsrc.data(), rsrc.size()); | |
| 544 | + | |
| 545 | + hfs_close(file); | |
| 546 | + hfs_umount(vol); | |
| 547 | + | |
| 548 | + } | |
| 549 | + break; | |
| 550 | + | |
| 551 | + default: | |
| 552 | + return false; | |
| 553 | + } | |
| 554 | + return true; | |
| 555 | 555 | } |
| 556 | 556 | |
| 557 | 557 | bool ResourceFile::hasPlainDataFork(ResourceFile::Format f) |
| 558 | 558 | { |
| 559 | − switch(f) | |
| 560 | − { | |
| 559 | + switch(f) | |
| 560 | + { | |
| 561 | 561 | #ifdef __APPLE__ |
| 562 | − case Format::real: | |
| 562 | + case Format::real: | |
| 563 | 563 | #endif |
| 564 | − case Format::basilisk: | |
| 565 | − case Format::underscore_appledouble: | |
| 566 | − case Format::percent_appledouble: | |
| 567 | − return true; | |
| 568 | − default: | |
| 569 | − return false; | |
| 570 | − } | |
| 564 | + case Format::basilisk: | |
| 565 | + case Format::underscore_appledouble: | |
| 566 | + case Format::percent_appledouble: | |
| 567 | + return true; | |
| 568 | + default: | |
| 569 | + return false; | |
| 570 | + } | |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | 573 | bool ResourceFile::hasPlainDataFork() |
| 574 | 574 | { |
| 575 | − return hasPlainDataFork(format); | |
| 575 | + return hasPlainDataFork(format); | |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | 578 | bool ResourceFile::isSingleFork(Format f) |
| 579 | 579 | { |
| 580 | − switch(f) | |
| 581 | − { | |
| 582 | − case Format::macbin: | |
| 583 | − case Format::applesingle: | |
| 584 | − return true; | |
| 585 | − default: | |
| 586 | − return false; | |
| 587 | − } | |
| 580 | + switch(f) | |
| 581 | + { | |
| 582 | + case Format::macbin: | |
| 583 | + case Format::applesingle: | |
| 584 | + return true; | |
| 585 | + default: | |
| 586 | + return false; | |
| 587 | + } | |
| 588 | 588 | } |