Inheritance: IFormattable, IWriteable
Exemplo n.º 1
0
 // ReSharper disable once CodeAnnotationAnalyzer
 internal void AppendChunk([NotNull] FormatChunk chunk)
 {
     if (ChildrenInternal == null)
     {
         ChildrenInternal = new List <FormatChunk>();
     }
     ChildrenInternal.Add(chunk);
 }
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>A <see cref="Resolution" />.</returns>
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     // ReSharper disable once PossibleNullReferenceException
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "verbose":
             return VerboseFormat;
         case "reversed":
             return ReversedFormat;
         case "key":
             return Key;
         case "value":
             return Value;
         case "position":
             return new Resolution(context.Position, true);
         case "!fill":
             int length = Math.Min(
                 120,
                 context.Layout.Width.Value - context.Layout.FirstLineIndentSize.Value);
             char c = !string.IsNullOrEmpty(chunk.Format) ? chunk.Format[0] : '-';
             StringBuilder fill = new StringBuilder(length + context.Position < 1 ? 2 : 4);
             if (context.Position > 0) fill.AppendLine();
             fill.AppendLine(new string(c, length));
             // Note we have to replace control chunk with value chunk to write it out.
             return new Resolution(new FormatChunk(fill.ToString()), true);
         case "nest":
             string k;
             string v;
             if (string.IsNullOrWhiteSpace(chunk.Format))
             {
                 k = "UnspecKey";
                 v = "UnspecValue";
             }
             else
             {
                 string[] split = chunk.Format.Split(new[] { ',' }, 2, StringSplitOptions.RemoveEmptyEntries);
                 if (split.Length < 1)
                 {
                     k = "UnspecKey";
                     v = "UnspecValue";
                 }
                 else if (split.Length < 2)
                 {
                     k = split[0];
                     v = "UnspecValue";
                 }
                 else
                 {
                     k = split[0];
                     v = split[1];
                 }
             }
             return new RWTest(k, v);
         default:
             return Resolution.Unknown;
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Resolves the specified tag.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="chunk">The chunk.</param>
        /// <returns>A <see cref="Resolution" />.</returns>
        // ReSharper disable once CodeAnnotationAnalyzer
        public override object Resolve(FormatWriteContext context, FormatChunk chunk)
        {
            TValue value;

            // ReSharper disable once AssignNullToNotNullAttribute
            return(_values.TryGetValue(chunk.Tag, out value)
                ? value
                : Resolution.Unknown);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Resolves the specified tag.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="chunk">The chunk.</param>
        /// <returns>A <see cref="Resolution" />.</returns>
        // ReSharper disable once CodeAnnotationAnalyzer
        public override object Resolve(FormatWriteContext context, FormatChunk chunk)
        {
            int index;

            return(int.TryParse(chunk.Tag, out index) &&
                   index >= 0 &&
                   index < _values.Count
                ? _values[index]
                : Resolution.Unknown);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Performs a deep copy of the child chunks from <paramref name="source"/> to <paramref name="destination"/>.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="destination">The destination.</param>
        internal static void DeepCopyChunks([NotNull] FormatChunk source, [NotNull] FormatChunk destination)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }

            if (source.ChildrenInternal != null &&
                source.ChildrenInternal.Count > 0)
            {
                Stack <FormatChunk, IEnumerable <FormatChunk> > stack = new Stack <FormatChunk, IEnumerable <FormatChunk> >();
                stack.Push(destination, source.ChildrenInternal.ToArray());

                while (stack.Count > 0)
                {
                    FormatChunk currParent;
                    IEnumerable <FormatChunk> chunks;
                    stack.Pop(out currParent, out chunks);

                    Debug.Assert(currParent != null);
                    Debug.Assert(chunks != null);

                    // ReSharper disable once PossibleNullReferenceException
                    currParent.ChildrenInternal = new List <FormatChunk>();

                    // Adds each chunk to the current parent
                    // ReSharper disable once PossibleNullReferenceException
                    foreach (FormatChunk child in chunks)
                    {
                        Debug.Assert(child != null);
                        FormatChunk newChunk = new FormatChunk(
                            child.Resolver,
                            child.Tag,
                            child.Alignment,
                            child.Format,
                            child.IsResolved,
                            child.Value,
                            child.IsControl);

                        currParent.ChildrenInternal.Add(newChunk);

                        // If the chunk has any children they need to be added to the new chunk
                        if (child.ChildrenInternal != null &&
                            child.ChildrenInternal.Count >= 1)
                        {
                            stack.Push(newChunk, child.ChildrenInternal);
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        public static IEnumerable <FormatChunk> Parse([NotNull] string value, [CanBeNull] IResolvable resolver = null)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            FormatChunk fc = new FormatChunk();

            fc.Append(
                value,
                resolver);
            return(fc.Children);
        }
            /// <summary>
            /// Resolves the specified tag.
            /// </summary>
            /// <param name="context">The context.</param>
            /// <param name="chunk">The chunk.</param>
            /// <returns>A <see cref="Resolution" />.</returns>
            // ReSharper disable once CodeAnnotationAnalyzer
            public override object Resolve(FormatWriteContext context, FormatChunk chunk)
            {
                Resolution resolution;
                // ReSharper disable once PossibleNullReferenceException
                string tag = chunk.Tag;

                Debug.Assert(tag != null);

                if (ResolveControls || !chunk.IsControl)
                {
                    if ((_values == null || !_values.TryGetValue(tag, out resolution)))
                    {
                        // Get the resolution using the resolver.
                        object result = _resolver(context, chunk);
                        resolution = result as Resolution? ?? new Resolution(result);

                        if (!resolution.NoCache)
                        {
                            // Cache the resolution.
                            if (_values == null)
                            {
                                _values =
                                    new Dictionary <string, Resolution>(
                                        IsCaseSensitive
                                            ? StringComparer.CurrentCulture
                                            : StringComparer.CurrentCultureIgnoreCase);
                            }

                            // ReSharper disable once AssignNullToNotNullAttribute
                            _values[tag] = resolution;
                        }
                    }
                }
                else
                {
                    resolution = (Resolution)Resolution.Unknown;
                }

                // If we don't have a resolution, ask the parent.
                if (!resolution.IsResolved &&
                    ResolveOuterTags &&
                    Parent != null)
                {
                    // ReSharper disable once PossibleNullReferenceException
                    resolution = (Resolution)Parent.Resolve(context, chunk);
                }
                return(resolution);
            }
Exemplo n.º 8
0
        /// <summary>
        /// Creates a clone of the <see cref="FormatChunk" />, changing the resolved value.
        /// </summary>
        /// <param name="chunk">The chunk.</param>
        /// <param name="value">The value.</param>
        public FormatChunk([NotNull] FormatChunk chunk, Optional <object> value)
        {
            if (chunk == null)
            {
                throw new ArgumentNullException("chunk");
            }

            Resolver  = chunk.Resolver;
            Tag       = chunk.Tag;
            IsControl = chunk.IsControl;
            Alignment = chunk.Alignment;
            Format    = chunk.Format;

            DeepCopyChunks(chunk, this);

            if (!value.IsAssigned)
            {
                return;
            }

            IsResolved = true;
            Value      = value.Value;
        }
Exemplo n.º 9
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
 // ReSharper disable once CodeAnnotationAnalyzer
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     // ReSharper disable once PossibleNullReferenceException
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "name":
             return Name;
         case "value":
             return Value;
         default:
             return Resolution.Unknown;
     }
 }
Exemplo n.º 10
0
        /// <summary>
        /// Resolves the specified tag.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="chunk">The chunk.</param>
        /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
        // ReSharper disable once CodeAnnotationAnalyzer
        public override object Resolve(FormatWriteContext context, FormatChunk chunk)
        {
            if (chunk.Tag == null) throw new ArgumentException();

            switch (chunk.Tag.ToLowerInvariant())
            {
                case "isvalid":
                    return IsValid ? Resolution.Empty : Resolution.Null;
                case "guid":
                    return Guid;
                case "host":
                    return Host;
                case "name":
                    return Name;
                case "fullname":
                    return FullName;
                case "pipe":
                    return Pipe;
                default:
                    return Resolution.Unknown;
            }
        }
Exemplo n.º 11
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>
 /// An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.
 /// </returns>
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     Debug.Assert(chunk.Tag != null);
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "name":
             return Name;
         case "altnames":
             return _names.Length > 1
                 ? _names.Skip(1)
                 : Resolution.Null;
         case "description":
             return Description;
         case "parameters":
             object[] parameters = ArgumentParameters.Select(ResolveParameter).ToArray();
             return parameters.Length > 0 ? parameters : Resolution.Null;
         default:
             return Resolution.Unknown;
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Resolves the specified tag.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="chunk">The chunk.</param>
        /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
        // ReSharper disable once CodeAnnotationAnalyzer
        public override object Resolve(FormatWriteContext context, FormatChunk chunk)
        {
            CultureInfo culture = context.FormatProvider as CultureInfo ?? Translation.DefaultCulture;
            // ReSharper disable once PossibleNullReferenceException
            switch (chunk.Tag.ToLowerInvariant())
            {
                /*
                 * Standard named formats.
                 */
                case "default":
                case "verbose":
                    return VerboseFormat;
                case "short":
                    return ShortFormat;
                case "all":
                    return AllFormat;
                case "json":
                    return JSONFormat;
                case "xml":
                    return XMLFormat;

                /* 
                 * Control Tags.
                 */
                case FormatBuilder.ForegroundColorTag:
                case FormatBuilder.BackgroundColorTag:
                    // Replace the LogLevel colour with this colour.
                    return string.Equals(
                        chunk.Format,
                        LogLevelColorName,
                        StringComparison.InvariantCultureIgnoreCase)
                        // Don't cache the response as it is format dependant.
                        ? new Resolution(_level.ToColor(), true)
                        : Resolution.UnknownYet;

                /*
                 * Log element completion.
                 */
                case FormatTagHeader:
                    // Create a header based on the format pattern.
                    // Get the width of the writer, for creating headers.
                    int width = Math.Min(256, context.Layout.Width.Value - context.Layout.FirstLineIndentSize.Value);

                    string pattern = chunk.Format;
                    if (string.IsNullOrEmpty(pattern))
                        pattern = "=";

                    bool startNewLine = context.Position > 0;
                    char[] header = new char[width + (startNewLine ? 2 : 1)];
                    int c = 0;
                    if (startNewLine)
                        header[c++] = '\r'; // Formatter normalizes '\r' to newline automatically.
                    for (int p = 0; p < width; p++)
                        header[c++] = pattern[p % pattern.Length];
                    header[c] = '\r';

                    // We have to replace the original chunk with a non-control chunk for it to to be output.
                    // Set NoCache to true to support format changes.
                    return new Resolution(new FormatChunk(new string(header)), true);

                case FormatTagMessage:
                    return new LogElement(
                        () => Resources.LogKeys_Message,
                        GetMessage(culture));

                case FormatTagResource:
                    return string.IsNullOrWhiteSpace(_resourceProperty)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_Resource,
                            _resourceProperty);

                case FormatTagCulture:
                    return new LogElement(
                        () => Resources.LogKeys_Culture,
                        culture);

                case FormatTagTimeStamp:
                    return new LogElement(
                        () => Resources.LogKeys_TimeStamp,
                        ((CombGuid)_guid).Created);

                case FormatTagLevel:
                    return new LogElement(
                        () => Resources.LogKeys_Level,
                        _level);

                case FormatTagGuid:
                    return new LogElement(
                        () => Resources.LogKeys_Guid,
                        _guid);

                case FormatTagException:
                    return string.IsNullOrWhiteSpace(_exceptionType)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_Exception,
                            _exceptionType);

                case FormatTagThreadID:
                    return _threadID < 0
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_ThreadID,
                            _threadID);

                case FormatTagThreadName:
                    return string.IsNullOrWhiteSpace(_threadName)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_ThreadName,
                            _threadName);

                case FormatTagApplicationName:
                    return string.IsNullOrWhiteSpace(ApplicationName)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_ApplicationName,
                            ApplicationName);

                case FormatTagApplicationGuid:
                    return new LogElement(
                        () => Resources.LogKeys_ApplicationGuid,
                        ApplicationGuid);

                case FormatTagInnerException:
                    if ((_innerExceptionGuids == null) ||
                        (_innerExceptionGuids.Length < 1)) return Resolution.Null;
                    return new LogEnumerableElement(
                        () => Resources.LogKeys_InnerException,
                        _innerExceptionGuids.Cast<object>());

                case FormatTagStoredProcedure:
                    // TODO This can be a specialized LogElement!
                    return string.IsNullOrWhiteSpace(_storedProcedure)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_StoredProcedure,
                            _storedProcedure + " at line " + _storedProcedureLine.ToString("D"));

                case FormatTagContext:
                    return (_context == null) ||
                           (_context.Count < 1)
                        ? Resolution.Null
                        : _context;

                case FormatTagStackTrace:
                    return string.IsNullOrWhiteSpace(_stackTrace)
                        ? Resolution.Null
                        : new LogElement(
                            () => Resources.LogKeys_StackTrace,
                            _stackTrace);

                default:
                    return Resolution.Unknown;
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="Resolution" />.</returns>
 public abstract object Resolve(FormatWriteContext context, FormatChunk chunk);
