Esempio n. 1
0
        /// <summary>
        /// Read meta information <see cref="Entity"/>
        /// </summary>
        /// <param name="stream">Stream.</param>
        /// <param name="decryptor">Decryptor.</param>
        /// <param name="decryptIndexBlock">Index Decrypt Block.</param>
        /// <param name="endian">File endian.</param>
        /// <param name="version">File version.</param>
        /// <returns></returns>
        public static Entity Read(Stream stream, IDecryptor decryptor, ref ulong decryptIndexBlock, Endian endian)
        {
            var cryptBlockCount = 0ul;
            var nextDecrIndex   = 0ul;

            var type = decryptor.ReadInt32(stream, decryptIndexBlock + cryptBlockCount, ref nextDecrIndex, endian);

            var blockSize = (ulong)Marshal.SizeOf(type);

            cryptBlockCount += (blockSize + Decryptor.CryptBlockSize - 1) / Decryptor.CryptBlockSize;

            var size = decryptor.ReadInt32(stream, decryptIndexBlock + cryptBlockCount, ref nextDecrIndex, endian);

            blockSize        = (ulong)Marshal.SizeOf(size);
            cryptBlockCount += (blockSize + Decryptor.CryptBlockSize - 1) / Decryptor.CryptBlockSize;
            var startDecryptIndexBlock = decryptIndexBlock + cryptBlockCount;

            var offset = stream.Position;

            cryptBlockCount += (ulong)((size + Decryptor.CryptBlockSize - 1) / Decryptor.CryptBlockSize);
            stream.Seek(size, SeekOrigin.Current);

            decryptIndexBlock += cryptBlockCount;
            return(new Entity
            {
                Type = type,
                Size = size,
                OffsetRawBlock = offset,
                DecryptIndexBlock = startDecryptIndexBlock,
            });
        }
Esempio n. 2
0
        public ICollection <Entity> GetEntities()
        {
            try
            {
                using (var stream = File.OpenRead(FilePath)) // TODO: Don't open the file stream twice for the parsing process
                {
                    FileHeader.Read(stream);

                    var cryptBlockIndex = 0ul;

                    var countEntities = _decryptor.ReadInt32(stream, cryptBlockIndex, ref cryptBlockIndex, Endian);
                    if (countEntities < 0 || countEntities > 1e6) // I don't think any i3d file would contain more than a million shapes..
                    {
                        throw new DecryptFailureException();
                    }

                    return(Enumerable.Range(0, countEntities)
                           .Select(v => Entity.Read(stream, _decryptor, ref cryptBlockIndex, Endian))
                           .ToArray());
                }
            }
            catch (Exception e)
            {
                if (e is ArgumentOutOfRangeException || e is IOException || e is OutOfMemoryException)
                {
                    throw new DecryptFailureException();
                }
                throw;
            }
        }
Esempio n. 3
0
        private static ICollection <Entity> ReadEntities(IDecryptor decryptor, string fileName)
        {
            using (var stream = File.OpenRead(fileName))
            {
                var header = ReadHeader(stream);
                var endian = GetEndian(header.Version);

                var cryptBlockIndex = 0ul;

                var countEntities = decryptor.ReadInt32(stream, cryptBlockIndex, ref cryptBlockIndex, endian);

                return(Enumerable.Range(0, countEntities)
                       .Select(v => Entity.Read(stream, decryptor, ref cryptBlockIndex, endian))
                       .ToArray());
            }
        }