/// <summary>
        /// Dispose enumerable and capture errors
        /// </summary>
        /// <param name="disposableObjects">list of disposables</param>
        /// <param name="disposeErrors">list to be created if errors occur</param>
        public static void DisposeAndCapture(IEnumerable disposableObjects, ref StructList4 <Exception> disposeErrors)
        {
            if (disposableObjects == null)
            {
                return;
            }

            // Dispose disposables
            foreach (object disposableObject in disposableObjects)
            {
                if (disposableObject is IDisposable disposable)
                {
                    try
                    {
                        disposable.Dispose();
                    }
                    catch (AggregateException ae)
                    {
                        foreach (Exception e in ae.InnerExceptions)
                        {
                            disposeErrors.Add(e);
                        }
                    }
                    catch (Exception e)
                    {
                        // Capture error
                        disposeErrors.Add(e);
                    }
                }
            }
        }
 /// <summary>
 /// Dispose enumerable and capture errors
 /// </summary>
 /// <param name="disposableObjects">list of disposables</param>
 /// <param name="disposeErrors">list to be created if errors occur</param>
 public static void DisposeAndCapture(ref StructList2 <IDisposable> disposableObjects, ref StructList4 <Exception> disposeErrors)
 {
     // Dispose disposables
     for (int i = 0; i < disposableObjects.Count; i++)
     {
         IDisposable disposable = disposableObjects[i];
         if (disposable != null)
         {
             try
             {
                 disposable.Dispose();
             }
             catch (AggregateException ae)
             {
                 foreach (Exception e in ae.InnerExceptions)
                 {
                     disposeErrors.Add(e);
                 }
             }
             catch (Exception e)
             {
                 // Capture error
                 disposeErrors.Add(e);
             }
         }
     }
 }
        /// <summary>
        /// If <paramref name="tokenContainer"/> is a single token, then enumerates it.
        /// If <paramref name="tokenContainer"/> is token collection, then enumerates all contained tokens.
        /// If <paramref name="recurse"/> is true, then enumerates tree of collections.
        /// </summary>
        /// <param name="tokenContainer"></param>
        /// <param name="recurse"></param>
        /// <returns>enumerable of tokens</returns>
        public static IEnumerable <IToken> ListTokens(this IOption tokenContainer, bool recurse = true)
        {
            // Is a token
            if (tokenContainer is IToken token)
            {
                // Enumerable
                if (tokenContainer is ITokenEnumerable enumr)
                {
                    // Return enumerable as is
                    if (!recurse)
                    {
                        return(enumr);
                    }

                    // Put into queue
                    StructList4 <IToken> queue = new StructList4 <IToken>();
                    foreach (IToken t in enumr)
                    {
                        queue.Add(t);
                    }
                    StructListSorter <StructList4 <IToken>, IToken> .Reverse(ref queue);

                    StructList4 <IToken> result = new StructList4 <IToken>();
                    while (queue.Count > 0)
                    {
                        int    ix = queue.Count - 1;
                        IToken t  = queue[ix];
                        queue.RemoveAt(ix);

                        if (t is ITokenEnumerable enumr_)
                        {
                            foreach (IToken tt in enumr_)
                            {
                                queue.Add(tt);
                            }
                        }
                        else
                        {
                            result.Add(t);
                        }
                    }
                    return(result.ToArray());
                }
                // Single token
                else
                {
                    return new IToken[] { token }
                };
            }
            else
            {
                // No tokens
                return(no_tokens);
            }
        }
        /// <summary>
        /// Process the actual dispose. This may be called from Dispose() or from the dispose of the last
        /// belate handle (After Dispose() has been called aswell).
        ///
        /// Disposes all attached diposables and call <see cref="InnerDispose(ref StructList4{Exception})"/>.
        ///
        /// Only one thread may process the dispose.
        /// Sets state to 2, and then 3.
        ///
        /// Unattaches all disposables, disposes them, and calls <see cref="InnerDispose(ref StructList4{Exception})"/>.
        /// </summary>
        /// <exception cref="AggregateException">thrown if disposing threw errors</exception>
        protected virtual void ProcessDispose()
        {
            // Set state IsDisposing=2, but let only one thread continue.
            bool thisThreadChangedStateToDispose = (Interlocked.CompareExchange(ref disposing, 2L, 0L) == 0L) || (Interlocked.CompareExchange(ref disposing, 2L, 1L) == 1L);

            // Not for this thread.
            if (!thisThreadChangedStateToDispose)
            {
                return;
            }

            // Extract snapshot, clear array
            StructList2 <IDisposable> toDispose = default;

            lock (m_disposelist_lock) { toDispose = disposeList; disposeList = default; }

            // Captured errors
            StructList4 <Exception> disposeErrors = new StructList4 <Exception>();

            // Dispose disposables
            DisposeAndCapture(ref toDispose, ref disposeErrors);

            // Call InnerDispose(). Capture errors to compose it with others.
            try
            {
                InnerDispose(ref disposeErrors);
            }
            catch (Exception e)
            {
                // Capture error
                disposeErrors.Add(e);
            }

            // Call InnerDisposeUnmanaged(). Capture errors to compose it with others.
            try
            {
                InnerDisposeUnmanaged(ref disposeErrors);
            }
            catch (Exception e)
            {
                // Capture error
                disposeErrors.Add(e);
            }

            // Is disposed
            Interlocked.CompareExchange(ref disposing, 3L, 2L);

            // Throw captured errors
            if (disposeErrors.Count > 0)
            {
                throw new AggregateException(disposeErrors);
            }
        }
        /// <summary>
        /// Query for all token objects at path <paramref name="path"/> as type <paramref name="key"/>.
        /// </summary>
        /// <param name="path">(optional) path to query token at</param>
        /// <param name="key">(optional) key to query with</param>
        /// <param name="tokens">array of tokens, or null if failed to find matching tokens</param>
        /// <returns>true if tokens were found</returns>
        public bool TryGetAllTokens(string path, String key, out object[] tokens)
        {
            StructList4 <object[]> tokenArrays = new StructList4 <object[]>();
            int c = 0;

            foreach (var t in this.tokens)
            {
                object[] array;
                if (t.TryGetAllTokens(path, key, out array))
                {
                    c += array.Length;
                    tokenArrays.Add(array);
                }
            }
            if (tokenArrays.Count == 0)
            {
                tokens = emptyArray; return(false);
            }
            if (tokenArrays.Count == 1)
            {
                tokens = tokenArrays[0]; return(true);
            }
            object[] result = new object[c];
            int      ix     = 0;

            for (int i = 0; i < tokenArrays.Count; i++)
            {
                object[] arr = tokenArrays[i];
                Array.Copy(arr, 0, result, ix, arr.Length);
                ix += arr.Length;
            }
            tokens = result;
            return(true);
        }
        /// <summary>Dispatch <paramref name="events"/></summary>
        /// <param name="events"></param>
        public void DispatchEvents(ref StructList12 <IEvent> events)
        {
            // Errors
            StructList4 <Exception> errors = new StructList4 <Exception>();

            for (int i = 0; i < events.Count; i++)
            {
                IEvent e = events[i];
                try
                {
                    e?.Observer?.Observer?.OnNext(e);
                }
                catch (Exception error)
                {
                    if (errorHandler != null)
                    {
                        errorHandler(this, e, error);
                    }
                    else
                    {
                        errors.Add(error);
                    }
                }
            }
            if (errors.Count > 0)
            {
                throw new AggregateException(errors.ToArray());
            }
        }
