internal void Add(int pos, int length)
        {
            if (boundaries == null)
            {
                boundaries = new StringSection[8];
            }
            else if (boundaries.Length == count)
            {
                var b = new StringSection[boundaries.Length * 2];

                boundaries.AsSpan().CopyTo(b);
                boundaries = b;
            }
            boundaries[count] = new StringSection(pos, length);
            count++;
        }
Exemple #2
0
        public Utf8SpanArray ReadLine()
        {
            if (reader.IsCompleted)
            {
                return(default(Utf8SpanArray));
            }
            var originalLine = new Utf8SpanWithIndex(reader.ReadLine(), 0);

            if (originalLine.IsEmpty)
            {
                return(default(Utf8SpanArray));
            }
            var line           = originalLine;
            var scratchpadUsed = 0;

            if (scratchpad.Length < line.Length)
            {
                scratchpad = new byte[Math.Min(line.Length, scratchpad.Length * 2)];
            }
            Utf8Span data2 = Utf8Span.Empty;
            var      num   = 0;

            while (true)
            {
                var idx = line.Span.IndexOfRaw(Separator);
                var val = idx == -1 ? line : line.SubstringRaw(0, idx);

                if (!val.IsEmpty && val.Span.CharAt(0) == (byte)'"')
                {
                    val = line.SubstringRaw(1);
                    var mustUnescapeQuotes = false;
                    int quotidx            = 0;
                    while (true)
                    {
                        var k = val.Span.Bytes.Slice(quotidx).IndexOf((byte)'"');
                        if (quotidx == -1)
                        {
                            throw new InvalidDataException();
                        }
                        quotidx += k;
                        if (quotidx + 1 < val.Length)
                        {
                            if (val.Span.CharAt(quotidx + 1) == (byte)'"')
                            {
                                quotidx           += 2;
                                mustUnescapeQuotes = true;
                                continue;
                            }
                        }
                        line = val.SubstringRaw(quotidx + 2);
                        val  = val.SubstringRaw(0, quotidx);
                        break;
                    }
                    if (mustUnescapeQuotes)
                    {
                        var len = 0;
                        var p   = scratchpad.Slice(scratchpadUsed);
                        while (true)
                        {
                            var pos = val.Span.IndexOfRaw((byte)'"');
                            if (pos == -1)
                            {
                                break;
                            }
                            val.SubstringRaw(0, pos).Span.Bytes.CopyTo(p.Slice(len));
                            val    = val.SubstringRaw(pos + 2);
                            len   += pos;
                            p[len] = (byte)'"';
                            len++;
                        }
                        val.Span.Bytes.CopyTo(p.Slice(len));
                        len            += val.Length;
                        arr[num]        = new StringSection(scratchpadUsed, -len);
                        scratchpadUsed += len;
                    }
                    else
                    {
                        arr[num] = new StringSection(val.Index, val.Length);
                    }
                }
                else
                {
                    line     = line.SubstringRaw(idx + 1);
                    arr[num] = new StringSection(val.Index, val.Length);
                }

                if (arr.Length == num)
                {
                    Array.Resize(ref arr, arr.Length * 2);
                }
                num++;
                if (idx == -1)
                {
                    break;
                }
            }

            Utf8SpanArray result = default(Utf8SpanArray);

            result.count      = num;
            result.data1      = originalLine.Span;
            result.data2      = new Utf8Span(scratchpad);
            result.boundaries = arr;
            return(result);
        }