//--------------------------------------------------------------------- /// <summary> /// Reads a percentage for partial thinning of a cohort age or age /// range. /// </summary> /// <remarks> /// The percentage is bracketed by parentheses. /// </remarks> public static InputValue<Percentage> ReadPercentage(StringReader reader, out int index) { TextReader.SkipWhitespace(reader); index = reader.Index; // Read left parenthesis int nextChar = reader.Peek(); if (nextChar == -1) throw new InputValueException(); // Missing value if (nextChar != '(') throw MakeInputValueException(TextReader.ReadWord(reader), "Value does not start with \"(\""); StringBuilder valueAsStr = new StringBuilder(); valueAsStr.Append((char) (reader.Read())); // Read whitespace between '(' and percentage valueAsStr.Append(ReadWhitespace(reader)); // Read percentage string word = ReadWord(reader, ')'); if (word == "") throw MakeInputValueException(valueAsStr.ToString(), "No percentage after \"(\""); valueAsStr.Append(word); Percentage percentage; try { percentage = Percentage.Parse(word); } catch (System.FormatException exc) { throw MakeInputValueException(valueAsStr.ToString(), exc.Message); } if (percentage < 0.0 || percentage > 1.0) throw MakeInputValueException(valueAsStr.ToString(), string.Format("{0} is not between 0% and 100%", word)); // Read whitespace and ')' valueAsStr.Append(ReadWhitespace(reader)); char? ch = TextReader.ReadChar(reader); if (! ch.HasValue) throw MakeInputValueException(valueAsStr.ToString(), "Missing \")\""); valueAsStr.Append(ch.Value); if (ch != ')') throw MakeInputValueException(valueAsStr.ToString(), string.Format("Value ends with \"{0}\" instead of \")\"", ch)); return new InputValue<Percentage>(percentage, valueAsStr.ToString()); }
public void NonEmptyString() { string str = "Hello World!"; StringReader reader = new StringReader(str); int expectedIndex = 0; foreach (char expectedCh in str) { Assert.AreEqual(expectedIndex, reader.Index); int i = reader.Read(); Assert.IsTrue(i != -1); Assert.AreEqual(expectedCh, (char) i); expectedIndex++; } Assert.AreEqual(expectedIndex, reader.Index); Assert.AreEqual(-1, reader.Peek()); }
public void ReadBlock() { string str = "Four score and seven years ago ..."; StringReader reader = new StringReader(str); char[] buffer = new char[str.Length]; int blockSize = 5; for (int bufferIndex = 0; bufferIndex < buffer.Length; bufferIndex += blockSize) { Assert.AreEqual(bufferIndex, reader.Index); int countToRead; if (bufferIndex + blockSize > buffer.Length) countToRead = buffer.Length - bufferIndex; else countToRead = blockSize; Assert.AreEqual(countToRead, reader.Read(buffer, bufferIndex, countToRead)); } Assert.AreEqual(str.Length, reader.Index); Assert.AreEqual(-1, reader.Peek()); Assert.AreEqual(str, new string(buffer)); }
//--------------------------------------------------------------------- /// <summary> /// Reads a word from a string reader. /// </summary> /// <remarks> /// The word is terminated by whitespace, the end of input, or a /// particular delimiter character. /// </remarks> public static string ReadWord(StringReader reader, char delimiter) { StringBuilder word = new StringBuilder(); int i = reader.Peek(); while (i != -1 && ! char.IsWhiteSpace((char) i) && i != delimiter) { word.Append((char) reader.Read()); i = reader.Peek(); } return word.ToString(); }
//--------------------------------------------------------------------- /// <summary> /// Reads whitespace from a string reader. /// </summary> public static string ReadWhitespace(StringReader reader) { StringBuilder whitespace = new StringBuilder(); int i = reader.Peek(); while (i != -1 && char.IsWhiteSpace((char) i)) { whitespace.Append((char) reader.Read()); i = reader.Peek(); } return whitespace.ToString(); }
//--------------------------------------------------------------------- /// <summary> /// Read a string from a StringReader. /// </summary> /// <remarks> /// This method reads a string from a StringReader. The string is /// either an unquoted word or a quoted string. A word is one or more /// adjacent non-whitespace characters. A quoted string is zero or /// more characters surrounded by a pair of quotes. The quotes may be /// a pair of double quotes (") or a pair of single quotes ('). A /// quote character can be included inside a quoted string by escaping /// it with a backslash (\). /// <example> /// Here are some valid strings: /// <code> /// foo /// a-brief-phrase /// C:\some\path\to\a\file.ext /// "" /// "Four score and seven years ago ..." /// "That's incredulous!" /// 'That\'s incredulous!' /// '' /// 'He said "Boo."' /// "He said \"Boo.\"" /// </code> /// </example> /// Whitespace preceeding the word or the quoted string is skipped. /// The delimiting quotes of a quoted string are removed. /// </remarks> /// <exception cref="">System.IO.EndOfStreamException</exception> public static InputValue<string> Read(StringReader reader, out int index) { TextReader.SkipWhitespace(reader); if (reader.Peek() == -1) throw new InputValueException(); index = reader.Index; char nextChar = (char) reader.Peek(); if (nextChar == '\'' || nextChar == '"') { // Quoted string char startQuote = (char) reader.Read(); StringBuilder quotedStr = new StringBuilder(); quotedStr.Append(startQuote); StringBuilder actualStr = new StringBuilder(); bool endQuoteFound = false; while (! endQuoteFound) { char? ch = TextReader.ReadChar(reader); if (! ch.HasValue) throw new InputValueException(quotedStr.ToString(), "String has no end quote: {0}", quotedStr.ToString()); if (ch.Value == startQuote) { endQuoteFound = true; quotedStr.Append(ch.Value); } else { if (ch.Value == '\\') { // Get the next character if it's a quote. nextChar = (char) reader.Peek(); if (nextChar == '\'' || nextChar == '"') { quotedStr.Append(ch.Value); ch = TextReader.ReadChar(reader); } } actualStr.Append(ch.Value); quotedStr.Append(ch.Value); } } return new InputValue<string>(actualStr.ToString(), quotedStr.ToString()); } else { string word = TextReader.ReadWord(reader); return new InputValue<string>(word, word); } }