Пример #1
0
        /// <summary>Forward OnNext</summary>
        public void OnNext(IEvent @event)
        {
            // A component observer registers in.
            if (@event is IStartEvent)
            {
                Interlocked.Increment(ref feedingObserverCount); return;
            }

            // If observer dispose has completed, don't forward events.
            if (this.IsDisposing)
            {
                return;
            }

            // Get child's state object
            StateInfo      state         = @event.Observer.State as StateInfo;
            IPathConverter pathConverter = state?.pathConverter;
            // Convert paths
            string newOldPath, newNewPath = null;

            if (pathConverter == null)
            {
                newOldPath = @event.Path;
                if (@event is IRenameEvent re)
                {
                    newNewPath = re.NewPath;
                }
            }
            else
            {
                if (!pathConverter.ChildToParent(@event.Path, out newOldPath))
                {
                    return;
                }
                if (@event is IRenameEvent re)
                {
                    if (!pathConverter.ChildToParent(re.NewPath, out newNewPath))
                    {
                        return;
                    }
                }
            }
            // Try to decorate event
            @event = EventDecoration.DecorateObserverAndPath(@event, this, newOldPath, newNewPath, false);
            // Forward event in this thread, which should be dispatcher's thread
            Observer.OnNext(@event);
        }
        /// <summary>
        /// Reads through html <paramref name="html"/> and scans for anchor elements with "href" attributes.
        /// Validates local or global links that refer to a subfile or subdirectory.
        /// </summary>
        /// <param name="baseUri">The uri where the document was loaded. Used for creating absolute uris from relative uris.</param>
        /// <param name="html">document data as stream</param>
        /// <param name="pathConverter">convert child urls (the real URIs) back to parent (API caller's) path format</param>
        /// <returns>array of files</returns>
        /// <exception cref="Exception"></exception>
        public virtual IEnumerable <IEntry> ReadEntries(string baseUri, string html, IPathConverter pathConverter)
        {
            // Result set
            HashSet <string> yielded = new HashSet <string>();
            // Parse base uri
            Uri _baseUri = new Uri(baseUri);
            // Get absolute uri
            string baseUriAbsolute = _baseUri.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped);

            // Search achors
            foreach (Match m in anchorPattern.Matches(html))
            {
                // Get href
                string href = m.Groups[1].Value;
                // Test not empty
                if (String.IsNullOrEmpty(href))
                {
                    continue;
                }
                // Parse attribute
                href = HttpUtility.HtmlDecode(href);
                // Entry
                IEntry entry = null;
                try
                {
                    // Parse uri
                    Uri uri = new Uri(_baseUri, href);
                    // Get absolute uri
                    string absoluteUri = uri.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped);
                    // Test that is child of baseUri
                    if (absoluteUri.Length <= baseUriAbsolute.Length || !absoluteUri.StartsWith(baseUriAbsolute))
                    {
                        continue;
                    }
                    // Test only one slash after baseUriAbsolute
                    int slashCount = 0;
                    int startIx    = baseUriAbsolute.EndsWith("/") ? baseUriAbsolute.Length : baseUriAbsolute.Length + 1;
                    for (int i = startIx; i < absoluteUri.Length - 1; i++)
                    {
                        // Not slash
                        if (absoluteUri[i] != '/')
                        {
                            continue;
                        }
                        // Add slash
                        slashCount++;
                        break;
                    }
                    // Too many slashes "<baseuri>/Dir/Dir/file", thereof not immediate child
                    if (slashCount >= 1)
                    {
                        continue;
                    }
                    // Already yielded?
                    if (!yielded.Add(absoluteUri))
                    {
                        continue;
                    }
                    // Extract name
                    String name = GetEntryName(absoluteUri);
                    // Convert path
                    string parentUri;
                    if (!pathConverter.ChildToParent(absoluteUri, out parentUri))
                    {
                        continue;
                    }
                    // Is directory
                    if (absoluteUri.EndsWith("/"))
                    {
                        entry = new DirectoryEntry(this, parentUri, name, DateTimeOffset.MinValue, DateTimeOffset.MinValue, null);
                    }
                    // Is unknown if is file or directory, so report as both
                    else
                    {
                        entry = new DirectoryAndFileEntry(this, parentUri, name, DateTimeOffset.MinValue, DateTimeOffset.MinValue, -1L, null);
                    }
                }
                catch (Exception)
                {
                    // bad uri
                    continue;
                }
                // Yield entry
                if (entry != null)
                {
                    yield return(entry);
                }
            }
        }