Пример #1
0
        /// <summary>
        /// Remove an item from the Cab
        /// Note : You will need to call GenerateArchive() to commit the changes
        /// </summary>
        /// <param name="key">the key to find</param>
        /// <returns>The direct Archiver than was containing this key</returns>
        public Archiver RemoveItem(string key)
        {
            Archiver fileOwner = null;

            //

            FileEntryDescriptor fileEntry = FindFileEntry(key);

            if (fileEntry == null)
            {
                throw new CompressionException("The specified key awsa not found, therefore, the element cannot be remoted");
            }
            fileOwner = fileEntry.Root;
            fileEntry.Root._files.Remove(fileEntry);

            // remove entry from all _argumentHash Hashtables
            Archiver ptr = fileOwner;

            while (ptr != null)
            {
                ptr._archiveHash.Remove(key);
                ptr = ptr._root;
            }
            return(fileOwner);
        }
Пример #2
0
        /// <summary>
        /// Add a File to to the archive
        /// </summary>
        /// <param name="fileName">The file name</param>
        /// <param name="index">The index number (must be unique)</param>
        /// <param name="cleanup">Delete the file after compression</param>
        public void AddFile(string fileName, string index, bool cleanup)
        {
            FileEntryDescriptor fed = new FileEntryDescriptor(fileName, index);

            fed.Cleanup = cleanup;
            AddFile(fed);
        }
Пример #3
0
 /// <summary>
 /// Add a FileEntryDescriptor to the archive
 /// </summary>
 public void AddFile(FileEntryDescriptor fileEntryDescriptor)
 {
     if (fileEntryDescriptor == null)
     {
         throw new ArgumentNullException("fileEntryDescriptor", "Must be set to a valid instance of FileEntryDescriptor");
     }
     AddFileInternal(fileEntryDescriptor);
 }
Пример #4
0
        /// <summary>
        /// Load an Archive and extract the files
        /// </summary>
        /// <param name="archiverName">The name of the archive to open</param>
        /// <returns>An instance of the Archiver object</returns>
        static public Archiver Load(string archiverName)
        {
            Archiver retVal = null;

            if (archiverName == null || archiverName.Trim() == string.Empty)
            {
                throw new ArgumentNullException("archiverName", "An invalid value was passed in as parameter (null / empty / whitespace)");
            }
            archiverName = TranslateEnvironmentVariable(archiverName);
            if (File.Exists(archiverName) == false)
            {
                throw new FileNotFoundException("the specified file was not found", archiverName);
            }

            retVal = new Archiver(archiverName);
            XmlDocument xmlDoc = new XmlDocument();

            // Get its description file
            retVal.CreateDirectory(retVal._archivePath);
            retVal._cabInfo.ExtractAll(retVal._archivePath, true, null, null);
            xmlDoc.Load(Path.Combine(retVal._archivePath, retVal._cabInfo.Name) + XMLEXTENSION);

            // Populate _files arraylist
            XmlNodeList nodeListFiles = xmlDoc.SelectNodes("*/" + ENTRY);

            foreach (XmlNode node in nodeListFiles)
            {
                FileEntryDescriptor fileDesc = new FileEntryDescriptor(Path.Combine(retVal._archivePath, node.Attributes[NAME].Value), node.Attributes[KEY].Value);
                fileDesc.Root = retVal;
                retVal._files.Add(fileDesc);
                retVal._archiveHash.Add(fileDesc.Index, fileDesc.FullName);
            }

            // Populate _subArchive arraylist
            XmlNodeList nodeListArchive = xmlDoc.SelectNodes("*/" + ARCHIVE);

            foreach (XmlNode node in nodeListArchive)
            {
                Archiver subArchive = Archiver.Load(Path.Combine(retVal._archivePath, node.Attributes[NAME].Value));
                retVal._subArchives.Add(subArchive);
                // copy hash of sub archive in this hash
                IDictionaryEnumerator iter = subArchive._archiveHash.GetEnumerator();
                while (iter.MoveNext())
                {
                    retVal._archiveHash.Add(iter.Key, iter.Value);
                }
            }

            retVal.CheckArchiveCrc();

            return(retVal);
        }
