public bool TryParseData(ReadOnlySpan <char> span) { var scanned = -1; var position = 0; if (!ParseChunk(ref span, ref scanned, ref position).Equals(ProtocolVersionString, StringComparison.OrdinalIgnoreCase)) { return(false); } if (!int.TryParse(ParseChunk(ref span, ref scanned, ref position), out _)) { return(false); } if (!int.TryParse(ParseChunk(ref span, ref scanned, ref position), out var origin)) { return(false); } else { Origin = origin; } if (!int.TryParse(ParseChunk(ref span, ref scanned, ref position), out var dataItemsCount)) { return(false); } Span <int> offsets = dataItemsCount * 4 < 1024 ? stackalloc int[dataItemsCount] : new int[dataItemsCount]; //Count from 4th item to second last item. Those are the offsets. for (var i = 0; i < dataItemsCount; i++) { if (!int.TryParse(ParseChunk(ref span, ref scanned, ref position), out var offset)) { return(false); } else { offsets[i] = offset; } } //Set the datastring, its the last item in the list. If it contained any separators, they will get read here: scanned += position + 1; var dataString = span.Slice(scanned, span.Length - scanned); //Cutting the data: for (var i = 0; i < offsets.Length; i++) { var cOffset = offsets[i]; var length = dataString.Length - cOffset; if (i < offsets.Length - 1) { length = offsets[i + 1] - cOffset; } if (length < 0) { return(false); } if (cOffset + length > dataString.Length) { return(false); } DataItems.AddToEnd(dataString.Slice(cOffset, length)); } return(true); }