Example #7
0
        /// <summary>
        /// Dispose observer
        /// </summary>
        /// <param name="disposeErrors"></param>
        protected override void InnerDispose(ref StructList4 <Exception> disposeErrors)
        {
            var _observer = Observer;

            // Remove watcher from dispose list.
            IFileSystem _filesystem = FileSystem;

            if (_filesystem is IDisposeList _disposelist)
            {
                _disposelist.RemoveDisposable(this);
            }

            // Call OnCompleted
            if (_observer != null)
            {
                Observer = null;
                try
                {
                    _observer.OnCompleted();
                }
                catch (Exception e)
                {
                    disposeErrors.Add(e);
                }
            }
        }
Example #8
0
 /// <summary>
 /// Get all canonical keys as parameterName,parameterValue from tail towards root.
 /// </summary>
 /// <param name="line">line to read keys from</param>
 /// <param name="list">result list to write results to</param>
 /// <param name="parameterInfos">(optional) map of infos for determining if parameter is key</param>
 /// <typeparam name="LIST">List type</typeparam>
 /// <returns>dictionary of keys</returns>
 public static void GetCanonicalKeyPairs <LIST>(this ILine line, ref LIST list, IParameterInfos parameterInfos = null) where LIST : IList <KeyValuePair <string, string> >
 {
     for (ILine l = line; l != null; l = l.GetPreviousPart())
     {
         if (l is ILineParameterEnumerable lineParameters)
         {
             StructList4 <KeyValuePair <string, string> > tmp = new StructList4 <KeyValuePair <string, string> >();
             foreach (var parameter in lineParameters)
             {
                 string name = parameter.ParameterName, value = parameter.ParameterValue;
                 if (parameter.IsCanonicalKey(parameterInfos) && name != null && value != null)
                 {
                     tmp.Add(new KeyValuePair <string, string>(name, value));
                 }
             }
             for (int i = tmp.Count - 1; i >= 0; i--)
             {
                 list.Add(tmp[i]);
             }
         }
         if (l is ILineParameter lineParameter && l.IsCanonicalKey(parameterInfos))
         {
             string name = lineParameter.ParameterName, value = lineParameter.ParameterValue;
             if (lineParameter.IsCanonicalKey(parameterInfos) && name != null && value != null)
             {
                 list.Add(new KeyValuePair <string, string>(name, value));
             }
         }
     }
 }
