Click here to Skip to main content
15,888,158 members
Articles / General Programming / Threads

SimplePack Library

Rate me:
Please Sign up or sign in to vote.
4.93/5 (30 votes)
23 Nov 2010CPOL7 min read 72.7K   1.9K   97  
Simple way how to pack data into one file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using SimplePack.Helper;
using SimplePack.Properties;

namespace SimplePack.Data
{
    ///<summary>
    /// Footer contain whole structure of Archive and implements <see cref="IArchiveStructure"/>.
    ///</summary>
    [Serializable]
    public class Footer : IArchiveStructure
    {
        #region Properties

        private string packerName;
        private string versionName;
        private long length;
        private Collection<DirectoryArchive> directoryList;
        private Collection<FileArchive> fileList;
        private readonly HashSet<string> allFilesPaths;

        #endregion

        ///<summary>
        /// Default constructor.
        ///</summary>
        public Footer()
        {
            DirectoryList = new Collection<DirectoryArchive>();
            FileList = new Collection<FileArchive>();
            allFilesPaths = new HashSet<string>();
        }

        #region Attributes

        ///<summary>
        /// Name of packer program which creates Archive.
        /// For now it is: <value>SimplePack</value>
        ///</summary>
        [XmlAttribute]
        public string PackerName
        {
            get { return packerName; }
            set { packerName = value; }
        }

        ///<summary>
        /// Version of Archive type
        /// For now it is: <value>1.0.0.0</value>
        ///</summary>
        [XmlAttribute]
        public string VersionName
        {
            get { return versionName; }
            set { versionName = value; }
        }

        ///<summary>
        /// Contain full path in Archive hierarchical structure.
        ///</summary>
        [XmlIgnore]
        public string FullPath
        {
            get { return Settings.Default.ArchivePathRoot; }
            set {}  //not implemented
        }

        ///<summary>
        /// Represent size of whole Archive (except size of serialized Footer).
        ///</summary>
        [XmlAttribute]
        public long Length
        {
            get { return length; }
            set { length = value; }
        }

        ///<summary>
        ///Contains List of nested directories (only one level below). 
        ///</summary>
        [XmlElement]
        public Collection<DirectoryArchive> DirectoryList
        {
            get { return directoryList; }
            set { directoryList = value; }
        }

        ///<summary>
        /// Contains list of files which belongs to Footer (current level).
        ///</summary>
        [XmlElement]
        public Collection<FileArchive> FileList
        {
            get { return fileList; }
            set { fileList = value; }
        }

        ///<summary>
        /// Contains information how many files are in Footer.
        ///</summary>
        [XmlIgnore]
        public int NumberOfFiles
        {
            get { return fileList.Count; }
        }

        ///<summary>
        /// Contains information how many Directories are directly nested into Footer.
        ///</summary>
        [XmlIgnore]
        public int NumberOfDirectories
        {
            get { return directoryList.Count; }
        }

        ///<summary>
        /// Holds paths of all files in Archive.
        ///</summary>
        [XmlIgnore]
        public HashSet<string> AllFilesPaths
        {
            get { return allFilesPaths; }
        }

        #endregion

        #region Methods

        ///<summary>
        /// Add file into Footer.
        ///</summary>
        ///<param name="fileArchive">file which will be added</param>
        public void AddFile(FileArchive fileArchive)
        {
            fileArchive.ParentDirectory = this;
            FileList.Add(fileArchive);
            UpdateLength(fileArchive.Length);
            AllFilesPaths.Add(fileArchive.FullPath);
        }

        ///<summary>
        /// Remove file from Footer.
        ///</summary>
        ///<param name="fileArchive">file which will be removed</param>
        public void RemoveFile(FileArchive fileArchive)
        {
            if (!fileList.Remove(fileArchive)) 
                return;
            UpdateLength(fileArchive.Length * (-1));
            AllFilesPaths.Remove(fileArchive.FullPath);
        }

        ///<summary>
        /// Add directory like nested directory into Footer. 
        ///</summary>
        ///<param name="directoryArchive">directory which will be added</param>
        public void AddDirectory(DirectoryArchive directoryArchive)
        {
            directoryList.Add(directoryArchive);
            List<FileArchive> allNestedFiles = GetAllNestedFiles(new List<FileArchive>(), directoryArchive);
            foreach (FileArchive nestedFileArchive in allNestedFiles)
            {
                AllFilesPaths.Add(nestedFileArchive.FullPath);
            }
            UpdateLength(directoryArchive.Length);
        }

        ///<summary>
        /// Remove directory from nested directories.
        ///</summary>
        ///<param name="directoryArchive">directory which will be removed</param>
        public void RemoveDirectory(DirectoryArchive directoryArchive)
        {
            if (!directoryList.Remove(directoryArchive)) 
                return;
            List<FileArchive> allNestedFiles = GetAllNestedFiles(new List<FileArchive>(), directoryArchive);
            foreach (FileArchive nestedFileArchive in allNestedFiles)
            {
                AllFilesPaths.Remove(nestedFileArchive.FullPath);
            }
            UpdateLength(directoryArchive.Length * (-1));
        }

        ///<summary>
        /// Update size of Footer.
        ///</summary>
        ///<param name="diff">positive or negative number depends on Add or Remove operation</param>
        public void UpdateLength(long diff)
        {
            Length += diff;
        }

        ///<summary>
        /// Check if selected file path already exist of not.
        ///</summary>
        ///<param name="filePath"></param>
        ///<returns></returns>
        public bool ContainsFileFullPath(string filePath)
        {
            return AllFilesPaths.Contains(filePath);
        }

        private static List<FileArchive> GetAllNestedFiles(List<FileArchive> allNestedFiles, IArchiveStructure dir)
        {
            foreach (DirectoryArchive directoryArchive in dir.DirectoryList)
            {
                GetAllNestedFiles(allNestedFiles, directoryArchive);
            }
            foreach (FileArchive fileArchive in dir.FileList)
            {
                allNestedFiles.Add(fileArchive);
            }
            return allNestedFiles;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Slovakia Slovakia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions