C# 将ReadOnlySequence拆分为行,然后按分隔符拆分ReadOnlySequence

C# 将ReadOnlySequence拆分为行,然后按分隔符拆分ReadOnlySequence,c#,.net-core,buffer,C#,.net Core,Buffer,我试图通过换行符\n和分隔符(在本例中为“)将以下分块内存拆分为只读序列 我有部分工作(按行)代码,当我调整代码时,下面会出现异常,并且当前有不正确的输出:hello,fun,one using System; using System.Buffers; namespace NotMuchFunYet { class Program { static void Main(string[] args) { var buffe

我试图通过换行符
\n
和分隔符(在本例中为
)将以下分块内存拆分为
只读序列

我有部分工作(按行)代码,当我调整代码时,下面会出现异常,并且当前有不正确的输出:
hello
fun
one

using System;
using System.Buffers;

namespace NotMuchFunYet
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = GetExampleBuffer();

            while (TryReadLine(ref buffer, out var line))
            {
                while (GetString(ref line, out var token))
                {
                    Console.WriteLine(token.ToString());
                }
            }
        }

        private static ReadOnlySequence<char> GetExampleBuffer()
        {
            Chunk<char> startChnk;
            var currentChnk = startChnk = new Chunk<char>(new ReadOnlyMemory<char>("\"hello\".\"mu".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("ch\".".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\"fun\"".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\n\"done\"\n".ToCharArray()));
            return new ReadOnlySequence<char>(startChnk, 0, currentChnk, currentChnk.Memory.Length);
        }

        private static bool TryReadLine(ref ReadOnlySequence<char> buffer, out ReadOnlySequence<char> line)
        {            
            var position = buffer.PositionOf('\n'); // Look for a EOL in the buffer.

            if (position == null)
            {
                line = default;
                return false;
            }

            line = buffer.Slice(0, position.Value); // Skip the line + the \n.
            buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
            return true;
        }

        public static bool GetString(ref ReadOnlySequence<char> line, out ReadOnlySequence<char> property)
        {
            var start = line.PositionOf('"');
            if (start == null)
            {
                property = default;
                return false;
            }

            property = line.Slice(start.Value.GetInteger() + 1);
            
            var end = property.PositionOf('"');
            if (end == null)
            {
                property = default;
                return false;
            }

            property = property.Slice(0, end.Value);
            line = line.Slice(line.GetPosition(1, end.Value));
            return true;
        }
    }

    class Chunk<T> : ReadOnlySequenceSegment<T>
    {
        public Chunk(ReadOnlyMemory<T> memory) => Memory = memory;

        public Chunk<T> Add(ReadOnlyMemory<T> mem)
        {
            var segment = new Chunk<T>(mem) { RunningIndex = RunningIndex + Memory.Length };
            Next = segment;
            return segment;
        }
    }
}
我认为我的问题在于我对
ReadOnlySequence.Slice()
SequencePosition
的使用,因为这似乎与起始序列的位置有关,而不是切片的
ReadOnlySequence
的开始(至少据我所知)

我诚恳地寻求以下更正示例的建议,以便我们获得预期结果:

你好
很多
有趣
完成

using System;
using System.Buffers;