Example #9
0
 /// <summary>
 /// Get all canonical keys from tail towards root.
 /// </summary>
 /// <param name="line">line to read keys from</param>
 /// <param name="list">result list to write results to</param>
 /// <param name="parameterInfos">(optional) map of infos for determining if parameter is key</param>
 /// <typeparam name="LIST">List type</typeparam>
 /// <returns>dictionary of keys</returns>
 public static void GetCanonicalKeys <LIST>(this ILine line, ref LIST list, IParameterInfos parameterInfos = null) where LIST : IList <ILineParameter>
 {
     for (ILine l = line; l != null; l = l.GetPreviousPart())
     {
         if (l is ILineParameterEnumerable lineParameters)
         {
             StructList4 <ILineParameter> tmp = new StructList4 <ILineParameter>();
             foreach (var parameter in lineParameters)
             {
                 if (parameter.IsCanonicalKey(parameterInfos) && parameter.ParameterName != null && parameter.ParameterValue != null)
                 {
                     tmp.Add(parameter);
                 }
             }
             for (int i = tmp.Count - 1; i >= 0; i--)
             {
                 list.Add(tmp[i]);
             }
         }
         if (l is ILineParameter lineParameter && l.IsCanonicalKey(parameterInfos))
         {
             if (lineParameter.IsCanonicalKey(parameterInfos) && lineParameter.ParameterName != null && lineParameter.ParameterValue != null)
             {
                 list.Add(lineParameter);
             }
         }
     }
 }