Exemplo n.º 14
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     string key;
     // ReSharper disable once PossibleNullReferenceException
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "default":
         case "verbose":
             return EnumerableElementVerboseFormat;
         case "xml":
             return EnumerableElementXMLFormat;
         case "json":
             return EnumerableElementJSONFormat;
         case "noline":
             return EnumerableElementNoLineFormat;
         case "key":
             key = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(key)
                 ? Resolution.Null
                 : key;
         case "keyxml":
             key = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(key)
                 ? Resolution.Null
                 : key.XmlEscape();
         case "keyxmltag":
             key = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(key)
                 ? Resolution.Null
                 : key.Replace(' ', '_');
         case "value":
             return Values;
         case "valuexml":
             return Values.Select(v => v != null ? v.XmlEscape() : null);
         default:
             return Resolution.Unknown;
     }
 }
Exemplo n.º 15
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="Resolution" />.</returns>
 public abstract object Resolve(FormatWriteContext context, FormatChunk chunk);
            /// <summary>
            /// Resolves the specified tag.
            /// </summary>
            /// <param name="context">The context.</param>
            /// <param name="chunk">The chunk.</param>
            /// <returns>A <see cref="Resolution" />.</returns>
            // ReSharper disable once CodeAnnotationAnalyzer
            public override object Resolve(FormatWriteContext context, FormatChunk chunk)
            {
                Resolution resolution;
                // ReSharper disable once PossibleNullReferenceException
                string tag = chunk.Tag;
                Debug.Assert(tag != null);

                if (ResolveControls || !chunk.IsControl)
                {
                    if ((_values == null || !_values.TryGetValue(tag, out resolution)))
                    {
                        // Get the resolution using the resolver.
                        object result = _resolver(context, chunk);
                        resolution = result as Resolution? ?? new Resolution(result);

                        if (!resolution.NoCache)
                        {
                            // Cache the resolution.
                            if (_values == null)
                                _values =
                                    new Dictionary<string, Resolution>(
                                        IsCaseSensitive
                                            ? StringComparer.CurrentCulture
                                            : StringComparer.CurrentCultureIgnoreCase);

                            // ReSharper disable once AssignNullToNotNullAttribute
                            _values[tag] = resolution;
                        }
                    }
                }
                else
                    resolution = (Resolution)Resolution.Unknown;

                // If we don't have a resolution, ask the parent.
                if (!resolution.IsResolved &&
                    ResolveOuterTags &&
                    Parent != null)
                    // ReSharper disable once PossibleNullReferenceException
                    resolution = (Resolution)Parent.Resolve(context, chunk);
                return resolution;
            }
