private IEnumerable <IArchiveFileInfo> ReadDirectories(BinaryReaderX br, IsoDirEntry directory, string currentPath = "") { var directoryOffset = directory.body.lbaExtent.Value * SectorSize_; var internalOffset = 0x60; // Skip self entry and parent entry directly while (br.PeekByte(directoryOffset + internalOffset) != 0) { br.BaseStream.Position = directoryOffset + internalOffset; var entry = br.ReadType <IsoDirEntry>(); br.BaseStream.Position += 0xE; internalOffset = (int)(br.BaseStream.Position - directoryOffset); // Continue reading if the entry points to the current one if (entry.body.lbaExtent.Value == directory.body.lbaExtent.Value) { continue; } // Read all sub directories and files of this directory if (entry.IsDirectory) { foreach (var afi in ReadDirectories(br, entry, Path.Combine(currentPath, entry.body.fileName))) { yield return(afi); } continue; } // Otherwise return file var subStream = new SubStream(br.BaseStream, entry.body.lbaExtent.Value * SectorSize_, entry.body.sizeExtent.Value); yield return(new Ps2DiscArchiveFileInfo(subStream, Path.Combine(currentPath, entry.body.fileName), entry)); } }
private string GetString(byte[] input) { using (var br = new BinaryReaderX(new MemoryStream(input))) { string res = ""; switch (usedEncoding) { case Enc.SJIS: while (br.BaseStream.Position < br.BaseStream.Length) { var peek = br.PeekByte(); if (peek == 0x1a) { br.BaseStream.Position++; var size = br.ReadByte(); res += "{"; res += br.ReadByte() + ","; for (int i = 0; i < size - 3; i++) { res += br.ReadByte() + ((i + 1 == size - 3) ? "" : ","); } res += "}"; } else { if (peek == 0x00) { br.ReadByte(); break; } else if (peek < 0x80) { res += Encoding.GetEncoding("SJIS").GetString(new[] { br.ReadByte() }); } else { res += Encoding.GetEncoding("SJIS").GetString(br.ReadBytes(2)); } } } break; case Enc.UTF16: while (br.BaseStream.Position < br.BaseStream.Length) { var peek = br.ReadInt16(); br.BaseStream.Position -= 2; if (peek == 0x1a) { br.BaseStream.Position += 2; var size = br.ReadByte(); res += "{"; res += br.ReadByte() + ","; for (int i = 0; i < size - 4; i += 2) { res += br.ReadUInt16() + ((i + 2 == size - 4) ? "" : ","); } res += "}"; } else if (peek == 0x00) { br.ReadByte(); break; } else { res += Encoding.GetEncoding("UTF-16").GetString(br.ReadBytes(2)); } } break; default: return(string.Empty); } return(res); } }
// TODO: Not all games use a standard encoding scheme. Example: Doubutsu no Mori e+. // TODO: It also uses custom binary data characters (0x7F for ControlCodes & 0x80 for MessageTags.) // TODO: Should this be supported somehow? I'm pretty certain those formats are unique to those game(s). // In the meantime I'll be disabling command parsing all together until a solution is determined. // It's also worth mentioning that not all BMG files have a 0x00 string-end character. // How should that be handled? private string GetString(byte[] input) { using (var br = new BinaryReaderX(new MemoryStream(input))) { string res = ""; switch (header.encoding) { case BmgEncoding.ASCII: while (br.BaseStream.Position < br.BaseStream.Length) { /*var peek = br.PeekByte(); * if (peek == 0x1a) * { * br.BaseStream.Position++; * var size = br.ReadByte(); * res += "{"; * res += br.ReadByte() + ","; * for (int i = 0; i < size - 3; i++) * res += br.ReadByte() + ((i + 1 == size - 3) ? "" : ","); * res += "}"; * } * else * { * if (peek == 0x00) * { * br.ReadByte(); * break; * } * * res += encoding.GetString(new[] { br.ReadByte() }); * }*/ res += encoding.GetString(new[] { br.ReadByte() }); } break; case BmgEncoding.ShiftJIS: while (br.BaseStream.Position < br.BaseStream.Length) { var peek = br.PeekByte(); /*if (peek == 0x1a) * { * br.BaseStream.Position++; * var size = br.ReadByte(); * res += "{"; * res += br.ReadByte() + ","; * for (int i = 0; i < size - 3; i++) * res += br.ReadByte() + ((i + 1 == size - 3) ? "" : ","); * res += "}"; * } * else * { * if (peek == 0x00) * { * br.ReadByte(); * break; * } * * if (peek < 0x80) * res += encoding.GetString(new[] { br.ReadByte() }); * else * res += encoding.GetString(br.ReadBytes(2)); * }*/ if (peek < 0x80) { res += encoding.GetString(new[] { br.ReadByte() }); } else { res += encoding.GetString(br.ReadBytes(2)); } } break; case BmgEncoding.UTF16: while (br.BaseStream.Position < br.BaseStream.Length) { /*var peek = br.ReadInt16(); * br.BaseStream.Position -= 2; * if (peek == 0x1a) * { * br.BaseStream.Position += 2; * var size = br.ReadByte(); * res += "{"; * res += br.ReadByte() + ","; * for (int i = 0; i < size - 4; i += 2) * res += br.ReadUInt16() + ((i + 2 == size - 4) ? "" : ","); * res += "}"; * } * else * if (peek == 0x00) * { * br.ReadByte(); * break; * } * else * res += encoding.GetString(br.ReadBytes(2));*/ res += encoding.GetString(br.ReadBytes(2)); } break; default: return(string.Empty); } return(res.Replace("\0", "")); } }