Example #10
0
        /// <summary>
        /// Process the non-dispose. Used when <see cref="nonDisposable"/> is true (singleton instances).
        ///
        /// This may be called from <see cref="Dispose"/> or from the dispose of the last
        /// belate handle (After <see cref="Dispose"/> has been called aswell).
        ///
        /// Only one thread may process the dispose. Returns state back to 0.
        ///
        /// Unattaches all disposables, disposes them, and calls <see cref="InnerDispose(ref StructList4{Exception})"/>.
        /// Does not set state
        /// </summary>
        /// <exception cref="AggregateException">thrown if disposing threw errors</exception>
        protected virtual void ProcessNonDispose()
        {
            // Revert state
            Interlocked.CompareExchange(ref disposing, 0L, 1L);

            // Extract snapshot, clear array
            StructList2 <IDisposable> toDispose = default;

            lock (m_disposelist_lock) { toDispose = disposeList; disposeList = default; }

            // Captured errors
            StructList4 <Exception> disposeErrors = new StructList4 <Exception>();

            // Dispose disposables
            DisposeList.DisposeAndCapture(ref toDispose, ref disposeErrors);

            // Call InnerDispose(). Capture errors to compose it with others.
            try
            {
                InnerDispose(ref disposeErrors);
            }
            catch (Exception e)
            {
                // Capture error
                disposeErrors.Add(e);
            }

            // Throw captured errors
            if (disposeErrors.Count > 0)
            {
                throw new AggregateException(disposeErrors);
            }
        }
 /// <summary>Dispose called by finalizer or consumer (on Dispose())</summary>
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         // Cancel source
         CancelSrc.Dispose();
         // Array of observer handles
         var handles = observers.Array;
         // Errors
         StructList4 <Exception> errors = new StructList4 <Exception>();
         foreach (var handle in handles)
         {
             try
             {
                 handle.observer.OnCompleted();
             }
             catch (Exception e)
             {
                 // Add observer exception as error event, but don't dispatch it.
                 Events.TryAdd(new OperationErrorEvent(null, e));
                 // Capture
                 errors.Add(e);
             }
         }
         if (errors.Count > 0)
         {
             throw new AggregateException(errors.ToArray());
         }
     }
 }
        /// <summary>Dispatch <paramref name="events"/></summary>
        /// <param name="events"></param>
        public void DispatchEvents(IEnumerable <IEvent> events)
        {
            // Errors
            StructList4 <Exception> errors = new StructList4 <Exception>();

            if (events != null)
            {
                foreach (IEvent e in events)
                {
                    try
                    {
                        e?.Observer?.Observer?.OnNext(e);
                    }
                    catch (Exception error)
                    {
                        if (errorHandler != null)
                        {
                            errorHandler(this, e, error);
                        }
                        else
                        {
                            errors.Add(error);
                        }
                    }
                }
            }
            if (errors.Count > 0)
            {
                throw new AggregateException(errors.ToArray());
            }
        }
Example #13
0
 /// <summary>
 /// Handle dispose, forwards OnCompleted event.
 /// </summary>
 /// <param name="disposeErrors"></param>
 protected override void InnerDispose(ref StructList4 <Exception> disposeErrors)
 {
     try
     {
         Observer.OnCompleted();
     }
     catch (Exception e)
     {
         disposeErrors.Add(e);
     }
 }
Example #14
0
        /// <summary>
        /// Resolve <paramref name="identifier"/> to <typeparamref name="T"/>.
        /// </summary>
        /// <param name="identifier"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns><typeparamref name="T"/> or null</returns>
        /// <exception cref="ObjectDisposedException">resolver is disposed</exception>
        /// <exception cref="LocalizationException">If resolve fails.</exception>
        public T Resolve <T>(string identifier)
        {
            StructList4 <Exception> errors = new StructList4 <Exception>();

            List <IResolver> list = resolversByType.TryGetList(typeof(T));

            if (list != null)
            {
                foreach (IResolver resolver in list)
                {
                    try
                    {
                        return(((IResolver <T>)resolver).Resolve(identifier));
                    } catch (Exception e)
                    {
                        errors.Add(e);
                    }
                }
            }

            foreach (IGenericResolver genericResolver in genericResolvers)
            {
                try
                {
                    return(genericResolver.Resolve <T>(identifier));
                }
                catch (Exception e)
                {
                    errors.Add(e);
                }
            }

            string msg = $"Failed to resolve {identifier} to {typeof(T).FullName}.";

            if (errors.Count == 0)
            {
                throw new LocalizationException(msg);
            }
            throw new LocalizationException(msg, new AggregateException(errors));
        }
        /// <summary>
        /// Dispose observer
        /// </summary>
        public void Dispose()
        {
            var _watcher  = watcher;
            var _observer = observer;

            StructList4 <Exception> errors = new StructList4 <Exception>();

            if (_observer != null)
            {
                observer = null;
                try
                {
                    _observer.OnCompleted();
                }
                catch (Exception e)
                {
                    errors.Add(e);
                }
            }

            if (_watcher != null)
            {
                watcher = null;
                try
                {
                    _watcher.Dispose();
                }
                catch (Exception e)
                {
                    errors.Add(e);
                }
            }

            if (errors.Count > 0)
            {
                throw new AggregateException(errors);
            }
            fileProvider = null;
        }
        /// <summary>
        /// Create a token that reads <paramref name="tokens"/> into array of tokens.
        /// Removes null values.
        /// </summary>
        /// <param name="tokens"></param>
        public TokenList(IEnumerable <IToken> tokens)
        {
            StructList4 <IToken> list = new StructList4 <IToken>();

            foreach (var t in tokens)
            {
                if (t != null)
                {
                    list.Add(t);
                }
            }
            this.tokens = list.ToArray();
        }