Exemplo n.º 17
0
        internal FormatChunk Append([NotNull] string value, [CanBeNull] IResolvable resolver = null)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            string tag       = null;
            string alignment = null;
            string format    = null;

            Stack <FormatChunk> chunks  = new Stack <FormatChunk>();
            FormatChunk         chunk   = this;
            StringBuilder       builder = new StringBuilder(value.Length);

            ParserState state = ParserState.Value;

            int i = 0;

            while (i < value.Length)
            {
                char c = value[i++];

                // Un-escape
                if (c == '\\' &&
                    (i < value.Length))
                {
                    builder.Append(value[i++]);
                    continue;
                }

                bool gotFillPoint = false;
                switch (state)
                {
                case ParserState.Tag:
                    switch (c)
                    {
                    case FormatBuilder.AlignmentChar:
                        state = ParserState.Alignment;
                        break;

                    case FormatBuilder.FormatChar:
                        state = ParserState.Format;
                        break;

                    case FormatBuilder.CloseChar:
                        state        = ParserState.Value;
                        gotFillPoint = true;
                        break;

                    default:
                        builder.Append(c);
                        break;
                    }
                    if (state != ParserState.Tag)
                    {
                        // We've got a tag
                        tag = builder.ToString();
                        builder.Clear();
                    }
                    break;

                case ParserState.Alignment:
                    switch (c)
                    {
                    case FormatBuilder.FormatChar:
                        state = ParserState.Format;
                        break;

                    case FormatBuilder.CloseChar:
                        state        = ParserState.Value;
                        gotFillPoint = true;
                        break;

                    default:
                        builder.Append(c);
                        break;
                    }
                    if (state != ParserState.Alignment)
                    {
                        // We've got an alignment
                        alignment = builder.ToString();
                        builder.Clear();
                    }
                    break;

                case ParserState.Format:
                    switch (c)
                    {
                    case FormatBuilder.OpenChar:
                        if (i >= value.Length || value[i] == FormatBuilder.OpenChar)
                        {
                            builder.Append(FormatBuilder.OpenChar);
                            i++;
                            break;
                        }

                        // We have a nested format!
                        Debug.Assert(tag != null);
                        FormatChunk newChunk = new FormatChunk(
                            chunks.Count < 1 ? resolver : null,
                            tag,
                            alignment,
                            null);
                        tag       = null;
                        alignment = null;
                        if (builder.Length > 0)
                        {
                            Debug.Assert(newChunk.ChildrenInternal == null);
                            newChunk.AppendChunk(new FormatChunk(builder.ToString()));
                            builder.Clear();
                        }
                        chunk.AppendChunk(newChunk);
                        chunks.Push(chunk);
                        chunk = newChunk;
                        state = ParserState.Tag;
                        break;

                    case FormatBuilder.CloseChar:
                        state        = ParserState.Value;
                        gotFillPoint = true;
                        format       = builder.ToString();
                        builder.Clear();
                        break;

                    default:
                        builder.Append(c);
                        break;
                    }
                    break;

                default:
                    switch (c)
                    {
                    case FormatBuilder.OpenChar:
                        if (i >= value.Length || value[i] == FormatBuilder.OpenChar)
                        {
                            builder.Append(FormatBuilder.OpenChar);
                            i++;
                            break;
                        }

                        state = ParserState.Tag;
                        // We've got a value
                        if (builder.Length > 0)
                        {
                            chunk.AppendChunk(new FormatChunk(builder.ToString()));
                            builder.Clear();
                        }
                        break;

                    case FormatBuilder.CloseChar:
                        state = ParserState.Value;
                        if (chunks.Count > 0)
                        {
                            // Closing a nest fill point.
                            if (builder.Length > 0)
                            {
                                chunk.AppendChunk(new FormatChunk(builder.ToString()));
                                builder.Clear();
                            }
                            chunk = chunks.Pop();
                            Debug.Assert(chunk != null);
                        }
                        else
                        {
                            builder.Append(c);
                        }
                        break;

                    default:
                        builder.Append(c);
                        break;
                    }
                    break;
                }

                if (gotFillPoint)
                {
                    Debug.Assert(tag != null);
                    FormatChunk newChunk = new FormatChunk(
                        chunks.Count < 1 ? resolver : null,
                        tag,
                        alignment,
                        format);
                    chunk.AppendChunk(newChunk);
                    tag       = null;
                    alignment = null;
                    format    = null;
                }
            }

            if (builder.Length <= 0)
            {
                return(this);
            }

            // We have some left overs
            string v = builder.ToString();

            builder.Clear();

            if (tag != null)
            {
                builder.Append(FormatBuilder.OpenChar).Append(tag);
            }
            if (alignment != null)
            {
                builder.Append(FormatBuilder.AlignmentChar).Append(alignment);
            }
            if (builder.Length < 1)
            {
                chunk.AppendChunk(new FormatChunk(v));
            }
            else
            {
                builder.Append(FormatBuilder.FormatChar).Append(v);
                chunk.AppendChunk(new FormatChunk(builder.ToString()));
            }
            return(this);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>A <see cref="Resolution" />.</returns>
 // ReSharper disable once CodeAnnotationAnalyzer
 public override object Resolve(FormatWriteContext context, FormatChunk chunk) => _resolver(context, chunk);
