/// <summary> /// Resolve archive type from Ba2ArchiveBase derived class instance. /// </summary> /// <param name="archive">The archive.</param> /// <returns> /// Archive type. /// </returns> /// <see cref="BA2Type" /> public static BA2Type GetArchiveType(BA2Archive archive) { var archiveType = archive.GetType(); if (archiveType == typeof(BA2GeneralArchive)) { return(BA2Type.General); } else if (archiveType == typeof(BA2TextureArchive)) { return(BA2Type.Texture); } return(BA2Type.Unknown); }
/// <summary> /// Load archive of specified type from stream. /// </summary> /// <param name="stream">Stream to read from.</param> /// <param name="flags">Flags for loader.</param> /// <returns>BA2Archive instance.</returns> /// <exception cref="ArgumentNullException">Thrown when <c>stream</c> is null.</exception> /// <exception cref="BA2LoadException" /> public static T Load <T>(Stream stream, BA2LoaderFlags flags = BA2LoaderFlags.None) where T : BA2Archive { BA2Archive archive = Load(stream, flags); Type exceptedType = typeof(T); var exceptedArchive = archive as T; if (exceptedArchive != null) { return(exceptedArchive); } else { if (archive != null) { archive.Dispose(); } throw new BA2LoadException( string.Format("Loaded archive has type {0}, which is not same as requested type {1}", GetArchiveType(archive), GetArchiveType <T>())); } }
/// <summary> /// Load archive from stream. /// </summary> /// <param name="stream">Stream to read from.</param> /// <param name="flags"></param> /// <returns>BA2Archive instance.</returns> /// <exception cref="ArgumentNullException">Thrown when <c>stream</c> is null.</exception> /// <exception cref="BA2LoadException" /> public static BA2Archive Load(Stream stream, BA2LoaderFlags flags = BA2LoaderFlags.None) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } BA2Archive archive = null; try { // file cannot be valid archive if header is less than HeaderSize if (stream.Length - stream.Position < HeaderSize) { throw new BA2LoadException("Given stream cannot be valid archive."); } using (BinaryReader reader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true)) { BA2Header header = LoadHeader(reader); if (!HeaderSignature.SequenceEqual(header.Signature)) { throw new BA2LoadException("Archive has invalid signature"); } if (header.Version != ArchiveVersion && !flags.HasFlag(BA2LoaderFlags.IgnoreVersion)) { throw new BA2LoadException($"Version of archive is not valid (\"{header.Version.ToString()}\")"); } // compare excepted signature and file signature switch (GetArchiveType(header.ArchiveType)) { case BA2Type.General: archive = new BA2GeneralArchive(); break; case BA2Type.Texture: // TODO archive = new BA2TextureArchive(); break; case BA2Type.Unknown: default: if (flags.HasFlag(BA2LoaderFlags.IgnoreArchiveType)) { archive = new BA2Archive(); } else { throw new BA2LoadException($"Archive of type \"{Encoding.ASCII.GetString(header.ArchiveType)}\" is not supported"); } break; } if (flags.HasFlag(BA2LoaderFlags.Multithreaded)) { archive.IsMultithreaded = true; } archive.Header = header; archive.m_archiveStream = stream; archive.PreloadData(reader); } } catch (Exception) { if (archive != null) { archive.Dispose(); } throw; } return(archive); }