internal void WriteEncoded(ReadOnlySpan <char> charSpan) { var escapedValueStartAndStop = Utils.NonNullValue(Configuration.Options.EscapedValueStartAndEnd); // try and blit things in big chunks var start = 0; var end = Utils.FindChar(charSpan, start, escapedValueStartAndStop); while (end != -1) { var escapeValueEscapeChar = Utils.NonNullValue(Configuration.Options.EscapedValueEscapeCharacter); var len = end - start; var toWrite = charSpan.Slice(start, len); PlaceAllInStaging(toWrite); PlaceCharInStaging(escapeValueEscapeChar); start += len; end = Utils.FindChar(charSpan, start + 1, escapedValueStartAndStop); } if (start != charSpan.Length) { var toWrite = charSpan.Slice(start); PlaceAllInStaging(toWrite); } }
private void WriteEncoded(ReadOnlySpan <char> charSpan) { // try and blit things in in big chunks var start = 0; var end = Utils.FindChar(charSpan, start, Config.EscapedValueStartAndStop); while (end != -1) { var len = end - start; var toWrite = charSpan.Slice(start, len); PlaceAllInStaging(toWrite); PlaceCharInStaging(Config.EscapeValueEscapeChar); start += len; end = Utils.FindChar(charSpan, start + 1, Config.EscapedValueStartAndStop); } if (start != charSpan.Length) { var toWrite = charSpan.Slice(start); PlaceAllInStaging(toWrite); } }
private void WriteHeaders() { var needsEscape = Config.SerializeColumnsNeedEscape; for (var i = 0; i < Columns.Length; i++) { // for the separator if (i != 0) { PlaceCharInStaging(Config.ValueSeparator); } var colName = Columns[i].Name; var escape = needsEscape[i]; if (!escape) { PlaceAllInStaging(colName.AsSpan()); } else { // start with the escape char PlaceCharInStaging(Config.EscapedValueStartAndStop); // try and blit everything in relatively few calls var colSpan = colName.AsSpan(); var start = 0; var end = Utils.FindChar(colSpan, start, Config.EscapedValueStartAndStop); while (end != -1) { var len = end - start; var toWrite = colSpan.Slice(start, len); var write = toWrite; PlaceAllInStaging(toWrite); // place the escape char PlaceCharInStaging(Config.EscapeValueEscapeChar); start = end; end = Utils.FindChar(colSpan, start + 1, Config.EscapedValueStartAndStop); } // copy the last bit if (start != colSpan.Length) { var toWrite = colSpan.Slice(start); PlaceAllInStaging(toWrite); } // end with the escape char PlaceCharInStaging(Config.EscapedValueStartAndStop); } } }
internal static void CheckCanEncode(ReadOnlySpan <char> chars, Options options) { var escapedValueStartAndEnd = options.EscapedValueStartAndEnd; var hasEscapedValueStartAndStop = escapedValueStartAndEnd != null; var hasEscapeValueEscapeChar = options.EscapedValueEscapeCharacter != null; // we can always encode if we have both (the common case) if (hasEscapedValueStartAndStop && hasEscapeValueEscapeChar) { return; } // we can NEVER encode if we don't have the ability to start an escaped value if (!hasEscapedValueStartAndStop) { // we can be slow here, we're about to throw an exception var carriageReturnIx = Utils.FindChar(chars, 0, '\r'); var newLineIx = Utils.FindChar(chars, 0, '\n'); var separatorIx = chars.IndexOf(options.ValueSeparator); var commentChar = options.CommentCharacter; var commentIx = commentChar != null?Utils.FindChar(chars, 0, commentChar.Value) : -1; if (carriageReturnIx == -1) { carriageReturnIx = int.MaxValue; } if (newLineIx == -1) { newLineIx = int.MaxValue; } if (separatorIx == -1) { separatorIx = int.MaxValue; } if (commentIx == -1) { commentIx = int.MaxValue; } var offendingIx = Math.Min(carriageReturnIx, Math.Min(newLineIx, Math.Min(separatorIx, commentIx))); var take = carriageReturnIx == offendingIx || newLineIx == offendingIx || commentIx == offendingIx ? 1 : options.ValueSeparator.Length; var offendingText = new string(chars[offendingIx..(offendingIx + take)]);