Exemplo n.º 19
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>A <see cref="Resolution" />.</returns>
 // ReSharper disable once CodeAnnotationAnalyzer
 public override object Resolve(FormatWriteContext context, FormatChunk chunk) => _resolver(context, chunk);
Exemplo n.º 20
0
        internal FormatChunk Append([NotNull] string value, [CanBeNull] IResolvable resolver = null)
        {
            if (value == null) throw new ArgumentNullException("value");

            string tag = null;
            string alignment = null;
            string format = null;

            Stack<FormatChunk> chunks = new Stack<FormatChunk>();
            FormatChunk chunk = this;
            StringBuilder builder = new StringBuilder(value.Length);

            ParserState state = ParserState.Value;

            int i = 0;
            while (i < value.Length)
            {
                char c = value[i++];

                // Un-escape
                if (c == '\\' &&
                    (i < value.Length))
                {
                    builder.Append(value[i++]);
                    continue;
                }

                bool gotFillPoint = false;
                switch (state)
                {
                    case ParserState.Tag:
                        switch (c)
                        {
                            case FormatBuilder.AlignmentChar:
                                state = ParserState.Alignment;
                                break;
                            case FormatBuilder.FormatChar:
                                state = ParserState.Format;
                                break;
                            case FormatBuilder.CloseChar:
                                state = ParserState.Value;
                                gotFillPoint = true;
                                break;
                            default:
                                builder.Append(c);
                                break;
                        }
                        if (state != ParserState.Tag)
                        {
                            // We've got a tag
                            tag = builder.ToString();
                            builder.Clear();
                        }
                        break;

                    case ParserState.Alignment:
                        switch (c)
                        {
                            case FormatBuilder.FormatChar:
                                state = ParserState.Format;
                                break;
                            case FormatBuilder.CloseChar:
                                state = ParserState.Value;
                                gotFillPoint = true;
                                break;
                            default:
                                builder.Append(c);
                                break;
                        }
                        if (state != ParserState.Alignment)
                        {
                            // We've got an alignment
                            alignment = builder.ToString();
                            builder.Clear();
                        }
                        break;

                    case ParserState.Format:
                        switch (c)
                        {
                            case FormatBuilder.OpenChar:
                                // We have a nested format!
                                Debug.Assert(tag != null);
                                FormatChunk newChunk = new FormatChunk(
                                    chunks.Count < 1 ? resolver : null,
                                    tag,
                                    alignment,
                                    null);
                                tag = null;
                                alignment = null;
                                if (builder.Length > 0)
                                {
                                    Debug.Assert(newChunk.ChildrenInternal == null);
                                    newChunk.AppendChunk(new FormatChunk(builder.ToString()));
                                    builder.Clear();
                                }
                                chunk.AppendChunk(newChunk);
                                chunks.Push(chunk);
                                chunk = newChunk;
                                state = ParserState.Tag;
                                break;
                            case FormatBuilder.CloseChar:
                                state = ParserState.Value;
                                gotFillPoint = true;
                                format = builder.ToString();
                                builder.Clear();
                                break;
                            default:
                                builder.Append(c);
                                break;
                        }
                        break;

                    default:
                        switch (c)
                        {
                            case FormatBuilder.OpenChar:
                                state = ParserState.Tag;
                                // We've got a value
                                if (builder.Length > 0)
                                {
                                    chunk.AppendChunk(new FormatChunk(builder.ToString()));
                                    builder.Clear();
                                }
                                break;
                            case FormatBuilder.CloseChar:
                                state = ParserState.Value;
                                if (chunks.Count > 0)
                                {
                                    // Closing a nest fill point.
                                    if (builder.Length > 0)
                                    {
                                        chunk.AppendChunk(new FormatChunk(builder.ToString()));
                                        builder.Clear();
                                    }
                                    chunk = chunks.Pop();
                                    Debug.Assert(chunk != null);
                                }
                                else
                                    builder.Append(c);
                                break;
                            default:
                                builder.Append(c);
                                break;
                        }
                        break;
                }

                if (gotFillPoint)
                {
                    Debug.Assert(tag != null);
                    FormatChunk newChunk = new FormatChunk(
                        chunks.Count < 1 ? resolver : null,
                        tag,
                        alignment,
                        format);
                    chunk.AppendChunk(newChunk);
                    tag = null;
                    alignment = null;
                    format = null;
                }
            }

            if (builder.Length <= 0) return this;

            // We have some left overs
            string v = builder.ToString();
            builder.Clear();

            if (tag != null)
                builder.Append(FormatBuilder.OpenChar).Append(tag);
            if (alignment != null)
                builder.Append(FormatBuilder.AlignmentChar).Append(alignment);
            if (builder.Length < 1)
                chunk.AppendChunk(new FormatChunk(v));
            else
            {
                builder.Append(FormatBuilder.FormatChar).Append(v);
                chunk.AppendChunk(new FormatChunk(builder.ToString()));
            }
            return this;
        }
