/// <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, }); }
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; } }
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()); } }