Пример #1
0
        // Group: Individual File Management Functions
        // __________________________________________________________________________


        /* Function: AddOrUpdateFile
         *
         * Adds a file or updates its last modification time.  If the file was not previously known to the class, it will be treated as
         * new, whereas if it was known but has a different modification time it will be treated as changed.  Returns whether this
         * call changed anything.  It is okay to call this multiple times on the same file.
         *
         * This is assumed to be called for files that are in a file source so it automatically sets <File.InFileSource>.
         */
        public bool AddOrUpdateFile(Path name, FileType type, DateTime lastModified, bool forceReparse = false)
        {
            lock (accessLock)
            {
                File file = files[name];

                // If the file didn't exist in our records it's new
                if (file == null)
                {
                    if (type == FileType.Image)
                    {
                        file = new ImageFile(name, lastModified);
                    }
                    else
                    {
                        file = new File(name, type, lastModified);
                    }

                    files.Add(file);
                    filesAddedSinceStart.Add(file.ID);
                    unprocessedChanges.AddNewFile(file);

                    foreach (var changeWatcher in changeWatchers)
                    {
                        changeWatcher.OnAddFile(file);
                    }

                    return(true);
                }

                // Make sure the file isn't being re-added as a different type
                else if (file.Type != type)
                {
                    throw new Exception("Added an existing file but the types didn't match.");
                }

                // If the file was previously marked as deleted it was recreated
                else if (file.Deleted)
                {
                    file.Deleted      = false;
                    file.LastModified = lastModified;

                    filesAddedSinceStart.Add(file.ID);
                    unprocessedChanges.AddNewFile(file);

                    foreach (var changeWatcher in changeWatchers)
                    {
                        changeWatcher.OnAddFile(file);
                    }

                    return(true);
                }

                // If the file changed or we're forcing everything to be reparsed anyway
                else if (file.LastModified != lastModified || forceReparse)
                {
                    file.LastModified = lastModified;

                    filesAddedSinceStart.Add(file.ID);
                    unprocessedChanges.AddChangedFile(file);

                    foreach (var changeWatcher in changeWatchers)
                    {
                        changeWatcher.OnFileChanged(file);
                    }

                    return(true);
                }

                // Otherwise the file is the same as the last time we saw it.
                else
                {
                    // This is still important because it's needed to know which files do and don't exist since the last time
                    // Natural Docs was run
                    filesAddedSinceStart.Add(file.ID);

                    return(false);
                }
            }
        }
Пример #2
0
        /* Function: Load
         * Loads <Files.nd> and returns whether it was successful.  If it wasn't it will still return valid objects, they will just
         * be empty.
         */
        public bool Load(Path filename, out IDObjects.Manager <File> files)
        {
            files = new IDObjects.Manager <File>(Config.Manager.KeySettingsForPaths, false);

            BinaryFile binaryFile = new BinaryFile();
            bool       result     = true;

            try
            {
                // We'll continue to handle 2.0 files in 2.0.2 since it's easy enough
                if (binaryFile.OpenForReading(filename, "2.0") == false)
                {
                    result = false;
                }
                else
                {
                    // [Int32: ID]
                    // [String: Path]
                    // [Byte: Type]
                    // [Int64: Last Modification in Ticks or 0]
                    // (if image)
                    //    [UInt32: Width in Pixels or 0 if unknown]
                    //    [UInt32: Height in Pixels or 0 if unknown]
                    // ...
                    // [Int32: 0]

                    int      id;
                    Path     path;
                    FileType type;
                    DateTime lastModification;
                    File     file;
                    uint     width, height;

                    for (;;)
                    {
                        id = binaryFile.ReadInt32();

                        if (id == 0)
                        {
                            break;
                        }

                        path             = binaryFile.ReadString();
                        type             = (FileType)binaryFile.ReadByte();
                        lastModification = new DateTime(binaryFile.ReadInt64());

                        if (type == FileType.Image)
                        {
                            if (binaryFile.Version < "2.0.2")
                            {
                                width  = 0;
                                height = 0;
                            }
                            else
                            {
                                width  = binaryFile.ReadUInt32();
                                height = binaryFile.ReadUInt32();
                            }

                            if (width == 0 || height == 0)
                            {
                                // If this file is from a different version of Natural Docs, no matter which one, reset the last modification
                                // time so they'll be reparsed and take another stab at getting the dimensions
                                if (binaryFile.Version != Engine.Instance.Version)
                                {
                                    lastModification = new DateTime(0);
                                }

                                file = new ImageFile(path, lastModification);
                            }
                            else
                            {
                                file = new ImageFile(path, lastModification, width, height);
                            }
                        }
                        else
                        {
                            file = new File(path, type, lastModification);
                        }

                        file.ID = id;
                        files.Add(file);
                    }
                }
            }
            catch
            {
                result = false;
            }
            finally
            {
                binaryFile.Close();
            }

            if (result == false)
            {
                files.Clear();
            }

            return(result);
        }
Пример #3
0
        // Group: Individual File Management Functions
        // __________________________________________________________________________


        /* Function: AddOrUpdateFile
         *
         * Adds a file or updates its last modification time.  If the file was not previously known to the class, it will be treated as
         * new, whereas if it was known but has a different modification time it will be treated as changed.  Returns whether this
         * call changed anything.  It is okay to call this multiple times on the same file.
         *
         * This is assumed to be called for files that are in a file source so it automatically sets <File.InFileSource>.
         */
        public bool AddOrUpdateFile(Path name, FileType type, DateTime lastModified, bool forceReparse = false)
        {
            bool changed = false;

            Monitor.Enter(accessLock);

            try
            {
                File file = files[name];

                // The file didn't exist in our records so it's new
                if (file == null)
                {
                    if (type == FileType.Image)
                    {
                        file = new ImageFile(name, lastModified);
                    }
                    else
                    {
                        file = new File(name, type, lastModified);
                    }

                    file.Status = FileFlags.NewOrChanged;
                    files.Add(file);

                    foreach (var changeWatcher in changeWatchers)
                    {
                        changeWatcher.OnAddFile(file);
                    }

                    changed = true;
                }

                else if (file.Type != type)
                {
                    throw new Exception("Added an existing file but the types didn't match.");
                }

                else if (file.Claimed == true)
                {
                    if (file.LastModified != lastModified || file.StatusSinceClaimed == FileFlags.DeletedSinceClaimed || forceReparse)
                    {
                        bool wasDeletedSinceClaimed = (file.StatusSinceClaimed == FileFlags.DeletedSinceClaimed);

                        file.LastModified       = lastModified;
                        file.StatusSinceClaimed = FileFlags.NewOrChangedSinceClaimed;

                        foreach (var changeWatcher in changeWatchers)
                        {
                            if (wasDeletedSinceClaimed)
                            {
                                changeWatcher.OnAddFile(file);
                            }
                            else
                            {
                                changeWatcher.OnFileChanged(file);
                            }
                        }

                        changed = true;
                    }
                }

                else if (file.LastModified != lastModified || file.Status == FileFlags.Deleted || forceReparse)
                {
                    bool wasDeleted = (file.Status == FileFlags.Deleted);

                    file.LastModified = lastModified;
                    file.Status       = FileFlags.NewOrChanged;

                    foreach (var changeWatcher in changeWatchers)
                    {
                        if (wasDeleted)
                        {
                            changeWatcher.OnAddFile(file);
                        }
                        else
                        {
                            changeWatcher.OnFileChanged(file);
                        }
                    }

                    changed = true;
                }

                file.InFileSource = true;
            }
            finally
            { Monitor.Exit(accessLock); }

            return(changed);
        }