Exemplo n.º 21
0
        public static IEnumerable<FormatChunk> Parse([NotNull] string value, [CanBeNull] IResolvable resolver = null)
        {
            if (value == null) throw new ArgumentNullException("value");

            FormatChunk fc = new FormatChunk();
            fc.Append(
                value,
                resolver);
            return fc.Children;
        }
Exemplo n.º 22
0
        /// <summary>
        /// Performs a deep copy of the child chunks from <paramref name="source"/> to <paramref name="destination"/>.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="destination">The destination.</param>
        internal static void DeepCopyChunks([NotNull] FormatChunk source, [NotNull] FormatChunk destination)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (destination == null) throw new ArgumentNullException("destination");

            if (source.ChildrenInternal != null &&
                source.ChildrenInternal.Count > 0)
            {
                Stack<FormatChunk, IEnumerable<FormatChunk>> stack = new Stack<FormatChunk, IEnumerable<FormatChunk>>();
                stack.Push(destination, source.ChildrenInternal.ToArray());

                while (stack.Count > 0)
                {
                    FormatChunk currParent;
                    IEnumerable<FormatChunk> chunks;
                    stack.Pop(out currParent, out chunks);

                    Debug.Assert(currParent != null);
                    Debug.Assert(chunks != null);

                    // ReSharper disable once PossibleNullReferenceException
                    currParent.ChildrenInternal = new List<FormatChunk>();

                    // Adds each chunk to the current parent
                    // ReSharper disable once PossibleNullReferenceException
                    foreach (FormatChunk child in chunks)
                    {
                        Debug.Assert(child != null);
                        FormatChunk newChunk = new FormatChunk(
                            child.Resolver,
                            child.Tag,
                            child.Alignment,
                            child.Format,
                            child.IsResolved,
                            child.Value,
                            child.IsControl);

                        currParent.ChildrenInternal.Add(newChunk);

                        // If the chunk has any children they need to be added to the new chunk
                        if (child.ChildrenInternal != null &&
                            child.ChildrenInternal.Count >= 1)
                            stack.Push(newChunk, child.ChildrenInternal);
                    }
                }
            }
        }
