Click here to Skip to main content
15,886,787 members
Articles / Programming Languages / C#

SIP Stack with SIP Proxy - (VOIP)

Rate me:
Please Sign up or sign in to vote.
4.86/5 (45 votes)
11 Jun 2007CPOL2 min read 1.6M   28.1K   162  
C# implementation of SIP
using System;
using System.Text;

namespace LumiSoft.Net
{
	/// <summary>
	/// String reader.
	/// </summary>
	public class StringReader
	{
        private string m_OriginalString = "";
		private string m_SourceString   = "";

		/// <summary>
		/// Default constructor.
		/// </summary>
		/// <param name="source">Source string.</param>
		public StringReader(string source)
		{	
            m_OriginalString = source;
			m_SourceString   = source;
		}

// SYNC JAVA
		#region method AppenString

		/// <summary>
		/// Appends specified string to SourceString.
		/// </summary>
		/// <param name="str">String value to append.</param>
		public void AppenString(string str)
		{
			m_SourceString += str;
		}

		#endregion


		#region method ReadToFirstChar

		/// <summary>
		/// Reads to first char, skips SP,VTAB,HTAB,CR,LF from the beginning of source string.
		/// </summary>
		public void ReadToFirstChar()
		{            
			m_SourceString = m_SourceString.TrimStart();
		}

		#endregion

	//	public string ReadToDelimiter(char delimiter)
	//	{
	//	}

		#region method ReadSpecifiedLength

		/// <summary>
		/// Reads string with specified length. Throws exception if read length is bigger than source string length.
		/// </summary>
		/// <param name="length">Number of chars to read.</param>
		/// <returns></returns>
		public string ReadSpecifiedLength(int length)
		{
			if(m_SourceString.Length >= length){
				string retVal = m_SourceString.Substring(0,length);
				m_SourceString = m_SourceString.Substring(length);

				return retVal;
			}
			else{
				throw new Exception("Read length can't be bigger than source string !");
			}
		}

		#endregion
// sync java
		#region method QuotedReadToDelimiter

        /// <summary>
		/// Reads string to specified delimiter or to end of underlying string. Notes: Delimiter in quoted string is skipped.
        /// Delimiter is removed by default.
		/// For example: delimiter = ',', text = '"aaaa,eee",qqqq' - then result is '"aaaa,eee"'.
		/// </summary>
		/// <param name="delimiter">Data delimiter.</param>
		/// <returns></returns>
		public string QuotedReadToDelimiter(char delimiter)
		{
            return QuotedReadToDelimiter(new char[]{delimiter});
        }

        /// <summary>
		/// Reads string to specified delimiter or to end of underlying string. Notes: Delimiters in quoted string is skipped.
        /// Delimiter is removed by default.
		/// For example: delimiter = ',', text = '"aaaa,eee",qqqq' - then result is '"aaaa,eee"'.
		/// </summary>
		/// <param name="delimiters">Data delimiters.</param>
		/// <returns></returns>
		public string QuotedReadToDelimiter(char[] delimiters)
		{
            return QuotedReadToDelimiter(delimiters,true);
        }

