/// <summary> /// Appends the specified <see cref="Substring"/>. /// </summary> /// <param name="sb">The <see cref="StringBuilder"/> to append to.</param> /// <param name="substr">The <see cref="Substring"/> to append.</param> /// <returns>A reference to <paramref name="sb"/> after the append operation has completed.</returns> public static StringBuilder Append( StringBuilder sb, Substring substr ) { if( substr.NullOrEmpty ) return sb; else return sb.Append(substr.Origin, substr.StartIndex, substr.Length); }
/// <summary> /// Specifies the <see cref="Substring"/> to read from. /// </summary> /// <param name="substr">The substring to read from.</param> public void Set( Substring substr ) { if( substr.Origin.NullReference() ) throw new ArgumentNullException().StoreFileLine(); this.substr = substr; }
private void AppendToBuilder( Substring substr ) { if( !substr.NullOrEmpty ) { if( this.sb.NullReference() ) this.sb = new StringBuilder(); this.sb.Append(substr.Origin, substr.StartIndex, substr.Length); } }
private Substring FromCsvString( Substring substr ) { if( substr.Length == 0 || substr.Equals("\"\"", CompareOptions.Ordinal, CultureInfo.InvariantCulture) ) return Substring.Empty; if( substr[0] == '"' && substr[substr.Length - 1] == '"' ) return substr.Substr(1, substr.Length - 2).ToString().Replace("\"\"", "\""); else return substr; }
public static void ConstructorAndFieldTest() { Assert.Null(Substring.Null.Origin); Assert.AreEqual(0, Substring.Null.StartIndex); Assert.AreEqual(0, Substring.Null.Length); Assert.Null(Substring.Null.ToString()); Assert.True(object.ReferenceEquals(string.Empty, Substring.Empty.Origin)); Assert.AreEqual(0, Substring.Empty.StartIndex); Assert.AreEqual(0, Substring.Empty.Length); Test.OrdinalEquals(string.Empty, Substring.Empty.ToString()); var substr = new Substring("asd"); Test.OrdinalEquals("asd", substr.Origin); Assert.AreEqual(0, substr.StartIndex); Assert.AreEqual(3, substr.Length); Test.OrdinalEquals("asd", substr.ToString()); substr = new Substring("asd", 1); Test.OrdinalEquals("asd", substr.Origin); Assert.AreEqual(1, substr.StartIndex); Assert.AreEqual(2, substr.Length); Test.OrdinalEquals("sd", substr.ToString()); substr = new Substring("asd", 3); Test.OrdinalEquals("asd", substr.Origin); Assert.AreEqual(3, substr.StartIndex); Assert.AreEqual(0, substr.Length); Test.OrdinalEquals(string.Empty, substr.ToString()); substr = new Substring("asd", 1, 1); Test.OrdinalEquals("asd", substr.Origin); Assert.AreEqual(1, substr.StartIndex); Assert.AreEqual(1, substr.Length); Test.OrdinalEquals("s", substr.ToString()); substr = new Substring("asd", 1, 0); Test.OrdinalEquals("asd", substr.Origin); Assert.AreEqual(1, substr.StartIndex); Assert.AreEqual(0, substr.Length); Test.OrdinalEquals(string.Empty, substr.ToString()); Assert.Throws<ArgumentOutOfRangeException>(() => new Substring("asd", -1)); Assert.Throws<ArgumentOutOfRangeException>(() => new Substring("asd", 4)); Assert.Throws<ArgumentException>(() => new Substring("asd", -1, 0)); Assert.Throws<ArgumentException>(() => new Substring("asd", 4, 0)); Assert.Throws<ArgumentException>(() => new Substring("asd", 0, -1)); Assert.Throws<ArgumentException>(() => new Substring("asd", 0, 4)); Assert.Throws<ArgumentException>(() => new Substring("asd", 3, 1)); }
private static bool IsValidWindowsNameCore( Substring fileName ) { Substring trimmedFileName = fileName.TrimEnd(); // may not end in period on windows // (even if period is followed by whitespaces) if( trimmedFileName[fileName.Length - 1] == '.' ) return false; // current and parent directory names // the step above accounts for this /*if( trimmedFileName.Equals(".", CompareOptions.Ordinal) || trimmedFileName.Equals("..", CompareOptions.Ordinal) ) return false;*/ // DOS device names, in any character case foreach( var dosDevName in DosDeviceNames ) { if( fileName.Equals(dosDevName, CompareOptions.OrdinalIgnoreCase) ) return false; } // DOS device names plus any extension int extensionAt = fileName.LastIndexOf('.'); // this would not be OK, if we were checking file paths, instead of file names! if( extensionAt != -1 ) { fileName = fileName.Substr(startIndex: 0, length: extensionAt); foreach( var dosDevName in DosDeviceNames ) { if( fileName.Equals(dosDevName, CompareOptions.OrdinalIgnoreCase) ) return false; } } return true; }
/// <summary> /// Writes the substring. /// </summary> /// <param name="substr">The substring to write.</param> public void Write( Substring substr ) { if( substr.Origin.NullReference() ) throw new ArgumentNullException().StoreFileLine(); this.sb.Append(substr.Origin, substr.StartIndex, substr.Length); }
/// <summary> /// Initializes a new instance of the <see cref="StringReader"/> class. /// </summary> /// <param name="substr">The substring to read from.</param> public StringReader( Substring substr ) { this.Set(substr); }
/// <summary> /// Fills the internal buffer of the reader. /// </summary> /// <returns>Characters from the stream, or a null or empty <see cref="Substring"/> if all characters have been read.</returns> protected override Substring RequestBuffer() { var newBuffer = this.substr; this.substr = Substring.Null; return newBuffer; }
private static int NumDoubleQuotes( Substring str ) { return NumDoubleQuotes(str, 0, str.Length); }
private void SetBufferPastNewLine( int newLineAt ) { this.buffer = this.buffer.Substr(newLineAt); int ch = this.Read(); if( (char)ch == '\r' ) { ch = this.Peek(); if( ch != -1 && (char)ch == '\n' ) this.Read(); } }
private static int NumDoubleQuotes( Substring str, int startIndex, int count ) { int num = 0; count += startIndex; for( int i = startIndex; i < count; ++i ) { if( str[i] == '"' ) ++num; } return num; }
/// <summary> /// Reads all characters from the current position to the end of the stream. /// </summary> /// <param name="substr">All characters from the current position to the end of the stream.</param> public void ReadToEnd( out Substring substr ) { var nextBuffer = this.RequestBuffer(); if( nextBuffer.NullOrEmpty ) { if( this.buffer.NullOrEmpty ) substr = Substring.Empty; else substr = this.buffer; } else { this.AppendToBuilder(this.buffer); this.buffer = nextBuffer; while( !this.buffer.NullOrEmpty ) { this.AppendToBuilder(this.buffer); this.buffer = this.RequestBuffer(); } substr = this.ClearBuilder(); } this.buffer = Substring.Null; }
public void ReadLine( out Substring substr ) { substr = this.ReadLine(); }
public void Write( Substring substr ) { this.Write(substr.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="DataStoreTextValue"/> class. /// </summary> /// <param name="name">The name of the data store node.</param> /// <param name="content">The content of the data store value.</param> public DataStoreTextValue( string name, Substring content ) : base(name) { this.Content = content; }
/// <summary> /// Determines whether the specified file name is portable. /// </summary> /// <param name="fileName">The file name to check.</param> /// <returns><c>true</c> if the file name is portable; otherwise, <c>false</c>.</returns> public static bool IsValidName( Substring fileName ) { // null or empty if( fileName.NullOrEmpty ) return false; // valid characters only for( int i = 0; i < fileName.Length; ++i ) { if( !IsValidPosixPortableFileNameCharacter(fileName[i]) ) return false; } return IsValidWindowsNameCore(fileName); }
/// <summary> /// Returns the first substring in <paramref name="substr"/> that is delimited by elements of <paramref name="separator"/>. /// </summary> /// <param name="substr">The substring to search in, and the rest of the substring not searched yet.</param> /// <param name="separator">An array of Unicode characters that delimit the substrings in <paramref name="substr"/>, an empty array that contains no delimiters, or <c>null</c>.</param> /// <param name="options"><see cref="StringSplitOptions.RemoveEmptyEntries"/> to omit empty substrings; or <see cref="StringSplitOptions.None"/> to include empty substrings.</param> /// <returns>The first substring in <paramref name="substr"/> that is delimited by elements of <paramref name="separator"/>.</returns> public static Substring SplitFirst( ref Substring substr, char[] separator = null, StringSplitOptions options = StringSplitOptions.None ) { if( substr.Origin.NullReference() ) return Substring.Null; // should we return empty substrings? if( options == StringSplitOptions.None ) { // find the first delimeter int delimeterAt = -1; int till = substr.StartIndex + substr.Length; if( separator.NullReference() || separator.Length == 0 ) { // delimeters are whitespaces for( int i = substr.StartIndex; i < till; ++i ) { if( char.IsWhiteSpace(substr.Origin[i]) ) { delimeterAt = i; break; } } } else { for( int i = substr.StartIndex; i < till; ++i ) { foreach( char ch in separator ) { if( substr.Origin[i] == ch ) { delimeterAt = i; i = till; break; } } } } // any delimeters? if( delimeterAt == -1 ) { var lastPart = substr; substr = Substring.Null; return lastPart; } else { var part = new Substring(substr.StartIndex, delimeterAt - substr.StartIndex, substr.Origin); substr = new Substring(delimeterAt + 1, till - delimeterAt - 1, substr.Origin); return part; } } else if( options == StringSplitOptions.RemoveEmptyEntries ) { Substring part; do { part = SplitFirst(ref substr, separator, StringSplitOptions.None); } while( part.Origin.NotNullReference() && part.Length == 0 ); return part; // null or substring } else { throw new ArgumentException().Store("substr", substr).Store("separator", separator).Store("options", options); } }
/// <summary> /// Determines whether the end of this instance matches the <paramref name="comparand"/>, using the specified comparison options and culture-specific information to influence the comparison. /// </summary> /// <param name="comparand">The substring to compare with this instance.</param> /// <param name="options">Options to use when performing the comparison (such as ignoring case or symbols).</param> /// <param name="culture">The culture that supplies culture-specific comparison information. <c>null</c> is interpreted as the current culture.</param> /// <returns><c>true</c> if the end of this instance matches the <paramref name="comparand"/>; otherwise <c>false</c>.</returns> public bool EndsWith( Substring comparand, CompareOptions options = CompareOptions.None, CultureInfo culture = null ) { // the original implementation throws too if( comparand.Origin.NullReference() ) throw new ArgumentNullException("comparand").StoreFileLine(); if( this.Origin.NullReference() ) return false; if( comparand.Length > this.Length ) return false; else if( comparand.Length == this.Length ) return this.CompareTo(comparand, options, culture) == 0; else return new Substring(this.StartIndex + this.Length - comparand.Length, comparand.Length, this.Origin).CompareTo(comparand, options, culture) == 0; }
/// <summary> /// Determines whether this instance and the <paramref name="comparand"/> have the same value, using the specified comparison options and culture-specific information to influence the comparison. /// </summary> /// <param name="comparand">The substring to compare with this instance.</param> /// <param name="options">Options to use when performing the comparison (such as ignoring case or symbols).</param> /// <param name="culture">The culture that supplies culture-specific comparison information. <c>null</c> is interpreted as the current culture.</param> /// <returns><c>true</c> if this instance and the <paramref name="comparand"/> have the same value; otherwise <c>false</c>.</returns> public bool Equals( Substring comparand, CompareOptions options = CompareOptions.None, CultureInfo culture = null ) { return this.CompareTo(comparand, options, culture) == 0; }
/// <summary> /// Compares this instance to the <paramref name="comparand"/> using the specified comparison options and culture-specific information to influence the comparison, and returns an integer that indicates the relationship of the two strings to each other in the sort order. /// </summary> /// <param name="comparand">The substring to compare with this instance.</param> /// <param name="options">Options to use when performing the comparison (such as ignoring case or symbols).</param> /// <param name="culture">The culture that supplies culture-specific comparison information. <c>null</c> is interpreted as the current culture.</param> /// <returns>A 32-bit signed integer that indicates the lexical relationship between the two substrings.</returns> public int CompareTo( Substring comparand, CompareOptions options = CompareOptions.None, CultureInfo culture = null ) { if( culture.NullReference() ) culture = CultureInfo.CurrentCulture; return culture.CompareInfo.Compare(this.Origin, this.StartIndex, this.Length, comparand.Origin, comparand.StartIndex, comparand.Length, options); }
/// <summary> /// Writes a(n) <see cref="Substring"/> to the data store value. /// </summary> /// <param name="value">The object to write to the data store value.</param> public void Write( Substring value ) { if( value.Origin.NullReference() ) throw new ArgumentNullException("value").StoreFileLine(); this.Write(value.Length); for( int i = 0; i < value.Length; ++i ) this.Write(value[i]); }
private static void AssertEqual( string str, Substring substr, char[] separator, StringSplitOptions options ) { var arr1 = str.Split(separator, options); var arr2 = substr.Split(separator, options).Select(s => s.ToString()).ToArray(); Assert.AreEqual(arr1.Length, arr2.Length); for( int i = 0; i < arr1.Length; ++i ) Test.OrdinalEquals(arr1[i], arr2[i]); }
/// <summary> /// Returns the next available character, without actually reading it. /// </summary> /// <returns>An integer representing the next character to be read, or <c>-1</c> if no more characters are available or the reader does not support seeking.</returns> public int Peek() { if( this.buffer.NullOrEmpty ) { this.buffer = this.RequestBuffer(); if( this.buffer.NullOrEmpty ) return -1; } return this.buffer[0]; }
/// <summary> /// Reads the next character. /// </summary> /// <returns>The next character, or <c>-1</c> if no more characters are available.</returns> public int Read() { int result = this.Peek(); if( result != -1 ) this.buffer = this.buffer.Substr(1); return result; }
/// <summary> /// Reads a specified maximum number of characters. /// </summary> /// <param name="count">The maximum number of characters to read. If the end of the stream is reached before the specified number of characters is read, the method returns.</param> /// <returns>The characters read. The number of characters that have been read will be less than or equal to <paramref name="count"/>, depending on whether the data is available within the stream. This method returns <see cref="Substring.Empty"/> if it is called when no more characters are left to read.</returns> public Substring Read( int count ) { if( count < 0 ) throw new ArgumentException().Store("count", count); if( count == 0 ) return Substring.Empty; // anything to read? if( this.buffer.NullOrEmpty ) { this.buffer = this.RequestBuffer(); if( this.buffer.NullOrEmpty ) return Substring.Empty; } // buffer not empty if( count <= this.buffer.Length ) { var result = this.buffer.Substr(startIndex: 0, length: count); this.buffer = this.buffer.Substr(count); return result; } else { while( true ) { int len = Math.Min(count, this.buffer.Length); this.AppendToBuilder(this.buffer.Substr(startIndex: 0, length: len)); this.buffer = this.buffer.Substr(len); count -= len; if( count == 0 ) break; // if count != 0; then buffer.Length == 0 this.buffer = this.RequestBuffer(); if( this.buffer.NullOrEmpty ) break; } // we either read the required number of characters, // or we've run out things to read return this.ClearBuilder(); } }
public void ReadToEnd( out Substring substr ) { substr = this.ReadToEnd(); }
/// <summary> /// Reads a line of characters. /// </summary> /// <param name="substr">The next line from the stream, or <see cref="Substring.Null"/> if all characters have been read.</param> public void ReadLine( out Substring substr ) { if( this.buffer.NullOrEmpty ) { this.buffer = this.RequestBuffer(); if( this.buffer.NullOrEmpty ) { substr = Substring.Null; return; } } int newLineAt = this.IndexOfNewLineInBuffer(); if( newLineAt != -1 ) { substr = this.buffer.Substr(startIndex: 0, length: newLineAt); this.SetBufferPastNewLine(newLineAt); } else { while( newLineAt == -1 ) { this.AppendToBuilder(this.buffer); this.buffer = this.RequestBuffer(); if( this.buffer.NullOrEmpty ) break; newLineAt = this.IndexOfNewLineInBuffer(); } if( newLineAt != -1 ) { this.AppendToBuilder(this.buffer.Substr(startIndex: 0, length: newLineAt)); this.SetBufferPastNewLine(newLineAt); } substr = this.ClearBuilder(); } }
public void Write( Substring value ) { if( this.IsDisposed ) throw new ObjectDisposedException(null).StoreFileLine(); this.writer.Write(value); }
private IDataStoreNode GetNodeAt( Substring dataStorePath ) { if( dataStorePath.NullOrEmpty ) return null; Substring remainingPath = dataStorePath; Substring name; IDataStoreNode currentNode = null; IList<IDataStoreNode> nodes; do { // get the next name from the path name = Substring.SplitFirst(ref remainingPath, DataStore.PathSeparatorArray, StringSplitOptions.None); if( !DataStore.IsValidName(name) ) return null; // search among root nodes, or child nodes if( currentNode.NullReference() ) { nodes = this.rootNodes; } else { // searching for a subdirectory inside a file? var asObjectNode = currentNode as IDataStoreObject; if( asObjectNode.NullReference() ) return null; else nodes = asObjectNode.Nodes; } // search for the name among the nodes currentNode = null; for( int i = 0; i < nodes.Count; ++i ) { if( DataStore.Comparer.Equals(name, nodes[i].Name) ) { currentNode = nodes[i]; break; } } // name not found: exit; otherise, continue if( currentNode.NullReference() ) return null; } while( !remainingPath.NullOrEmpty ); return currentNode; }