public static void TrimEnd(this StringWriter writer, char @char) { var builder = writer.GetStringBuilder(); var length = builder.Length; var last = builder[length - 1]; if (last == @char) { writer.RemoveLast(1); } }
public void RemoveLastTest() { var writer = new StringWriter(); writer.Write("EKIEKIEKIPATENG "); writer.RemoveLast(2); const string expected = "EKIEKIEKIPATENG"; var actual = writer.ToString(); Assert.AreEqual(expected, actual); }
public override string ToString() { using (var sw = new StringWriter()) { foreach (var value in Values) { sw.Write(value); sw.Write(Characters.Comma); } sw.RemoveLast(1); return(sw.ToString()); } }
public string ReadSection(ImapResponseReader reader) { var text = reader.CurrentLine; var sn = Regex.Match(text, @"\d+").Value; using (var sw = new StringWriter()) { using (var sr = new StringReader(text)) { var stack = new Stack <char>(); var isStarted = false; var index = text.IndexOf("BODYSTRUCTURE"); var buffer = new char[index + 1]; sr.Read(buffer, 0, index); while (true) { if (isStarted) { sw.Write(buffer[0]); } var count = sr.Read(buffer, 0, 1); // end of string if (count == 0) { break; } // matching brace found if (isStarted && stack.Count == 0) { break; } if (buffer[0] == Characters.RoundOpenBracket) { stack.Push(buffer[0]); isStarted = true; continue; } if (buffer[0] == Characters.RoundClosedBracket) { stack.Pop(); continue; } } // is a size appended to indicate multilined data? {####} var sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$"); if (sizeMatch.Success) { // need to remove {####} from end of string sw.RemoveLast(sizeMatch.Value.Length); // Usually we could determine the amount of data to read from the size parameter at the end of the line // unfortunately here the number contained seems to be completely arbitrary since it never fits, coming from 1und1 its always 107, no matter what follows. // The 'only' thing I can be sure of when determining the amount of data to append is that it has to end with a closing bracket, no matter what. while (true) { reader.ReadNextLine(); var line = reader.CurrentLine; sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$"); // cut trailing {###} expression if necessary var normalizedLine = sizeMatch.Success ? line.Substring(0, line.Length - sizeMatch.Value.Length) : line; // decode line since its usually encoded using QP or Base64 normalizedLine = TransferEncoder.DecodeHeaderIfNecessary(normalizedLine); // append line to regular body struct sw.Write(normalizedLine); if (reader.CurrentLine.EndsWith(")")) { break; } } } // we silently append the sequence number to the end of the body structure, // the parser will ignore it, but we can read it later without having to split or change this string sw.Write(Characters.Space); sw.Write(sn); return(sw.ToString()); } } }