コード例 #1
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
        /// <summary>
        /// Reads and collects clusters in index
        /// </summary>
        private void ReconstructIndex()
        {
            byte[] buffer = new byte[HeaderCluster.HeaderBytes];
            for (int i = 0; i < (fs.Length - ReservedHeaderLength) / clusterSize; i++)
            {
                PositionToCluster(i);
                fs.Read(buffer, 0, buffer.Length);

                ClusterFlags flags = (ClusterFlags)buffer[0];

                if (flags != ClusterFlags.Empty)
                {
                    if ((flags & ClusterFlags.StreamHeader) != 0)
                    {
                        Guid id = new Guid(new byte[] { buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18], buffer[19], buffer[20] });

                        if (!id.Equals(indexKey))
                        {
                            if ((flags & ClusterFlags.SafeCopy) != 0)
                            {
                                // Write not safe copy status
                                PositionToCluster(i);
                                fs.WriteByte((byte)ClusterFlags.StreamHeader);

                                // Key already in index ?
                                if (index.ContainsKey(id))
                                {
                                    // Delete previous chain and free space
                                    DeleteChain((int)index[id], true);
                                    // Remove from index
                                    index.Remove(id);
                                }
                            }

                            if (!index.ContainsKey(id))
                            {
                                index.Add(id, i);
                            }
                            else
                            {
                                // Delete duplicate chain and free space
                                DeleteChain(i, true);
                            }
                        }
                        else
                        {
                            // Index entry found at this point means it was corrupted
                            DeleteChain(i, false);
                        }
                    }
                }
                else
                {
#if DEBUG
                    Debug.Assert(!emptyClusters.Contains(i));
#endif
                    emptyClusters.Enqueue(i);
                }
            }
        }
コード例 #2
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
        /// <summary>
        /// Reads the data from file
        /// </summary>
        /// <param name="clusterNumber">Cluster of data location.</param>
        /// <returns>Data bytes</returns>
        private byte[] Read(int clusterNumber)
        {
            byte[] result     = null;
            int    dataOffset = 0;
            int    dataLength = 1;

            byte[] buffer = new byte[clusterSize];
            while (dataOffset < dataLength)
            {
                PositionToCluster(clusterNumber);
                fs.Read(buffer, 0, clusterSize);

                ClusterFlags flags       = (ClusterFlags)buffer[0];
                int          headerBytes = 0;

                if ((flags & ClusterFlags.StreamHeader) != 0)
                {
                    clusterNumber = BitConverter.ToInt32(buffer, 1);
                    dataLength    = BitConverter.ToInt32(buffer, 21);
                    headerBytes   = HeaderCluster.HeaderBytes;

                    if (result == null)
                    {
                        result = new byte[dataLength];
                    }
                    else
                    {
                        throw new InvalidOperationException("Unexpected second header in chain");
                    }
                }
                else
                {
                    if ((flags & ClusterFlags.StreamData) != 0)
                    {
                        clusterNumber = BitConverter.ToInt32(buffer, 1);
                        headerBytes   = DataCluster.HeaderBytes;
                    }
                    else
                    {
                        throw new InvalidDataException();
                    }
                }

                if (result == null)
                {
                    throw new InvalidOperationException("Header not found in chain");
                }

                int remainingBytes = clusterSize - headerBytes;
                Array.Copy(buffer, headerBytes, result, dataOffset, Math.Min(remainingBytes, dataLength - dataOffset));
                dataOffset += remainingBytes;
            }
            return(result);
        }
