/// <summary> /// Constructor /// </summary> /// <param name="stream">IMG stream</param> /// <param name="mode">IMG archive mode</param> /// <param name="entryNameEncoding">Entry name encoding</param> internal IMGArchive(Stream stream, EIMGArchiveAccessMode mode, Encoding entryNameEncoding, Dictionary <string, IIMGArchiveEntry> entries) { Stream = stream; AccessMode = mode; EntryNameEncoding = entryNameEncoding; InternalEntries = entries; }
/// <summary> /// Open IMG archive /// </summary> /// <param name="imgArchiveFilePath">IMG archive file path</param> /// <param name="accessMode">IMG archive access mode</param> /// <param name="entryNameEncoding">IMG archive entry name encoding</param> /// <returns>IMG archive</returns> /// <exception cref="InvalidOperationException">Return value is null</exception> /// <exception cref="ArgumentNullException">Archive file name is null</exception> /// <exception cref="FileNotFoundException">Archive file not found</exception> /// <exception cref="InvalidDataException">Archive error</exception> public static IIMGArchive Open(string imgArchiveFilePath, EIMGArchiveAccessMode accessMode, Encoding entryNameEncoding) { if (imgArchiveFilePath == null) { throw new ArgumentNullException(nameof(imgArchiveFilePath)); } if (entryNameEncoding == null) { throw new ArgumentNullException(nameof(entryNameEncoding)); } IMGArchive ret = null; try { if ((accessMode != EIMGArchiveAccessMode.Create) && (!File.Exists(imgArchiveFilePath))) { throw new FileNotFoundException("Archive not found", imgArchiveFilePath); } FileStream archive_file_stream = File.Open(imgArchiveFilePath, (accessMode == EIMGArchiveAccessMode.Create) ? FileMode.Create : FileMode.Open, (accessMode != EIMGArchiveAccessMode.Read) ? FileAccess.ReadWrite : FileAccess.Read); if (archive_file_stream == null) { throw new FileNotFoundException("Archive not found", imgArchiveFilePath); } Dictionary <string, IIMGArchiveEntry> img_archive_entries = new Dictionary <string, IIMGArchiveEntry>(); ret = new IMGArchive(archive_file_stream, accessMode, entryNameEncoding, img_archive_entries); if (accessMode == EIMGArchiveAccessMode.Create) { byte[] new_data = new byte[2048]; new_data[0] = 0x56; new_data[1] = 0x45; new_data[2] = 0x52; new_data[3] = 0x32; archive_file_stream.Write(new_data, 0, new_data.Length); } else { using (BinaryReader archive_file_stream_binary_reader = new BinaryReader(archive_file_stream, entryNameEncoding, true)) { int archive_version = archive_file_stream_binary_reader.ReadInt32(); if (archive_version != SupportedIMGArchiveVersion) { throw new InvalidDataException($"Invalid IMG archive version { archive_version }."); } uint num_entries = archive_file_stream_binary_reader.ReadUInt32(); if (archive_file_stream.Length < (num_entries * 8)) { throw new InvalidDataException($"IMG archive file size is smaller than expected."); } for (uint num_entry = 0U; num_entry != num_entries; num_entry++) { long offset = archive_file_stream_binary_reader.ReadInt32() * 2048L; int length = archive_file_stream_binary_reader.ReadInt16() * 2048; short dummy = archive_file_stream_binary_reader.ReadInt16(); byte[] full_name_bytes_raw = new byte[24]; if (archive_file_stream_binary_reader.Read(full_name_bytes_raw, 0, full_name_bytes_raw.Length) != full_name_bytes_raw.Length) { throw new InvalidDataException("IMG entry name is missing."); } int full_name_bytes_count = IMGUtilities.GetNullTerminatedByteStringLength(full_name_bytes_raw); if (full_name_bytes_count <= 0) { throw new InvalidDataException("IMG entry name can't be empty."); } string full_name = entryNameEncoding.GetString(full_name_bytes_raw, 0, full_name_bytes_count); img_archive_entries.Add(full_name.ToLower(), new IMGArchiveEntry(ret, offset, length, full_name)); } } } if (ret == null) { throw new InvalidOperationException("Return value is null"); } } catch (Exception e) { ret?.Dispose(); throw e; } return(ret); }
/// <summary> /// Open IMG archive /// </summary> /// <param name="imgArchiveFilePath">IMG archive file path</param> /// <param name="accessMode">IMG archive access mode</param> /// <returns>IMG archive</returns> /// <exception cref="InvalidOperationException">Return value is null</exception> /// <exception cref="ArgumentNullException">Archive file name is null</exception> /// <exception cref="FileNotFoundException">Archive file not found</exception> /// <exception cref="InvalidDataException">Archive error</exception> public static IIMGArchive Open(string imgArchiveFilePath, EIMGArchiveAccessMode accessMode) => Open(imgArchiveFilePath, accessMode, Encoding.UTF8);