Пример #5
0
        private FileEntryDescriptor FindFileEntry(string key)
        {
            FileEntryDescriptor retVal = null;

            for (int t = 0; t < this._files.Count; t++)
            {
                if (((FileEntryDescriptor)this._files[t]).Index == key)
                {
                    return((FileEntryDescriptor)this._files[t]);
                }
            }
            foreach (Archiver archive in this._subArchives)
            {
                retVal = archive.FindFileEntry(key);
                if (retVal != null)
                {
                    return(retVal);
                }
            }
            return(null);
        }
Пример #6
0
        private void AddFileInternal(FileEntryDescriptor fileEntry)
        {
            // Check if index already exist
            if (_archiveHash.Contains(fileEntry.Index))
            {
                throw new DuplicateNameException("Index '" + fileEntry.Index + "'  (existing 1 : '" + _archiveHash[fileEntry.Index].ToString() + "' file being added : '" + fileEntry.FullName + "') already exist, indexes must be unique");
            }
            // Check if file exist at specified location
            if (File.Exists(fileEntry.FullName) == false)
            {
                throw new FileNotFoundException("The specified file ('" + fileEntry.Name + "') was not found", fileEntry.FullName);
            }
            Archiver ptr = this;

            fileEntry.Root = this;
            _files.Add(fileEntry);
            // Cabinet needs to be recreated
            while (ptr != null)
            {
                ptr._isDirty = true;
                ptr          = ptr._root;
            }
        }
Пример #7
0
        private void AddStuffObjectInternal(string key, object streamed, string prefix)
        {
            if (key == null || key.Trim() == string.Empty)
            {
                throw new ArgumentNullException("The indexing key is null / empty / whitespace");
            }
            // Check if index already exist
            if (_archiveHash.Contains(key))
            {
                throw new DuplicateNameException("Index '" + key + "' already exist, indexes must be unique");
            }

            CreateDirectory(_archivePath);

            // Create file so it can be added to the cab
            string       cntName = Path.Combine(_archivePath, prefix + Guid.NewGuid().ToString() + ".cnt");
            StreamWriter strw    = null;

            try
            {
                strw = new StreamWriter(cntName);
                strw.Write(streamed);
            }
            finally
            {
                if (strw != null)
                {
                    strw.Close();
                }
            }

            FileEntryDescriptor fileDescription = new FileEntryDescriptor(cntName, key);

            fileDescription.Cleanup = true;
            AddFileInternal(fileDescription);
        }
