Пример #1
0
        private static TagParserResult ParseTag(string tag, bool throwException)
        {
            var result = new TagParserResult();

            using (var buffer = MemoryPool <char> .Shared.Rent(tag.Length))
            {
                var input = buffer.Memory.Slice(0, tag.Length).Span;
                tag.AsSpan().ToLowerInvariant(input);
                var indexStart           = 0;
                var state                = TagParserState.Area;
                ReadOnlySpan <char> type = null;

                for (var i = 0; i < input.Length; i++)
                {
                    if (input[i] != '.' && input[i] != ',')
                    {
                        continue;
                    }
                    Parse(tag, ref result, ref indexStart, ref state, ref type, input.Slice(indexStart, i - indexStart), i, throwException);
                }
                Parse(tag, ref result, ref indexStart, ref state, ref type, input.Slice(indexStart), input.Length - 1, throwException);


                state = TagParserState.TypeValidation;
                Parse(tag, ref result, ref indexStart, ref state, ref type, input, input.Length - 1, throwException);

                if (state == TagParserState.Success)
                {
                    result.ErrorState = TagParserState.Success;
                }
            }

            return(result);
        }
Пример #2
0
 private static void Parse(string tag, ref TagParserResult result, ref int indexStart, ref TagParserState state, ref ReadOnlySpan <char> type, ReadOnlySpan <char> data, int index, bool throwException = false)
 {
     if (!TryExtractData(ref result, data, ref indexStart, ref state, ref type, index) && throwException)
     {
         result.ErrorState = state;
         ThrowHelper.ThrowTagParseException(TagParserState.Area, data.ToString(), tag);
     }
 }
Пример #3
0
 // DB1.80000,x,1
 public static bool TryParseTag(string tag, out TagParserResult result)
 {
     result = ParseTag(tag, false);
     return(result.ErrorState == TagParserState.Success);
 }
Пример #4
0
        private static bool TryExtractData(ref TagParserResult result, ReadOnlySpan <char> input, ref int indexStart, ref TagParserState state, ref ReadOnlySpan <char> type, int i)
        {
            switch (state)
            {
            case TagParserState.Area:
            {
                if (TryDetectArea(input, out var selector, out var db))
                {
                    result.Area     = selector;
                    result.DbNumber = db;
                    indexStart      = i + 1;
                    state           = TagParserState.Offset;
                    return(true);
                }
            }
            break;

            case TagParserState.Offset:
            {
                // TODO:  !!!!!!!
#if SPANSUPPORT
                if (int.TryParse(input, out var offset))
#else
                if (TryConvertSpanToInt32(input, out var offset))
#endif

                {
                    result.Offset = offset;
                    indexStart    = i + 1;
                    state         = TagParserState.Type;
                    return(true);
                }
            }
            break;

            case TagParserState.Type:
            {
                type       = input;
                state      = TagParserState.NumberOfItems;
                indexStart = i + 1;
                return(true);
            }

            case TagParserState.NumberOfItems:
            {
                if (input.IsEmpty)
                {
                    return(true);
                }
                // TODO:  !!!!!!!
#if SPANSUPPORT
                if (ushort.TryParse(input, out var length))
#else
                if (TryConvertSpanToUShort(input, out var length))
#endif
                {
                    result.Length = length;
                    state         = TagParserState.TypeValidation;
                    return(true);
                }
            }
            break;

            case TagParserState.TypeValidation:
            {
                if (result.Length <= 0)
                {
                    result.Length = 1;
                }
                var offset = result.Offset;
                var length = result.Length;

                if (!type.IsEmpty && TryDetectTypes(type, ref length, ref offset, out var vtype, out var rType, out var unicode))
                {
                    result.Length     = length;
                    result.Offset     = offset;
                    result.VarType    = vtype;
                    result.ResultType = rType;
                    result.Encoding   = unicode;
                    indexStart        = i + 1;
                    state             = TagParserState.Success;
                    return(true);
                }
            }
            break;

            case TagParserState.Success:
                return(true);
            }
            return(false);
        }