Exemple #1
0
 public BSAStateObject(BSAReader bsaReader)
 {
     Magic        = bsaReader._magic;
     Version      = (uint)bsaReader.HeaderType;
     ArchiveFlags = (uint)bsaReader.ArchiveFlags;
     FileFlags    = (uint)bsaReader.FileFlags;
 }
Exemple #2
0
 public FileNameBlock(BSAReader bsa, long position)
 {
     Names = new Lazy <ReadOnlyMemorySlice <byte>[]>(
         mode: System.Threading.LazyThreadSafetyMode.ExecutionAndPublication,
         valueFactory: () =>
     {
         using var stream                   = bsa.GetStream();
         stream.BaseStream.Position         = position;
         ReadOnlyMemorySlice <byte> data    = stream.ReadBytes(checked ((int)bsa._totalFileNameLength));
         ReadOnlyMemorySlice <byte>[] names = new ReadOnlyMemorySlice <byte> [bsa._fileCount];
         for (int i = 0; i < bsa._fileCount; i++)
         {
             var index = data.Span.IndexOf(default(byte));
             if (index == -1)
             {
                 throw new InvalidDataException("Did not end all of its strings in null bytes");
             }
             names[i] = data.Slice(0, index + 1);
             var str  = names[i].ReadStringTerm(bsa.HeaderType);
             data     = data.Slice(index + 1);
         }
         // Data doesn't seem to need to be fully consumed.
         // Official BSAs have overflow of zeros
         return(names);
     });
 }
Exemple #3
0
 public BSAStateObject(BSAReader bsaReader)
 {
     Magic        = bsaReader._magic;
     Version      = bsaReader._version;
     ArchiveFlags = bsaReader._archiveFlags;
     FileFlags    = bsaReader._fileFlags;
 }
Exemple #4
0
        public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src, int index)
        {
            _index = index;
            _bsa   = bsa;
            Hash   = src.ReadUInt64();
            var size = src.ReadUInt32();

            FlipCompression = (size & (0x1 << 30)) > 0;

            if (FlipCompression)
            {
                _size = size ^ (0x1 << 30);
            }
            else
            {
                _size = size;
            }

            if (Compressed)
            {
                _size -= 4;
            }

            _offset = src.ReadUInt32();
            Folder  = folderRecord;

            var old_pos = src.BaseStream.Position;

            src.BaseStream.Position = _offset;

            if (bsa.HasNameBlobs)
            {
                _nameBlob = src.ReadStringLenNoTerm(bsa.HeaderType);
            }


            if (Compressed)
            {
                _originalSize = src.ReadUInt32();
            }

            _onDiskSize = (uint)(_size - (_nameBlob == null ? 0 : _nameBlob.Length + 1));

            if (Compressed)
            {
                _dataSize    = _originalSize;
                _onDiskSize -= 4;
            }
            else
            {
                _dataSize = _onDiskSize;
            }

            _dataOffset = src.BaseStream.Position;

            src.BaseStream.Position = old_pos;
        }
Exemple #5
0
 public static async ValueTask <IBSAReader> OpenRead(AbsolutePath filename)
 {
     return(await BSASignatures.MatchesAsync(filename) switch
     {
         Definitions.FileType.TES3 => await TES3Reader.Load(new NativeFileStreamFactory(filename)),
         Definitions.FileType.BSA => await BSAReader.LoadAsync(new NativeFileStreamFactory(filename)),
         Definitions.FileType.BA2 => await BA2Reader.Load(new NativeFileStreamFactory(filename)),
         _ => throw new InvalidDataException("Filename is not a .bsa or .ba2")
     });
Exemple #6
0
        public static BSAReader Load(AbsolutePath filename)
        {
            var bsa = new BSAReader {
                _streamFactory = new NativeFileStreamFactory(filename)
            };

            using var rdr = bsa.GetStream();
            bsa.LoadHeaders(rdr);
            return(bsa);
        }
Exemple #7
0
        public static async ValueTask <BSAReader> LoadAsync(IStreamFactory factory)
        {
            await using var stream = await factory.GetStream().ConfigureAwait(false);

            using var br = new BinaryReader(stream);
            var bsa = new BSAReader {
                _streamFactory = factory
            };

            bsa.LoadHeaders(br);
            return(bsa);
        }
Exemple #8
0
        internal void LoadFileRecordBlock(BSAReader bsa, BinaryReader src)
        {
            if (bsa.HasFolderNames)
            {
                Name = src.ReadStringLen(bsa.HeaderType);
            }

            _files = new List <FileRecord>();
            for (var idx = 0; idx < _fileCount; idx += 1)
            {
                _files.Add(new FileRecord(bsa, this, src, idx));
            }
        }
Exemple #9
0
 internal FolderRecord(BSAReader bsa, BinaryReader src)
 {
     Hash       = src.ReadUInt64();
     _fileCount = src.ReadUInt32();
     if (bsa.HeaderType == VersionType.SSE)
     {
         _unk    = src.ReadUInt32();
         _offset = src.ReadUInt64();
     }
     else
     {
         _offset = src.ReadUInt32();
     }
 }
Exemple #10
0
        public static async ValueTask <BSAReader> Load(AbsolutePath filename)
        {
            using var stream = await filename.OpenRead();

            using var br = new BinaryReader(stream);
            var bsa = new BSAReader {
                _rdr = br, _stream = stream, _fileName = filename
            };
            await bsa.LoadHeaders();

            bsa._rdr    = null;
            bsa._stream = null;
            return(bsa);
        }
Exemple #11
0
        public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src)
        {
            _bsa  = bsa;
            _hash = src.ReadUInt64();
            var size = src.ReadInt32();

            _compressedFlag = (size & (0x1 << 30)) > 0;

            if (_compressedFlag)
            {
                _size = size ^ (0x1 << 30);
            }
            else
            {
                _size = size;
            }

            _offset = src.ReadInt32();

            _folder = folderRecord;
        }
Exemple #12
0
        public static async ValueTask <IBSAReader> OpenRead(AbsolutePath filename)
        {
            var fourcc = "";

            using (var file = await filename.OpenRead())
            {
                fourcc = Encoding.ASCII.GetString(new BinaryReader(file).ReadBytes(4));
            }

            if (fourcc == TES3Reader.TES3_MAGIC)
            {
                return(await TES3Reader.Load(filename));
            }
            if (fourcc == "BSA\0")
            {
                return(await BSAReader.Load(filename));
            }
            if (fourcc == "BTDX")
            {
                return(await BA2Reader.Load(filename));
            }
            throw new InvalidDataException("Filename is not a .bsa or .ba2, magic " + fourcc);
        }
Exemple #13
0
 internal void LoadFileRecord(BSAReader bsaReader, FolderRecord folder, FileRecord file, BinaryReader rdr)
 {
     _name = rdr.ReadStringTerm(_bsa.HeaderType);
 }
Exemple #14
0
 internal FolderRecord(BSAReader bsa, ReadOnlyMemorySlice <byte> data, int index)
 {
     BSA   = bsa;
     _data = data;
     Index = index;
 }