Example #1
0
        /// <summary>
        /// reads in all the indexes from the specified input stream.
        /// </summary>
        /// <param name="input"></param>
        public void ReadIndexes(Stream input)
        {
            // reads all the index data from the filestream
            while (input.Position < input.Length)
            {
                // get the starting position of the index block.
                long indexStartPosition = input.Position;
                int  indexLength        = 0;

                // read in the raw index descriptor:
                RawIndex raw = ReadNextIndexBlock(input, out indexLength);

                // add a new index to the list:
                _fileIndex.Add(new ArchiveFileIndex()
                {
                    // keep the length, name, start index, and index block position/length
                    FileLength              = raw.L,
                    FileName                = raw.N,
                    FileStartIndex          = input.Position,
                    IndexBlockPositionStart = indexStartPosition,
                    IndexBlockLength        = indexLength
                });

                // skip the appropriate amount of the file:
                input.Position += raw.L;
            }
        }
Example #2
0
        /// <summary>
        /// writes the index data and the raw file blocks to the destination stream.
        /// </summary>
        /// <param name="destStream"></param>
        /// <param name="idx"></param>
        /// <param name="dataArray"></param>
        /// <param name="updIndex"></param>
        public static void AddRawData(Stream destStream, RawIndex idx, byte[] dataArray, IndexHandler updIndex)
        {
            // serialize and compress the index data:
            byte[] indexData = RawIndex.ToByteArray(idx);

            // generate the header bytes:
            byte[] header = BitConverter.GetBytes((ushort)indexData.Length);

            // move to the end of the stream:
            destStream.Position = destStream.Length;

            // write the header data:
            destStream.Write(header, 0, header.Length);

            // write the index data:
            destStream.Write(indexData, 0, indexData.Length);

            // add the index record to the handler:
            updIndex.ArchiveIndex.Add(new ArchiveFileIndex()
            {
                FileLength     = idx.L,
                FileName       = idx.N,
                FileStartIndex = destStream.Position
            });

            // write the data to the stream
            destStream.Write(dataArray, 0, dataArray.Length);
        }
Example #3
0
        /// <summary>
        /// adds a list of files to an archive.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="destStream"></param>
        /// <param name="updIndex"></param>
        public static void AddData(List <ArchiveFile> data, Stream destStream, IndexHandler updIndex)
        {
            if (!destStream.CanWrite)
            {
                throw new ArgumentException("Cannot Write to Stream");
            }
            if (!destStream.CanSeek)
            {
                throw new ArgumentException("Cannot Seek!");
            }

            // enumerate the archive files: generate the index and the data.
            foreach (var file in data)
            {
                // serialize and compress the archive file
                byte[] serialData = file.ToByteArray();

                // generate a new index:
                RawIndex idx = new RawIndex()
                {
                    N = file.ToString(),
                    L = serialData.Length
                };
                AddRawData(destStream, idx, serialData, updIndex);
            }
        }
Example #4
0
        /// <summary>
        /// read in the next index descriptor, and pass out the length.
        /// this assumes that the position of the filestream is at the start of an index.
        /// </summary>
        /// <param name="fs"></param>
        /// <returns></returns>
        public static RawIndex ReadNextIndexBlock(Stream fs, out int length)
        {
            // read in the length of the index data
            length = readNextIndexDataLength(fs);

            // read in the block of index data:
            byte[] idxBlock = ReadBuffer(fs, length);

            // deserialize it:
            return(RawIndex.FromByteArray(idxBlock));
        }