		/// <summary>
		/// Reads string to specified delimiter or to end of underlying string. Notes: Delimiters in quoted string is skipped. 
		/// For example: delimiter = ',', text = '"aaaa,eee",qqqq' - then result is '"aaaa,eee"'.
		/// </summary>
		/// <param name="delimiters">Data delimiters.</param>
        /// <param name="removeDelimiter">Specifies if delimiter is removed from underlying string.</param>
		/// <returns></returns>
		public string QuotedReadToDelimiter(char[] delimiters,bool removeDelimiter)
		{
			StringBuilder currentSplitBuffer = new StringBuilder(); // Holds active
			bool          inQuotedString     = false;               // Holds flag if position is quoted string or not
			char          lastChar           = (char)0;

			for(int i=0;i<m_SourceString.Length;i++){
				char c = m_SourceString[i];

				// Skip escaped(\) "
				if(lastChar != '\\' && c == '\"'){
					// Start/end quoted string area
					inQuotedString = !inQuotedString;
				}
			
                // See if char is delimiter
                bool isDelimiter = false;
                foreach(char delimiter in delimiters){
                    if(c == delimiter){
                        isDelimiter = true;
                        break;
                    }
                }

				// Current char is split char and it isn't in quoted string, do split
				if(!inQuotedString && isDelimiter){
					string retVal = currentSplitBuffer.ToString();
                                        
					// Remove readed string + delimiter from source string
                    if(removeDelimiter){
					    m_SourceString = m_SourceString.Substring(retVal.Length + 1);
                    }
                    // Remove readed string
                    else{
                        m_SourceString = m_SourceString.Substring(retVal.Length);
                    }

					return retVal;
				}
				else{
					currentSplitBuffer.Append(c);
				}

				lastChar = c;
			}

			// If we reached so far then we are end of string, return it
			m_SourceString = "";
			return currentSplitBuffer.ToString();
		}

		#endregion


		// SYNC JAVA
		#region method ReadWord

        /// <summary>
		/// Reads word from string. Returns null if no word is available.
		/// Word reading begins from first char, for example if SP"text", then space is trimmed.
		/// </summary>
		/// <returns></returns>
        public string ReadWord()
		{
            return ReadWord(true);
        }

        /// <summary>
		/// Reads word from string. Returns null if no word is available.
		/// Word reading begins from first char, for example if SP"text", then space is trimmed.
		/// </summary>
		/// <param name="unQuote">Specifies if quoted string word is unquoted.</param>
		/// <returns></returns>
		public string ReadWord(bool unQuote)
		{
            return ReadWord(unQuote,new char[]{' ',',',';','{','}','(',')','[',']','<','>','\r','\n'},false);
        }

		/// <summary>
		/// Reads word from string. Returns null if no word is available.
		/// Word reading begins from first char, for example if SP"text", then space is trimmed.
		/// </summary>
		/// <param name="unQuote">Specifies if quoted string word is unquoted.</param>
		/// <param name="wordTerminatorChars">Specifies chars what terminate word.</param>
		/// <param name="removeWordTerminator">Specifies if work terminator is removed.</param>
		/// <returns></returns>
		public string ReadWord(bool unQuote,char[] wordTerminatorChars,bool removeWordTerminator)
		{			
			// Always start word reading from first char.
			this.ReadToFirstChar();

            if(this.Available == 0){
				return null;
			}
            			            
			// quoted word can contain any char, " must be escaped with \
			// unqouted word can conatin any char except: SP VTAB HTAB,{}()[]<>

			if(m_SourceString.StartsWith("\"")){
                if(unQuote){
                    return TextUtils.UnQuoteString(QuotedReadToDelimiter(wordTerminatorChars,removeWordTerminator));
                }
                else{
                    return QuotedReadToDelimiter(wordTerminatorChars,removeWordTerminator);
                }				
			}
			else{
				int wordLength = 0;
				for(int i=0;i<m_SourceString.Length;i++){
					char c = m_SourceString[i];

                    bool isTerminator = false;
                    foreach(char terminator in wordTerminatorChars){
                        if(c == terminator){
                            isTerminator = true;
                            break;
                        }
                    }
                    if(isTerminator){
                        break;
                    }

					wordLength++;
				}
				
				string retVal = m_SourceString.Substring(0,wordLength);
                if(removeWordTerminator){
                    if(m_SourceString.Length >= wordLength + 1){
                        m_SourceString = m_SourceString.Substring(wordLength + 1);
                    }
                }
                else{
				    m_SourceString = m_SourceString.Substring(wordLength);
                }

				return retVal;
			}			
		}

		#endregion
	// SYNC JAVA	
		#region method ReadParenthesized