コード例 #3
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
        /// <summary>
        /// Reads the chain of clusters
        /// </summary>
        /// <param name="clusterNumber">Cluster number</param>
        /// <returns>Cluster chain</returns>
        private DataCluster ReadChain(int clusterNumber)
        {
            if (clusterNumber == -1)
            {
                return(null);
            }

            // Position to start of cluster
            PositionToCluster(clusterNumber);

            byte[] buffer = new byte[HeaderCluster.HeaderBytes];
            fs.Read(buffer, 0, buffer.Length);

            ClusterFlags flags = (ClusterFlags)buffer[0];

            if ((flags & ClusterFlags.StreamHeader) != 0)
            {
                HeaderCluster cluster = new HeaderCluster(
                    flags,
                    new Guid(new byte[] { buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18], buffer[19], buffer[20] }),
                    clusterNumber,
                    BitConverter.ToInt32(buffer, 21),
                    ReadChain(BitConverter.ToInt32(buffer, 1))
                    );

                return(cluster);
            }
            else
            {
                if ((flags & ClusterFlags.StreamData) != 0)
                {
                    DataCluster cluster = new DataCluster(
                        flags,
                        clusterNumber,
                        ReadChain(BitConverter.ToInt32(buffer, 1)));

                    return(cluster);
                }
                else
                {
                    return(null);
                }
            }
        }
コード例 #4
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
        /// <summary>
        /// Generates report about data fragmentation
        /// </summary>
        /// <returns>List of present bytestream lengths separated by newline</returns>
        public string FragmentationReport()
        {
            StringBuilder sb = new StringBuilder();

            byte[] buffer = new byte[clusterSize];

            foreach (Guid item in index.Keys)
            {
                int clusterNumber = (int)index[item];
                PositionToCluster(clusterNumber);
                fs.Read(buffer, 0, clusterSize);

                ClusterFlags flags = (ClusterFlags)buffer[0];

                if ((flags & ClusterFlags.StreamHeader) != 0)
                {
                    int dataLength = BitConverter.ToInt32(buffer, 21);
                    sb.AppendLine(dataLength.ToString());
                }
            }

            return(sb.ToString());
        }
コード例 #5
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
 /// <summary>
 /// Creates new instance of HeaderCluster type
 /// </summary>
 /// <param name="flags">Initial flags</param>
 /// <param name="clusterNumber">Assigned cluster number</param>
 /// <param name="nextCluster">Next cluster</param>
 /// <param name="key">Key which is stored</param>
 /// <param name="dataLength">Total data length</param>
 public HeaderCluster(ClusterFlags flags, Guid key, int clusterNumber, int dataLength, DataCluster nextCluster)
     : base(flags, clusterNumber, nextCluster)
 {
     this.Key = key;
     this.DataLength = dataLength;
 }
コード例 #6
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
 /// <summary>
 /// Creates new instance of DataCluster type
 /// </summary>
 /// <param name="flags">Initial flags</param>
 /// <param name="clusterNumber">Assigned cluster number</param>
 /// <param name="nextCluster">Next cluster</param>
 public DataCluster(ClusterFlags flags, int clusterNumber, DataCluster nextCluster)
 {
     this.Flags = flags;
     this.ClusterNumber = clusterNumber;
     this.NextCluster = nextCluster;
 }
コード例 #7
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
 /// <summary>
 /// Creates new instance of DataCluster type
 /// </summary>
 /// <param name="flags">Initial flags</param>
 /// <param name="clusterNumber">Assigned cluster number</param>
 /// <param name="nextCluster">Next cluster</param>
 public DataCluster(ClusterFlags flags, int clusterNumber, DataCluster nextCluster)
 {
     this.Flags         = flags;
     this.ClusterNumber = clusterNumber;
     this.NextCluster   = nextCluster;
 }
コード例 #8
0
ファイル: IndexedFile.cs プロジェクト: nemanjazz/iog
 /// <summary>
 /// Creates new instance of HeaderCluster type
 /// </summary>
 /// <param name="flags">Initial flags</param>
 /// <param name="clusterNumber">Assigned cluster number</param>
 /// <param name="nextCluster">Next cluster</param>
 /// <param name="key">Key which is stored</param>
 /// <param name="dataLength">Total data length</param>
 public HeaderCluster(ClusterFlags flags, Guid key, int clusterNumber, int dataLength, DataCluster nextCluster) :
     base(flags, clusterNumber, nextCluster)
 {
     this.Key        = key;
     this.DataLength = dataLength;
 }