Ejemplo n.º 1
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);
        }
        public static void Split(this Utf8Span this_, byte ch, StringSplitOptions options, ref Utf8SpanArray arr)
        {
            arr.data1 = this_;
            var removeEmpty = (options & StringSplitOptions.RemoveEmptyEntries) != 0;

            var index = 0;
            var pos   = 0;

            arr.count = 0;
            while (true)
            {
                var idx = this_.SubstringRaw(pos).IndexOfRaw(ch);
                if (idx == -1)
                {
                    break;
                }
                else
                {
                    idx += pos;
                }
                var length = idx != -1 ? idx - pos : this_.Length() - pos;
                if (!removeEmpty || length != 0)
                {
                    arr.Add(pos, length);
                    index++;
                }
                pos = idx + 1;
            }
            var last = this_.SubstringRaw(pos);

            if (!removeEmpty || last.Length() != 0)
            {
                arr.Add(pos, last.Length());
            }
        }