Example #17
0
 /// <summary>
 /// Dispose cache parts and possibly <see cref="Source"/>.
 /// </summary>
 /// <param name="errors"></param>
 protected override void Dispose(ref StructList4 <Exception> errors)
 {
     // Dispose cache parts
     base.Dispose(ref errors);
     try
     {
         // Dispose source
         if (disposeSource)
         {
             Source.Dispose();
         }
     }
     catch (Exception e)
     {
         // Add error
         errors.Add(e);
     }
 }
            /// <summary>
            /// Dispose observer
            /// </summary>
            protected override void InnerDispose(ref StructList4 <Exception> errors)
            {
                base.InnerDispose(ref errors);
                var _watcher = watcher;

                if (_watcher != null)
                {
                    watcher = null;
                    try
                    {
                        _watcher.Dispose();
                    }
                    catch (Exception e)
                    {
                        errors.Add(e);
                    }
                }
            }
 /// <summary>
 /// Dispose
 /// </summary>
 /// <param name="errors"></param>
 protected virtual void Dispose(ref StructList4 <Exception> errors)
 {
     foreach (IDisposable disposable in _getComponents <IDisposable>())
     {
         try
         {
             disposable.Dispose();
         }
         catch (Exception e)
         {
             errors.Add(e);
         }
     }
     lock (m_lock)
     {
         Clear();
         ClearCache();
     }
 }
        /// <summary>Forward events to observers.</summary>
        /// <param name="events">IEnumerable or <see cref="IEvent"/></param>
        protected void processEvents(object events)
        {
            // Errors
            StructList4 <Exception> errors = new StructList4 <Exception>();

            if (events is IEnumerable <IEvent> eventsEnumr)
            {
                foreach (IEvent e in eventsEnumr)
                {
                    try
                    {
                        e?.Observer?.Observer?.OnNext(e);
                    }
                    catch (Exception error)
                    {
                        if (errorHandler != null)
                        {
                            errorHandler(this, e, error);
                        }
                        else
                        {
                            errors.Add(error);
                        }
                    }
                }
                if (errors.Count > 0)
                {
                    throw new AggregateException(errors.ToArray());
                }
            }
            else if (events is IEvent @event)
            {
                try
                {
                    @event.Observer?.Observer?.OnNext(@event);
                }
                catch (Exception error) when(errorHandler != null)
                {
                    errorHandler(this, @event, error);
                }
            }
        }