Exemplo n.º 23
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
 // ReSharper disable once CodeAnnotationAnalyzer
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     // ReSharper disable once PossibleNullReferenceException
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "default":
         case "verbose":
             return ElementVerboseFormat;
         case "xml":
             return ElementXMLFormat;
         case "json":
             return ElementJSONFormat;
         case "noline":
             return ElementNoLineFormat;
         case "key":
             return Key;
         case "keyxml":
             return Key.XmlEscape();
         case "keyxmltag":
             return Key.Replace(' ', '_');
         case "value":
             return Value;
         case "valuexml":
             return Value.XmlEscape();
         case "valuejson":
             return Value == null ? "null" : Value.ToJSON();
         default:
             return Resolution.Unknown;
     }
 }
Exemplo n.º 24
0
 /// <summary>
 /// Resolves the specified tag.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="chunk">The chunk.</param>
 /// <returns>An object that will be cached unless it is a <see cref="T:WebApplications.Utilities.Formatting.Resolution" />.</returns>
 // ReSharper disable once CodeAnnotationAnalyzer
 public override object Resolve(FormatWriteContext context, FormatChunk chunk)
 {
     // ReSharper disable once PossibleNullReferenceException
     switch (chunk.Tag.ToLowerInvariant())
     {
         case "default":
         case "verbose":
             return ElementVerboseFormat;
         case "xml":
             return ElementXMLFormat;
         case "json":
             return ElementJSONFormat;
         case "jsonfirst":
             return ElementJSONFirstFormat;
         case "noline":
             return ElementNoLineFormat;
         case "key":
             string key = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(key)
                 ? Resolution.Null
                 : key;
         case "keyxml":
             string keyXml = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(keyXml)
                 ? Resolution.Null
                 : keyXml.XmlEscape();
         case "keyxmltag":
             string keyXmlTag = Translation.GetResource(
                 Resource,
                 context.FormatProvider as CultureInfo ?? Translation.DefaultCulture);
             return string.IsNullOrEmpty(keyXmlTag)
                 ? Resolution.Null
                 : keyXmlTag.Replace(' ', '_');
         case "value":
             return Value;
         case "valuexml":
             return Value == null ? Resolution.Null : Value.XmlEscape();
         case "valuejson":
             return Value == null ? "null" : Value.ToString().ToJSON();
         default:
             return Resolution.Unknown;
     }
 }