예제 #1
0
 /// <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);
 }
예제 #2
0
        /// <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;
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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;
        }
예제 #5
0
        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));
        }
예제 #6
0
        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;
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
 /// <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);
 }
예제 #9
0
 /// <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;
 }
예제 #10
0
 private static int NumDoubleQuotes( Substring str )
 {
     return NumDoubleQuotes(str, 0, str.Length);
 }
예제 #11
0
        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();
            }
        }
예제 #12
0
 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;
 }
예제 #13
0
        /// <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;
        }
예제 #14
0
 public void ReadLine( out Substring substr )
 {
     substr = this.ReadLine();
 }
예제 #15
0
 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;
 }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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);
            }
        }
예제 #19
0
        /// <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;
        }
예제 #20
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;
 }
예제 #21
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]);
        }
예제 #23
0
        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]);
        }
예제 #24
0
        /// <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];
        }
예제 #25
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;
 }
예제 #26
0
        /// <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();
            }
        }
예제 #27
0
 public void ReadToEnd( out Substring substr )
 {
     substr = this.ReadToEnd();
 }
예제 #28
0
        /// <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();
            }
        }
예제 #29
0
            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;
        }