		/// <summary>
		/// Reads parenthesized value. Supports {},(),[],&lt;&gt; parenthesis. 
		/// Throws exception if there isn't parenthesized value or closing parenthesize is missing.
		/// </summary>
		/// <returns></returns>
		public string ReadParenthesized()
		{
            ReadToFirstChar();

			char startingChar = ' ';
			char closingChar  = ' ';

			if(m_SourceString.StartsWith("{")){
				startingChar = '{';
				closingChar = '}';
			}
			else if(m_SourceString.StartsWith("(")){
				startingChar = '(';
				closingChar = ')';
			}			
			else if(m_SourceString.StartsWith("[")){
				startingChar = '[';
				closingChar = ']';
			}						
			else if(m_SourceString.StartsWith("<")){
				startingChar = '<';
				closingChar = '>';
			}
			else{
				throw new Exception("No parenthesized value '" + m_SourceString + "' !");
			}

			bool inQuotedString = false; // Holds flag if position is quoted string or not
			char lastChar       = (char)0;

			int closingCharIndex = -1;
			int nestedStartingCharCounter = 0;
			for(int i=1;i<m_SourceString.Length;i++){
				// Skip escaped(\) "
				if(lastChar != '\\' && m_SourceString[i] == '\"'){
					// Start/end quoted string area
					inQuotedString = !inQuotedString;
				}
				// We need to skip parenthesis in quoted string
				else if(!inQuotedString){
					// There is nested parenthesis
					if(m_SourceString[i] == startingChar){
						nestedStartingCharCounter++;
					}
					// Closing char
					else if(m_SourceString[i] == closingChar){
						// There isn't nested parenthesis closing chars left, this is closing char what we want
						if(nestedStartingCharCounter == 0){
							closingCharIndex = i;
							break;
						}
						// This is nested parenthesis closing char
						else{
							nestedStartingCharCounter--;
						}
					}
				}

				lastChar = m_SourceString[i];
			}

			if(closingCharIndex == -1){
				throw new Exception("There is no closing parenthesize for '" + m_SourceString + "' !");
			}
			else{
				string retVal = m_SourceString.Substring(1,closingCharIndex - 1);
				m_SourceString = m_SourceString.Substring(closingCharIndex + 1);

				return retVal;
			}
		}

		#endregion

        // SYNC JAVA

        #region method ReadToEnd

        /// <summary>
        /// Reads all remaining string, returns null if no chars left to read.
        /// </summary>
        /// <returns></returns>
        public string ReadToEnd()
        {
            if(this.Available == 0){
				return null;
			}

            string retVal = m_SourceString;
            m_SourceString = "";

            return retVal;
        }

        #endregion


        #region method StartsWith

        /// <summary>
		/// Gets if source string starts with specified value. Compare is case-sensitive.
		/// </summary>
		/// <param name="value">Start string value.</param>
		/// <returns></returns>
		public bool StartsWith(string value)
		{
			return m_SourceString.StartsWith(value);
		}
		
		/// <summary>
		/// Gets if source string starts with specified value.
		/// </summary>
		/// <param name="value">Start string value.</param>
		/// <param name="case_sensitive">Specifies if compare is case-sensitive.</param>
		/// <returns></returns>
		public bool StartsWith(string value,bool case_sensitive)
		{
			if(case_sensitive){
				return m_SourceString.StartsWith(value);
			}
			else{
				return m_SourceString.ToLower().StartsWith(value.ToLower());
			}
		}

		#endregion


		#region Properties Implementation

		/// <summary>
		/// Gets how many chars are available for reading.
		/// </summary>
		public long Available
		{
			get{ return m_SourceString.Length; }
		}

        /// <summary>
        /// Gets original string passed to class constructor.
        /// </summary>
        public string OriginalString
        {
            get{ return m_OriginalString; }
        }

		/// <summary>
		/// Gets currently remaining string.
		/// </summary>
		public string SourceString
		{
			get{ return m_SourceString; }
		}

        /// <summary>
        /// Gets position in original string.
        /// </summary>
        public int Position
        {
            get{ return m_OriginalString.Length - m_SourceString.Length; }
        }

		#endregion

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Estonia Estonia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions