Пример #1
0
        public FileInformation AddProperties(Stream stream, FileProperties requiredProperties)
        {
            requiredProperties -= requiredProperties & GetProperties();

            if (Size == null
                && (requiredProperties.HasFlag(FileProperties.Size)
                || requiredProperties.HasFlag(FileProperties.BlockSize)
                || (requiredProperties & FileProperties.AllBlockHashes) != FileProperties.None
                || (requiredProperties & FileProperties.AllHashes) != FileProperties.None))
            {
                Size = stream.Length;
            }

            if (BlockSize == null
                && (requiredProperties & (FileProperties.BlockSize | FileProperties.AllHashes | FileProperties.AllBlockHashes)) != FileProperties.None)
            {
                BlockSize = GetBlockSize(Size.Value);
            }

            int readLength = 0;
            byte[] buffer = new byte[BlockSize == null ? SliceLength : BlockSize.Value];

            if (stream != null && stream.CanSeek)
            {
                // Assume at head if stream is not seekable.
                stream.Seek(0, SeekOrigin.Begin);
            }

            if (requiredProperties.HasFlag(FileProperties.SliceMD5))
            {
                readLength = stream.Read(buffer, 0, SliceLength);
                SliceMD5 = (readLength == SliceLength)
                    ? new MD5CryptoServiceProvider().ComputeHash(buffer, 0, SliceLength).ToHexString()
                    : null;
            }

            if ((requiredProperties & FileProperties.AllHashes) != FileProperties.None)
            {
                List<HashAlgorithm> hashers = new List<HashAlgorithm>
                {
                    requiredProperties.HasFlag(FileProperties.MD5) ? new MD5CryptoServiceProvider() : null,
                    requiredProperties.HasFlag(FileProperties.SHA1) ? new SHA1CryptoServiceProvider() : null,
                    requiredProperties.HasFlag(FileProperties.SHA256) ? new SHA256CryptoServiceProvider() : null
                };

                BlockMD5 = requiredProperties.HasFlag(FileProperties.BlockMD5) ? new List<string>() : BlockMD5;
                BlockSHA1 = requiredProperties.HasFlag(FileProperties.BlockSHA1) ? new List<string>() : BlockSHA1;
                BlockSHA256 = requiredProperties.HasFlag(FileProperties.BlockSHA256) ? new List<string>() : BlockSHA256;

                List<HashAlgorithm> blockHashers = new List<HashAlgorithm>
                {
                    requiredProperties.HasFlag(FileProperties.BlockMD5) ? new MD5CryptoServiceProvider() : null,
                    requiredProperties.HasFlag(FileProperties.BlockSHA1) ? new SHA1CryptoServiceProvider() : null,
                    requiredProperties.HasFlag(FileProperties.BlockSHA256) ? new SHA256CryptoServiceProvider() : null
                };

                List<IHash> additionalHashers = new List<IHash>
                {
                    requiredProperties.HasFlag(FileProperties.CRC32) ? HashFactory.Checksum.CreateCRC32a() : null,
                    requiredProperties.HasFlag(FileProperties.Adler32) ? HashFactory.Checksum.CreateAdler32() : null
                };

                foreach (var hasher in additionalHashers)
                {
                    hasher?.Initialize();
                }

                while ((readLength += stream.Read(buffer, readLength, BlockSize.Value - readLength)) != 0)
                {
                    Parallel.ForEach(
                        hashers,
                        hasher =>
                        {
                            hasher?.TransformBlock(buffer, 0, readLength, buffer, 0);
                        }
                    );

                    Parallel.ForEach(
                        additionalHashers,
                        hasher =>
                        {
                            hasher?.TransformBytes(buffer, 0, readLength);
                        }
                    );

                    if (requiredProperties.HasFlag(FileProperties.BlockMD5))
                    {
                        BlockMD5.Add(blockHashers[0].ComputeHash(buffer, 0, readLength).ToHexString());
                    }

                    if (requiredProperties.HasFlag(FileProperties.BlockSHA1))
                    {
                        BlockSHA1.Add(blockHashers[1].ComputeHash(buffer, 0, readLength).ToHexString());
                    }

                    if (requiredProperties.HasFlag(FileProperties.BlockSHA256))
                    {
                        BlockSHA256.Add(blockHashers[2].ComputeHash(buffer, 0, readLength).ToHexString());
                    }

                    readLength = 0;
                }

                foreach (var hasher in hashers)
                {
                    hasher?.TransformFinalBlock(buffer, 0, 0);
                }

                MD5 = MD5 ?? hashers[0]?.Hash.ToHexString();
                SHA1 = SHA1 ?? hashers[1]?.Hash.ToHexString();
                SHA256 = SHA256 ?? hashers[2]?.Hash.ToHexString();
                CRC32 = CRC32 ?? additionalHashers[0]?.TransformFinal().GetBytes().Reverse().ToArray().ToHexString();
                Adler32 = Adler32 ?? additionalHashers[1]?.TransformFinal().GetBytes().Reverse().ToArray().ToHexString();
            }

            if (requiredProperties.HasFlag(FileProperties.EncryptionKey))
            {
                EncryptionKey = GenerateEncryptionKey();
            }

            return this;
        }
Пример #2
0
        public static FileInformation GetInformation(string basePath, string path, FileProperties requiredProperties)
        {
            FileInformation info = GetInformation(File.OpenRead($"{basePath}/{path}"), requiredProperties);

            if (requiredProperties.HasFlag(FileProperties.Path))
            {
                info.Path = path.Replace(System.IO.Path.DirectorySeparatorChar, '/');
            }

            return info;
        }
Пример #3
0
        public FileInformation RemoveProperties(FileProperties removedProperties)
        {
            foreach (var p in Properties)
            {
                if (removedProperties.HasFlag(p.Key))
                {
                    p.Value.SetValue(this, null);
                }
            }

            return this;
        }
Пример #4
0
        public FileProperties CompareProperties(FileInformation other, FileProperties propertiesToCompare)
        {
            FileProperties result = FileProperties.None;
            foreach (var p in Properties)
            {
                if (propertiesToCompare.HasFlag(p.Key))
                {
                    if (p.Value.GetValue(other) != null)
                    {
                        if (p.Value.PropertyType.IsAssignableFrom(typeof(List<string>)))
                        {
                            var olist = p.Value.GetValue(other) as List<string>;
                            var tlist = p.Value.GetValue(this) as List<string>;
                            if (!tlist.SequenceEqual(olist))
                            {
                                result |= p.Key;
                            }
                        }
                        else if (!object.Equals(p.Value.GetValue(other), p.Value.GetValue(this)))
                        {
                            result |= p.Key;
                        }
                    }
                }
            }

            return result;
        }
Пример #5
0
    public FileInformation GetInfo(
        FileProperties propertiesToRemove = FileProperties.None,
        FileProperties requiredProperties = FileProperties.All) {
        using (var stream = OpenRead())
        {
            var info = FileInformation.Get(Path)
                .RemoveProperties(propertiesToRemove)
                .AddProperties(stream, requiredProperties);

            if (requiredProperties.HasFlag(FileProperties.Path) && info.Path == null) {
                info.Path = Path;
            }

            if (requiredProperties.HasFlag(FileProperties.Locations)) {
                if (info.Locations == null)
                    info.Locations = new Dictionary<string, string>();
                info.Locations[Spec] = ToString();
            }

            return info;
        }
    }