Example #21
0
            /// <summary>
            /// Write to <see cref="StringBuilder"/> <paramref name="output"/>.
            /// </summary>
            /// <param name="output"></param>
            /// <param name="format">print format</param>
            public void WriteTo(TextWriter output, Format format = Format.Default)
            {
                // Number of info fields printed
                int column = 0;

                // Print tree
                if (format.HasFlag(Format.Tree) && Level > 0)
                {
                    if (column++ > 0)
                    {
                        output.Write(" ");
                    }
                    // Print indents
                    for (int l = 1; l < Level; l++)
                    {
                        output.Write(LevelContinues(l) ? "│  " : "   ");
                    }
                    // Print last indent
                    if (Level >= 1)
                    {
                        output.Write(LevelContinues(Level) ? "├──" : "└──");
                    }
                }
                // Print name
                if (format.HasFlag(Format.Name))
                {
                    if (column++ > 0)
                    {
                        output.Write(" ");
                    }
                    output.Write("\"");
                    output.Write(Entry.Name);
                    output.Write("\"");
                }
                // Print path
                if (format.HasFlag(Format.Path))
                {
                    if (column++ > 0)
                    {
                        output.Write(" ");
                    }
                    output.Write(Entry.Path);
                }

                // [xx, yy, zz]
                StructList4 <string> infos = new StructList4 <string>();

                // Print mountpoint
                if (format.HasFlag(Format.Mount) && Entry.IsMountPoint())
                {
                    FileSystemAssignment[] mounts = Entry.Mounts();
                    if (mounts != null)
                    {
                        for (int i = 0; i < mounts.Length; i++)
                        {
                            FileSystemAssignment info = mounts[i];
                            if (info.FileSystem != null)
                            {
                                string fs = info.FileSystem.ToString();
                                if (!String.IsNullOrEmpty(fs))
                                {
                                    infos.Add(fs);
                                }
                            }
                            if (info.Option != null)
                            {
                                string op = info.Option.ToString();
                                if (!String.IsNullOrEmpty(op))
                                {
                                    infos.Add(op);
                                }
                            }
                        }
                    }
                }

                // Write drive label [Tank]
                if (format.HasFlag(Format.DriveLabel))
                {
                    string label = Entry.DriveLabel();
                    if (!String.IsNullOrEmpty(label))
                    {
                        infos.Add(label);
                    }
                }

                // Append free space [Freespace: 10G]
                if (format.HasFlag(Format.DriveFreespace))
                {
                    long freespace = format.HasFlag(Format.DriveFreespace) ? Entry.DriveFreeSpace() : -1L;
                    if (freespace > 0)
                    {
                        infos.Add("Freespace: " + (freespace >> 30) + "G");
                    }
                }

                // Append total size [Size: 8G/32G]
                if (format.HasFlag(Format.DriveSize))
                {
                    long freespace = format.HasFlag(Format.DriveFreespace) ? Entry.DriveFreeSpace() : -1L;
                    long size      = format.HasFlag(Format.DriveSize) ? Entry.DriveSize() : -1L;
                    long reserved  = freespace < 0L ? -1L : size - freespace;
                    if (reserved > 0 && size > 0)
                    {
                        infos.Add("Size: " + (reserved >> 30) + "G/" + (size >> 30) + "G");
                    }
                    else if (size > 0)
                    {
                        infos.Add("Size: " + (size >> 30) + "G");
                    }
                }

                // Write drive type [Ram]
                if (format.HasFlag(Format.DriveType))
                {
                    DriveType driveType = Entry.DriveType();
                    if (driveType != DriveType.Unknown)
                    {
                        infos.Add(driveType.ToString());
                    }
                }

                // Write drive format [NTFS]
                if (format.HasFlag(Format.DriveFormat))
                {
                    string driveFormat = Entry.DriveFormat();
                    if (!String.IsNullOrEmpty(driveFormat))
                    {
                        infos.Add(driveFormat);
                    }
                }

                // Print file attributes
                if (format.HasFlag(Format.FileAttributes) && Entry.HasFileAttributes())
                {
                    string attribs = Entry.FileAttributes().ToString();
                    if (!string.IsNullOrEmpty(attribs))
                    {
                        infos.Add(attribs);
                    }
                }

                // Print length
                if (format.HasFlag(Format.Length) && Entry.IsFile())
                {
                    long length = Entry.Length();
                    if (length >= 0L)
                    {
                        infos.Add(length.ToString());
                    }
                }

                // Print error
                if (format.HasFlag(Format.Error) && Error != null)
                {
                    if (String.IsNullOrEmpty(Error.Message))
                    {
                        infos.Add(Error.GetType().Name);
                    }
                    else
                    {
                        infos.Add(Error.GetType().Name + ": " + Error.Message);
                    }
                }

                // Print physical path
                if (format.HasFlag(Format.PhysicalPath))
                {
                    string physicalPath = Entry.PhysicalPath();
                    if (!String.IsNullOrEmpty(physicalPath))
                    {
                        infos.Add(physicalPath);
                    }
                }

                // Print colon infos
                if (infos.Count > 0)
                {
                    if (column++ > 0)
                    {
                        output.Write(" ");
                    }
                    output.Write('[');
                    for (int i = 0; i < infos.Count; i++)
                    {
                        if (i > 0)
                        {
                            output.Write(", ");
                        }
                        output.Write(infos[i]);
                    }
                    output.Write(']');
                }
                // Next line
                if (format.HasFlag(Format.LineFeed))
                {
                    output.WriteLine();
                }
            }
Example #22
0
 /// <summary>
 /// Push new <paramref name="rules"/> to the scope.
 /// The last added have higher priority.
 /// </summary>
 /// <param name="rules"></param>
 public void Push(IPluralRules rules)
 => stack.Add(rules);