Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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>()));
            }
        }
Ejemplo n.º 3
0
        /// <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);
        }