public override void Process(Command command) { var count = 0; var options = this.LoadOptions <CommandOptions>((TextCommand)command); var dir = this.Connection.FileSystemManager.ResolveDirectory(options.Uri); dir.Refresh(); if (options.Regex != null) { options.Regex = TextConversion.FromEscapedHexString(options.Regex); } if (!dir.Exists) { throw new DirectoryNodeNotFoundException(dir.Address); } Connection.WriteOk(); if (options.IncludeAttributes) { Exception exception = null; InvocationQueue queue; if (t_InvocationQueue == null) { t_InvocationQueue = new InvocationQueue(); } queue = t_InvocationQueue; queue.TaskAsynchronisity = TaskAsynchronisity.AsyncWithSystemPoolThread; queue.Start(); try { IEnumerable <INode> children = null; if (String.IsNullOrEmpty(options.Regex)) { children = dir.GetChildren(); } else { children = dir.GetChildren(RegexBasedNodePredicateHelper.New(options.Regex)); } foreach (var node in children) { var enclosedNode = node; if (queue.TaskState == TaskState.Stopped) { break; } queue.Enqueue ( delegate { try { if (enclosedNode.NodeType == NodeType.Directory) { Connection.WriteTextPartialBlock("d:"); } else { Connection.WriteTextPartialBlock("f:"); } Connection.WriteTextBlock(TextConversion.ToEscapedHexString(enclosedNode.Name, TextConversion.IsStandardUrlEscapedChar)); AttributesCommands.PrintAttributes(this.Connection, enclosedNode); count++; if (count % 15 == 0) { Connection.Flush(); } } catch (Exception e) { queue.Stop(); exception = e; } } ); } if (queue.TaskState == TaskState.Stopped) { throw exception; } } finally { queue.Enqueue(queue.Stop); queue.WaitForAnyTaskState(value => value != TaskState.Running); queue.Reset(); Connection.Flush(); } } else { IEnumerable <string> children; if (string.IsNullOrEmpty(options.Regex)) { children = dir.GetChildNames(NodeType.Directory); } else { children = dir.GetChildNames(NodeType.Directory, PredicateUtils.NewRegex(options.Regex)); } foreach (var name in children) { Connection.WriteTextPartialBlock("d:"); Connection.WriteTextBlock(TextConversion.ToEscapedHexString(name, TextConversion.IsStandardUrlEscapedChar)); count++; if (count % 15 == 0) { Connection.Flush(); } } count = 0; if (string.IsNullOrEmpty(options.Regex)) { children = dir.GetChildNames(NodeType.File); } else { children = dir.GetChildNames(NodeType.File, PredicateUtils.NewRegex(options.Regex)); } foreach (var name in children) { Connection.WriteTextPartialBlock("f:"); Connection.WriteTextBlock(TextConversion.ToEscapedHexString(name)); count++; if (count % 15 == 0) { Connection.Flush(); } } } Connection.Flush(); }
public override IEnumerable <INode> DoGetChildren(NodeType nodeType, Predicate <INode> acceptNode) { var listedAllChildren = false; IDictionary <string, INode> newChildren; Pair <DirectoryRefreshMask, int> refreshInfo; foreach (INode node in this.GetJumpPoints(nodeType, acceptNode)) { yield return(node); } var shouldLoadFromNetwork = false; lock (this.SyncLock) { refreshInfo = this.directoryRefreshInfo; if ((refreshInfo.Left & DirectoryRefreshMask.Children) != 0) { shouldLoadFromNetwork = true; } if (this.children == null) { this.children = new SortedDictionary <string, INode>(StringComparer.CurrentCultureIgnoreCase); } } if (shouldLoadFromNetwork) { string regex = null; var skipAcceptNode = false;; var toRemove = new List <string>(); var newAttributes = new Dictionary <string, object>(StringComparer.CurrentCultureIgnoreCase); if (NetworkDirectory.threadLocalNewChildren == null) { NetworkDirectory.threadLocalNewChildren = new SortedDictionary <string, INode>(StringComparer.CurrentCultureIgnoreCase); } else { NetworkDirectory.threadLocalNewChildren.Clear(); } newChildren = NetworkDirectory.threadLocalNewChildren; try { if (RegexBasedNodePredicateHelper.IsRegexBasedNodePredicate(acceptNode) /* Only load based on REGEX if not refreshing AllChildren */ && refreshInfo.Left != DirectoryRefreshMask.AllChildren) { regex = RegexBasedNodePredicateHelper.GetRegexFromRegexBasedNodePredicate(acceptNode).ToString(); if (RegexBasedNodePredicateHelper.PredicateNameBasedOnly(acceptNode)) { skipAcceptNode = true; } } using (var freeClientContext = ((NetworkFileSystem)this.FileSystem).GetFreeClientContext()) { var networkclient = freeClientContext.NetworkFileSystemClient; IEnumerator <NetworkFileSystemEntry> enumerator; var enumerable = networkclient.ListAttributes(this.Address.RemoteUri, regex); using (enumerator = enumerable.GetEnumerator()) { while (true) { try { if (!enumerator.MoveNext()) { break; } } catch (DirectoryNodeNotFoundException) { lock (this.SyncLock) { foreach (var node in this.children.Values) { ((NetworkNodeAndFileAttributes)node.Attributes).Clear(); ((NetworkNodeAndFileAttributes)node.Attributes).SetValue <bool>("exists", false); } this.children.Clear(); } throw; } var entry = enumerator.Current; INode child = null; if (entry.NodeType == NodeType.Directory) { child = this.ResolveDirectory(entry.Name); } else { child = this.ResolveFile(entry.Name); } var attributes = (NetworkNodeAndFileAttributes)child.Attributes; newAttributes.Clear(); foreach (var attribute in entry.ReadAttributes()) { newAttributes[attribute.Key] = attribute.Value; } try { lock (attributes.SyncLock) { toRemove.Clear(); foreach (var attribute in newAttributes) { attributes.SetValue <object>(attribute.Key, attribute.Value); } foreach (var name in attributes.Names) { if (!newAttributes.ContainsKey(name)) { toRemove.Add(name); } } foreach (var name in toRemove) { attributes.SetValue <object>(name, null); } attributes.SetValue <bool>("exists", true); } newChildren.Add(child.Name, child); } catch (Exception) { Debugger.Break(); } if ((nodeType.Equals(NodeType.Any) || child.NodeType.Equals(nodeType)) && (skipAcceptNode || acceptNode(child))) { yield return(child); } } } if (regex == null) { listedAllChildren = true; } } } finally { lock (this.SyncLock) { if (listedAllChildren) { toRemove.Clear(); foreach (var node in this.children.Values) { if (!newChildren.ContainsKey(node.Name)) { ((NetworkNodeAndFileAttributes)node.Attributes).Clear(); ((NetworkNodeAndFileAttributes)node.Attributes).SetValue <bool>("exists", false); toRemove.Add(node.Name); } } foreach (var name in toRemove) { this.children.Remove(name); } if (this.directoryRefreshInfo.Right == refreshInfo.Right) { this.directoryRefreshInfo.Left = DirectoryRefreshMask.None; } } foreach (var node in newChildren.Values) { this.children[node.Name] = node; } } toRemove.Clear(); } yield break; } else { var retvals = new List <INode>(); // Copy the children because we want to yield outside the lock lock (this.SyncLock) { foreach (var pair in this.children) { if ((nodeType.Equals(NodeType.Any) || pair.Value.NodeType.Equals(nodeType)) && acceptNode(pair.Value)) { retvals.Add(pair.Value); } } } foreach (var node in retvals) { yield return(node); } } }