namespace NotMuchFunYet
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = GetExampleBuffer();

            while (TryReadLine(ref buffer, out var line))
            {
                while (GetString(ref line, out var token))
                {
                    Console.WriteLine(token.ToString());
                }
            }
        }

        private static ReadOnlySequence<char> GetExampleBuffer()
        {
            Chunk<char> startChnk;
            var currentChnk = startChnk = new Chunk<char>(new ReadOnlyMemory<char>("\"hello\".\"mu".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("ch\".".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\"fun\"".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\n\"done\"\n".ToCharArray()));
            return new ReadOnlySequence<char>(startChnk, 0, currentChnk, currentChnk.Memory.Length);
        }

        private static bool TryReadLine(ref ReadOnlySequence<char> buffer, out ReadOnlySequence<char> line)
        {            
            var position = buffer.PositionOf('\n'); // Look for a EOL in the buffer.

            if (position == null)
            {
                line = default;
                return false;
            }

            line = buffer.Slice(0, position.Value); // Skip the line + the \n.
            buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
            return true;
        }

        public static bool GetString(ref ReadOnlySequence<char> line, out ReadOnlySequence<char> property)
        {
            var start = line.PositionOf('"');
            if (start == null)
            {
                property = default;
                return false;
            }

            property = line.Slice(start.Value.GetInteger() + 1);
            
            var end = property.PositionOf('"');
            if (end == null)
            {
                property = default;
                return false;
            }

            property = property.Slice(0, end.Value);
            line = line.Slice(line.GetPosition(1, end.Value));
            return true;
        }
    }

    class Chunk<T> : ReadOnlySequenceSegment<T>
    {
        public Chunk(ReadOnlyMemory<T> memory) => Memory = memory;

        public Chunk<T> Add(ReadOnlyMemory<T> mem)
        {
            var segment = new Chunk<T>(mem) { RunningIndex = RunningIndex + Memory.Length };
            Next = segment;
            return segment;
        }
    }
}
使用系统;
使用系统缓冲区;
名称空间还没有结束
{
班级计划
{
静态void Main(字符串[]参数)
{
var buffer=GetExampleBuffer();
while(TryReadLine(参考缓冲区,输出变量行))
{
while(GetString(ref行,out-var标记))
{
Console.WriteLine(token.ToString());
}
}
}
私有静态只读序列GetExampleBuffer()
{
Chunk startChnk;
var currentChnk=startChnk=new Chunk(新的只读内存(“\”hello\“\”mu“.ToCharArray());
currentChnk=currentChnk.Add(新的只读存储器(“ch\”.ToCharArray());
currentChnk=currentChnk.Add(新的只读存储器(“\'fun\”“.ToCharArray());
currentChnk=currentChnk.Add(新只读内存(“\n\”完成“\n”.ToCharArray());
返回新的只读序列(startChnk,0,currentChnk,currentChnk.Memory.Length);
}
专用静态bool TryReadLine(ref ReadOnlySequence缓冲区,out ReadOnlySequence行)
{            
var position=buffer.PositionOf('\n');//在缓冲区中查找EOL。
如果(位置==null)
{
行=默认值;
返回false;
}
line=buffer.Slice(0,position.Value);//跳过该行和\n。
buffer=buffer.Slice(buffer.GetPosition(1,position.Value));
返回true;
}
公共静态bool GetString(ref ReadOnlySequence行,out ReadOnlySequence属性)
{
var start=line.PositionOf(“”);
if(start==null)
{
属性=默认值;
返回false;
}
属性=line.Slice(start.Value.GetInteger()+1);
var end=property.PositionOf(“”);
if(end==null)
{
属性=默认值;
返回false;
}
property=property.Slice(0,end.Value);
line=line.Slice(line.GetPosition(1,end.Value));
返回true;
}
}
类块:ReadOnlySequenceSegment
{
公共块(ReadOnlyMemory)=>内存=内存;
公共块添加(ReadOnlyMemy mem)
{
var segment=newchunk(mem){RunningIndex=RunningIndex+Memory.Length};
下一个=段;
返回段;
}
}
}

GetString()方法中更改第一个属性fetch可从以下内容解决此问题:

property = line.Slice(start.Value.GetInteger() + 1);
致:

给出代码:

using System;
using System.Buffers;

namespace NowMuchFun
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = GetExampleBuffer();

            while (TryReadLine(ref buffer, out var line))
            {
                while (GetString(ref line, out var token))
                {
                    Console.WriteLine(token.ToString());
                }
            }
        }

        private static ReadOnlySequence<char> GetExampleBuffer()
        {
            Chunk<char> startChnk;
            var currentChnk = startChnk = new Chunk<char>(new ReadOnlyMemory<char>("\"hello\".\"mu".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("ch\".".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\"fun\"".ToCharArray()));
            currentChnk = currentChnk.Add(new ReadOnlyMemory<char>("\n\"done\"\n".ToCharArray()));
            return new ReadOnlySequence<char>(startChnk, 0, currentChnk, currentChnk.Memory.Length);
        }

        private static bool TryReadLine(ref ReadOnlySequence<char> buffer, out ReadOnlySequence<char> line)
        {
            var position = buffer.PositionOf('\n'); // Look for a EOL in the buffer.

            if (position == null)
            {
                line = default;
                return false;
            }

            line = buffer.Slice(0, position.Value); // Skip the line + the \n.
            buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
            return true;
        }

        public static bool GetString(ref ReadOnlySequence<char> line, out ReadOnlySequence<char> property)
        {
            var start = line.PositionOf('"');
            if (start == null)
            {
                property = default;
                return false;
            }

            // property = line.Slice(start.Value.GetInteger() + 1);
            // REPLACE WITH BELOW:
            property = line.Slice(line.GetPosition(1, start.Value));

            var end = property.PositionOf('"');
            if (end == null)
            {
                property = default;
                return false;
            }

            property = property.Slice(0, end.Value);
            line = line.Slice(line.GetPosition(1, end.Value));
            return true;
        }
    }


    class Chunk<T> : ReadOnlySequenceSegment<T>
    {
        public Chunk(ReadOnlyMemory<T> memory) => Memory = memory;
        public Chunk<T> Add(ReadOnlyMemory<T> mem)
        {
            var segment = new Chunk<T>(mem) { RunningIndex = RunningIndex + Memory.Length };
            Next = segment;
            return segment;
        }
    }
}
使用系统;
使用系统缓冲区;
名称空间NowMuchFun
{
班级计划
{
静态void Main(字符串[]参数)
{
var buffer=GetExampleBuffer();
while(TryReadLine(参考缓冲区,输出变量行))
{
while(GetString(ref行,out-var标记))
{
Console.WriteLine(token.ToString());
}
}
}
私有静态只读序列GetExampleBuffer()
{
Chunk startChnk;
var currentChnk=startChnk=new Chunk(新的只读内存(“\”hello\“\”mu“.ToCharArray());
currentChnk=currentChnk.Add(新的只读存储器(“ch\”.ToCharArray());
currentChnk=currentChnk.Add(新的只读存储器(“\'fun\”“.ToCharArray());
currentChnk=currentChnk.Add(新只读内存(“\n\”完成“\n”.ToCharArray());
返回新的只读序列(startChnk,0,currentChnk,currentChnk.Memory.Length);
}
专用静态bool TryReadLine(ref ReadOnlySequence缓冲区,out ReadOnlySequence行)
{
var position=buffer.PositionOf('\n');//在缓冲区中查找EOL。
如果(位置==null)
{
行=默认值;
返回false;
}
line=buffer.Slice(0,position.Value);//跳过该行和\n。
buffer=buffer.Slice(buffer.GetPosition(1,position.Value));
返回true;
}
公共静态bool GetString(ref ReadOnlySequence行,out ReadOnlySequence属性)
{
var start=line.PositionOf(“”);
if(start==null)
{
属性=默认值;
返回false;
}
//属性=line.Slice(start.Value.GetInteger()+1);
//替换为以下内容:
属性=line.Slice(line.GetPosition(1,start.Value));
var end=property.PositionOf(“”);
if(end==null)
{
属性=默认值;
返回false;
}
property=property.Slice(0,end.Value);
line=line.Slice(line.GetPosition(1,end.Value));
返回true;
}
}
类块:ReadOnlySequenceSegment
{
公共块(ReadOnlyMemory)=>内存=内存;
公共块