Пример #8
0
        private XmlElement GenArchive(string accessPath)
        {
            if (this._isDirty)
            {
                _archiveHash.Clear();
                this._isDirty = false;
            }
            // Create description file (xml file describing the cab file)
            XmlElement   node           = _xmlDoc.CreateElement(ARCHIVE);
            XmlAttribute indexAttribute = _xmlDoc.CreateAttribute(INDEX);

            if (accessPath != null && accessPath.Trim() != string.Empty)
            {
                accessPath = accessPath.Trim() + SEPARATOR + _name;
            }
            else
            {
                accessPath = _name;
            }
            indexAttribute.Value = accessPath;
            XmlAttribute nameAttribute = _xmlDoc.CreateAttribute(NAME);

            nameAttribute.Value = _name;
            XmlAttribute typeAttribute = _xmlDoc.CreateAttribute("type");

            typeAttribute.Value = _Type.ToString();
            node.Attributes.Append(indexAttribute);
            node.Attributes.Append(nameAttribute);
            node.Attributes.Append(typeAttribute);


            foreach (FileEntryDescriptor ftd in _files)
            {
                XmlElement   fileNode     = _xmlDoc.CreateElement(ENTRY);
                XmlAttribute keyAttribute = _xmlDoc.CreateAttribute(KEY);
                keyAttribute.Value = ftd.Index;
                XmlAttribute fileNameAttribute = _xmlDoc.CreateAttribute(NAME);
                fileNameAttribute.Value = ftd.Name;
                XmlAttribute rootAttribute = _xmlDoc.CreateAttribute(ROOT);
                rootAttribute.Value = ftd.Root._name;
                fileNode.Attributes.Append(keyAttribute);
                fileNode.Attributes.Append(fileNameAttribute);
                fileNode.Attributes.Append(rootAttribute);
                node.AppendChild(fileNode);
            }

            ArrayList filesToCab = new ArrayList();

            // Recurse in sub archive
            foreach (Archiver subArchive in _subArchives)
            {
                XmlElement childNode = subArchive.GenArchive(/*archivePath,*/ accessPath);
                node.AppendChild(childNode);
                // Add sub-Archive to CAB
//                        filesToCab.Add(Path.Combine(/*archivePath*/subArchive._directoryName, subArchive._name));
                string subArchivePath            = Path.Combine(subArchive._directoryName, subArchive._name);
                FileEntryDescriptor ArchiveEntry = new FileEntryDescriptor(subArchivePath, Path.GetFileName(subArchivePath));
                ArchiveEntry.Cleanup = true;
                _files.Add(ArchiveEntry);
                // copy hashtable entry to this hashtable
                IDictionaryEnumerator iter = subArchive._archiveHash.GetEnumerator();
                while (iter.MoveNext())
                {
                    if (_archiveHash.Contains(iter.Key))
                    {
                        throw new DuplicateNameException("Index must be unique, index '" + iter.Key.ToString() + "' already exist");
                    }
                    _archiveHash.Add(iter.Key, iter.Value);         // check for duplicate index
                }
            }

            // Add files to CAB
            foreach (FileEntryDescriptor fileDesc in _files)
            {
                if (File.Exists(fileDesc.FullName) == false)
                {
                    throw new FileNotFoundException("The file specified does not exist", fileDesc.Name);
                }
                filesToCab.Add(fileDesc.FullName);
                if (_archiveHash.Contains(fileDesc.Index))
                {
                    throw new DuplicateNameException("Index must be unique, index '" + fileDesc.Index + "' already exist");
                }
                _archiveHash.Add(fileDesc.Index, fileDesc.FullName);
            }

            // Compute CRC
            string crc = CompFileCrc((string[])filesToCab.ToArray(typeof(string)));

            // Add CRC And save file description (xml file describing the cab file)
            XmlAttribute crcAttribute = _xmlDoc.CreateAttribute(CRC);

            crcAttribute.Value = crc;
            node.Attributes.Append(crcAttribute);
            _xmlDoc.LoadXml(node.OuterXml);
            CreateDirectory(_archivePath);
            string xmlFile = Path.Combine(_archivePath, _name + XMLEXTENSION);

            _xmlDoc.Save(xmlFile);
            _xmlDoc.RemoveAll();
            FileEntryDescriptor fed = new FileEntryDescriptor(xmlFile, xmlFile);

            fed.Cleanup = true;
            _files.Add(fed);
            filesToCab.Add(xmlFile);

            // Generate CAB
            _cabInfo.CompressFiles(null, (string[])filesToCab.ToArray(typeof(string)), null);

            // Clean up
            foreach (FileEntryDescriptor fileDesc in _files)
            {
                if (fileDesc.Cleanup == true)
                {
                    try
                    {
                        // @ review : Bypass system readonly setting if user want to delete a readonly file ?
                        FileAttributes fileAttribute = File.GetAttributes(fileDesc.FullName);
                        if ((fileAttribute & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                        {
                            fileAttribute ^= FileAttributes.ReadOnly;
                            File.SetAttributes(fileDesc.FullName, fileAttribute);
                        }
                        File.Delete(fileDesc.FullName);
                    }
                    catch (IOException ioe)
                    {
                        // file might be in use
                        Console.WriteLine("Cannot delete file -- reason : " + ioe.Message);
                    }
                }
            }
            //
            return(node);
        }
Пример #9
0
 private string CompFileCrc(FileEntryDescriptor fileDescriptor)
 {
     return(CompFileCrc(new FileEntryDescriptor[] { fileDescriptor }));
 }