Example #5
0
        /// <summary>
        /// remove a list of files from the archive by the archive file index.
        /// this works by duplicating the archive file into a temp location, skipping the files due to be deleted
        /// and then copying the duplicate back over the original.
        /// not the most inspired solution but better than nothing.
        /// </summary>
        /// <param name="filesToRemove"></param>
        public void RemoveFiles(List <ArchiveFileIndex> filesToRemove)
        {
            // create a temporary file:
            String tempFileName = Path.GetTempFileName();

            // create a temporary archive:
            StreamingArchiveFile tempArc = new StreamingArchiveFile(tempFileName);

            // extract each file from this archive, add it to the other archive,
            // except the files to be deleted.
            using (Stream input = GetStream())
            {
                using (Stream output = tempArc.GetStream())
                {
                    // enumerate the indexes:
                    foreach (ArchiveFileIndex idx in _index.ArchiveIndex)
                    {
                        if (!filesToRemove.Contains(idx))
                        {
                            // process this... read in the raw data block:
                            input.Seek(idx.FileStartIndex, SeekOrigin.Begin);

                            // read the compressed file data:
                            byte[] data = IndexHandler.ReadBuffer(input, idx.FileLength);

                            // now generate the raw index:
                            RawIndex rawIndex = new RawIndex()
                            {
                                N = idx.FileName,
                                L = idx.FileLength
                            };

                            // add to the destination:
                            AddRawData(output, rawIndex, data, tempArc._index);
                        }
                    }
                }
            }



            // now copy the temp file back over the archive:
            File.Delete(_fileName);
            File.Move(tempFileName, _fileName);

            // now re-read the indexes:
            OpenArchive(_fileName);
        }
 /// <summary>
 /// compresses an array of RawIndex objects to a byte-array.
 /// </summary>
 /// <param name="indexData"></param>
 /// <returns></returns>
 public static byte[] ToByteArray(RawIndex indexData)
 {
     return TinySerializer.Serialize(indexData, true);
 }
        /// <summary>
        /// writes the index data and the raw file blocks to the destination stream.
        /// </summary>
        /// <param name="destStream"></param>
        /// <param name="idx"></param>
        /// <param name="dataArray"></param>
        /// <param name="updIndex"></param>
        public static void AddRawData(Stream destStream, RawIndex idx, byte[] dataArray, IndexHandler updIndex)
        {
            // serialize and compress the index data:
            byte[] indexData = RawIndex.ToByteArray(idx);

            // generate the header bytes:
            byte[] header = BitConverter.GetBytes((ushort)indexData.Length);

            // move to the end of the stream:
            destStream.Position = destStream.Length;

            // write the header data:
            destStream.Write(header, 0, header.Length);

            // write the index data:
            destStream.Write(indexData, 0, indexData.Length);

            // add the index record to the handler:
            updIndex.ArchiveIndex.Add(new ArchiveFileIndex()
            {
                FileLength = idx.L,
                FileName = idx.N,
                FileStartIndex = destStream.Position
            });

            // write the data to the stream
            destStream.Write(dataArray, 0, dataArray.Length);

        }
        /// <summary>
        /// adds a list of files to an archive.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="destStream"></param>
        /// <param name="updIndex"></param>
        public static void AddData(List<ArchiveFile> data, Stream destStream, IndexHandler updIndex)
        {
            if (!destStream.CanWrite)
                throw new ArgumentException("Cannot Write to Stream");
            if (!destStream.CanSeek)
                throw new ArgumentException("Cannot Seek!");

            // enumerate the archive files: generate the index and the data.
            foreach (var file in data)
            {
                // serialize and compress the archive file
                byte[] serialData = file.ToByteArray();

                // generate a new index:
                RawIndex idx = new RawIndex()
                {
                    N = file.ToString(),
                    L = serialData.Length
                };
                AddRawData(destStream, idx, serialData, updIndex);
            }

            
        }
        /// <summary>
        /// remove a list of files from the archive by the archive file index.
        /// this works by duplicating the archive file into a temp location, skipping the files due to be deleted
        /// and then copying the duplicate back over the original.
        /// not the most inspired solution but better than nothing.
        /// </summary>
        /// <param name="filesToRemove"></param>
        public void RemoveFiles(List<ArchiveFileIndex> filesToRemove)
        {
            // create a temporary file:
            String tempFileName = Path.GetTempFileName();

            // create a temporary archive:
            StreamingArchiveFile tempArc = new StreamingArchiveFile(tempFileName);

            // extract each file from this archive, add it to the other archive,
            // except the files to be deleted.
            using (Stream input = GetStream())
            {
                using (Stream output = tempArc.GetStream())
                {
                    // enumerate the indexes:
                    foreach (ArchiveFileIndex idx in _index.ArchiveIndex)
                    {
                        if (!filesToRemove.Contains(idx))
                        {
                            // process this... read in the raw data block:
                            input.Seek(idx.FileStartIndex, SeekOrigin.Begin);

                            // read the compressed file data:
                            byte[] data = IndexHandler.ReadBuffer(input, idx.FileLength);

                            // now generate the raw index:
                            RawIndex rawIndex = new RawIndex()
                            {
                                N = idx.FileName,
                                L = idx.FileLength
                            };

                            // add to the destination:
                            AddRawData(output, rawIndex, data, tempArc._index);
                        }
                    }
                }
            }

            

            // now copy the temp file back over the archive:
            File.Delete(_fileName);
            File.Move(tempFileName, _fileName);

            // now re-read the indexes:
            OpenArchive(_fileName);

        }
Example #10
0
 /// <summary>
 /// compresses an array of RawIndex objects to a byte-array.
 /// </summary>
 /// <param name="indexData"></param>
 /// <returns></returns>
 public static byte[] ToByteArray(RawIndex indexData)
 {
     return(TinySerializer.Serialize(indexData, true));
 }