public MacBinary(Stream input) { byte[] buf = new byte[128]; if (input.Read(buf, 0, 128) != 128) throw new MacBinaryException("Could not read header."); version = Version.MacBinaryIII; // Version if (buf[0] != 0) throw new MacBinaryException("Incompatible version."); // Signature 'mBIN' if (buf[102] != 'm' || buf[103] != 'B' || buf[104] != 'I' || buf[105] != 'N') version = Version.MacBinaryII; // Zero padding if (buf[74] != 0 || buf[82] != 0 || buf[126] != 0 || buf[127] != 0) throw new MacBinaryException("Zero padding is not zero."); // MacBinary version of this file. if (version == Version.MacBinaryII && buf[122] != 129) throw new MacBinaryException("Version field corrupt for a MacBinary II file."); if (version == Version.MacBinaryIII && buf[122] != 130) { if (buf[122] == 129) version = Version.MacBinaryII; else throw new MacBinaryException("Version field corrupt for a MacBinary III file."); } // CRC at the end of the header int crc = MacUtil.read16(buf, 124); // FIXME: check CRC if (crc == 0) version = Version.MacBinaryI; // File name int namelen = buf[1]; if (namelen < 1 || namelen > 63) throw new MacBinaryException("Invalid file length."); filename = MacUtil.readString(buf, 2, namelen); // File type filetype = MacUtil.readString(buf, 65, 4); // File creator filecreator = MacUtil.readString(buf, 69, 4); // Finder flags finderflags = buf[73]; // Window position windowposy = MacUtil.read16(buf, 75); windowposx = MacUtil.read16(buf, 77); // Window or folder ID windowid = MacUtil.read16(buf, 79); // Protected flag protectedflag = (buf[81] & 1) == 1; // Data en resource fork lengths int datlen = MacUtil.read32(buf, 83); int reslen = MacUtil.read32(buf, 87); // Creation and modification dates ctime = MacUtil.read32(buf, 91); mtime = MacUtil.read32(buf, 95); int commentlen = 0; int secheaderlen = 0; if (version != Version.MacBinaryI) { // Get Info comment length commentlen = MacUtil.read16(buf, 99); // Finder flags finderflags2 = buf[101]; if (version != Version.MacBinaryII) { // Finder fxInfo fields fxScript = buf[106]; fdXFlags = buf[107]; } // Length of total files when packed files are unpacked. (never really used) //int unpackedlen = read32(buf, 117); // Length of secondary header. secheaderlen = MacUtil.read16(buf, 120); // Minimum version to support in order to read this file (ignored) //int minversion = buf[123]; } // Skip the secondary header if (secheaderlen > 0) { // Round up to 128 bytes secheaderlen = (int)Math.Ceiling((double)secheaderlen / 128) * 128; input.Seek(secheaderlen, SeekOrigin.Current); } // Read data fork dat = new byte[datlen]; if (input.Read(dat, 0, datlen) != datlen) throw new MacBinaryException("Could not read data fork."); // Round up to 128 bytes and skip padding long temp = (int)Math.Ceiling((double)datlen / 128) * 128 - datlen; input.Seek(temp, SeekOrigin.Current); // Read the resource fork temp = input.Position + (int)Math.Ceiling((double)reslen / 128) * 128; res = new MacResourceFork(input); input.Seek(temp, SeekOrigin.Begin); if (commentlen > 0) { buf = new byte[commentlen]; if (input.Read(buf, 0, commentlen) != commentlen) throw new MacBinaryException("Could not read Get Info comment."); comment = MacUtil.readString(buf, 0, commentlen); } }
public MacBinary(Stream input) { byte[] buf = new byte[128]; if (input.Read(buf, 0, 128) != 128) { throw new MacBinaryException("Could not read header."); } version = Version.MacBinaryIII; // Version if (buf[0] != 0) { throw new MacBinaryException("Incompatible version."); } // Signature 'mBIN' if (buf[102] != 'm' || buf[103] != 'B' || buf[104] != 'I' || buf[105] != 'N') { version = Version.MacBinaryII; } // Zero padding if (buf[74] != 0 || buf[82] != 0 || buf[126] != 0 || buf[127] != 0) { throw new MacBinaryException("Zero padding is not zero."); } // MacBinary version of this file. if (version == Version.MacBinaryII && buf[122] != 129) { throw new MacBinaryException("Version field corrupt for a MacBinary II file."); } if (version == Version.MacBinaryIII && buf[122] != 130) { if (buf[122] == 129) { version = Version.MacBinaryII; } else { throw new MacBinaryException("Version field corrupt for a MacBinary III file."); } } // CRC at the end of the header int crc = MacUtil.read16(buf, 124); // FIXME: check CRC if (crc == 0) { version = Version.MacBinaryI; } // File name int namelen = buf[1]; if (namelen < 1 || namelen > 63) { throw new MacBinaryException("Invalid file length."); } filename = MacUtil.readString(buf, 2, namelen); // File type filetype = MacUtil.readString(buf, 65, 4); // File creator filecreator = MacUtil.readString(buf, 69, 4); // Finder flags finderflags = buf[73]; // Window position windowposy = MacUtil.read16(buf, 75); windowposx = MacUtil.read16(buf, 77); // Window or folder ID windowid = MacUtil.read16(buf, 79); // Protected flag protectedflag = (buf[81] & 1) == 1; // Data en resource fork lengths int datlen = MacUtil.read32(buf, 83); int reslen = MacUtil.read32(buf, 87); // Creation and modification dates ctime = MacUtil.read32(buf, 91); mtime = MacUtil.read32(buf, 95); int commentlen = 0; int secheaderlen = 0; if (version != Version.MacBinaryI) { // Get Info comment length commentlen = MacUtil.read16(buf, 99); // Finder flags finderflags2 = buf[101]; if (version != Version.MacBinaryII) { // Finder fxInfo fields fxScript = buf[106]; fdXFlags = buf[107]; } // Length of total files when packed files are unpacked. (never really used) //int unpackedlen = read32(buf, 117); // Length of secondary header. secheaderlen = MacUtil.read16(buf, 120); // Minimum version to support in order to read this file (ignored) //int minversion = buf[123]; } // Skip the secondary header if (secheaderlen > 0) { // Round up to 128 bytes secheaderlen = (int)Math.Ceiling((double)secheaderlen / 128) * 128; input.Seek(secheaderlen, SeekOrigin.Current); } // Read data fork dat = new byte[datlen]; if (input.Read(dat, 0, datlen) != datlen) { throw new MacBinaryException("Could not read data fork."); } // Round up to 128 bytes and skip padding long temp = (int)Math.Ceiling((double)datlen / 128) * 128 - datlen; input.Seek(temp, SeekOrigin.Current); // Read the resource fork temp = input.Position + (int)Math.Ceiling((double)reslen / 128) * 128; res = new MacResourceFork(input); input.Seek(temp, SeekOrigin.Begin); if (commentlen > 0) { buf = new byte[commentlen]; if (input.Read(buf, 0, commentlen) != commentlen) { throw new MacBinaryException("Could not read Get Info comment."); } comment = MacUtil.readString(buf, 0, commentlen); } }