AppendChunk() private method

private AppendChunk ( [ chunk ) : void
chunk [
return void
Exemplo n.º 1
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.º 2
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;
        }