StreamTokenizer.cs
上传用户:sex100000
上传日期:2013-11-09
资源大小:1377k
文件大小:9k
源码类别:

GIS编程

开发平台:

C#

  1. // Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
  2. //
  3. // This file is part of SharpMap.
  4. // SharpMap is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. // 
  9. // SharpMap is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with SharpMap; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  16. // SOURCECODE IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
  17. /*
  18.  *  Copyright (C) 2002 Urban Science Applications, Inc. 
  19.  *
  20.  *  This library is free software; you can redistribute it and/or
  21.  *  modify it under the terms of the GNU Lesser General Public
  22.  *  License as published by the Free Software Foundation; either
  23.  *  version 2.1 of the License, or (at your option) any later version.
  24.  *
  25.  *  This library is distributed in the hope that it will be useful,
  26.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  28.  *  Lesser General Public License for more details.
  29.  *
  30.  *  You should have received a copy of the GNU Lesser General Public
  31.  *  License along with this library; if not, write to the Free Software
  32.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  33.  *
  34.  */
  35. #region Using
  36. using System;
  37. using System.IO;
  38. using System.Text;
  39. using SharpMap.Converters.WellKnownText;
  40. #endregion
  41. // http://java.sun.com/j2se/1.4/docs/api/java/io/StreamTokenizer.html
  42. // a better implementation could be written. Here is a good Java implementation of StreamTokenizer.
  43. //   http://www.flex-compiler.lcs.mit.edu/Harpoon/srcdoc/java/io/StreamTokenizer.html
  44. // a C# StringTokenizer
  45. //  http://sourceforge.net/snippet/detail.php?type=snippet&id=101171
  46. namespace SharpMap.Converters.WellKnownText.IO
  47. {
  48. ///<summary>
  49. ///The StreamTokenizer class takes an input stream and parses it into "tokens", allowing the tokens to be read one at a time. The parsing process is controlled by a table and a number of flags that can be set to various states. The stream tokenizer can recognize identifiers, numbers, quoted strings, and various comment style
  50. ///</summary>
  51. ///<remarks>
  52. ///This is a crude c# implementation of Java's <a href="http://java.sun.com/products/jdk/1.2/docs/api/java/io/StreamTokenizer.html">StreamTokenizer</a> class.
  53. ///</remarks>
  54. internal class StreamTokenizer 
  55. {
  56. TokenType _currentTokenType;
  57. TextReader _reader;
  58. string _currentToken;
  59. bool _ignoreWhitespace = false;
  60. int _lineNumber=1;
  61. int _colNumber=1;
  62. #region Constructors
  63. /// <summary>
  64. /// Initializes a new instance of the StreamTokenizer class.
  65. /// </summary>
  66. /// <param name="reader">A TextReader with some text to read.</param>
  67. /// <param name="ignoreWhitespace">Flag indicating whether whitespace should be ignored.</param>
  68. public StreamTokenizer(TextReader reader, bool ignoreWhitespace)
  69. {
  70. if (reader==null)
  71. {
  72. throw new ArgumentNullException("reader");
  73. }
  74. _reader = reader;
  75. _ignoreWhitespace = ignoreWhitespace;
  76. }
  77. #endregion
  78. #region Properties
  79. /// <summary>
  80. /// The current line number of the stream being read.
  81. /// </summary>
  82. public int LineNumber
  83. {
  84. get
  85. {
  86. return _lineNumber;
  87. }
  88. }
  89. /// <summary>
  90. /// The current column number of the stream being read.
  91. /// </summary>
  92. public int Column
  93. {
  94. get
  95. {
  96. return _colNumber;
  97. }
  98. }
  99. #endregion
  100. #region Methods
  101. /// <summary>
  102. /// If the current token is a number, this field contains the value of that number. 
  103. /// </summary>
  104. /// <remarks>
  105. /// If the current token is a number, this field contains the value of that number. The current token is a number when the value of the ttype field is TT_NUMBER.
  106. /// </remarks>
  107. /// <exception cref="FormatException">Current token is not a number in a valid format.</exception>
  108. public double GetNumericValue()
  109. {
  110. string number = this.GetStringValue();
  111. if (this.GetTokenType()==TokenType.Number)
  112. {
  113. return double.Parse(number,SharpMap.Map.numberFormat_EnUS);
  114. }
  115. throw new Exception(String.Format(SharpMap.Map.numberFormat_EnUS, "The token '{0}' is not a number at line {1} column {2}.", number, this.LineNumber, this.Column)); ;
  116. }
  117. /// <summary>
  118. /// If the current token is a word token, this field contains a string giving the characters of the word token. 
  119. /// </summary>
  120. public string GetStringValue()
  121. {
  122. return _currentToken;
  123. }
  124. /// <summary>
  125. /// Gets the token type of the current token.
  126. /// </summary>
  127. /// <returns></returns>
  128. public TokenType GetTokenType()
  129. {
  130. return _currentTokenType;
  131. }
  132. /// <summary>
  133. /// Returns the next token.
  134. /// </summary>
  135. /// <param name="ignoreWhitespace">Determines is whitespace is ignored. True if whitespace is to be ignored.</param>
  136. /// <returns>The TokenType of the next token.</returns>
  137. public TokenType NextToken(bool ignoreWhitespace)
  138. {
  139. TokenType nextTokenType;
  140. if (ignoreWhitespace)
  141. {
  142. nextTokenType= NextNonWhitespaceToken();
  143. }
  144. else
  145. {
  146. nextTokenType=NextTokenAny();
  147. }
  148. return nextTokenType;
  149. }
  150. /// <summary>
  151. /// Returns the next token.
  152. /// </summary>
  153. /// <returns>The TokenType of the next token.</returns>
  154. public TokenType NextToken()
  155. {
  156. return NextToken(_ignoreWhitespace);
  157. }
  158. private TokenType NextTokenAny()
  159. {
  160. TokenType nextTokenType = TokenType.Eof;
  161. char[] chars = new char[1];
  162. _currentToken="";
  163. _currentTokenType = TokenType.Eof;
  164. int finished = _reader.Read(chars,0,1);
  165. bool isNumber=false;
  166. bool isWord=false;
  167. byte[] ba=null;
  168. ASCIIEncoding AE = new ASCIIEncoding();
  169. char[] ascii=null;
  170. Char currentCharacter;
  171. Char nextCharacter;
  172. while (finished != 0 )
  173. {
  174. // convert int to char
  175. ba = new Byte[]{(byte)_reader.Peek()};
  176.  ascii = AE.GetChars(ba);
  177. currentCharacter = chars[0];
  178. nextCharacter = ascii[0];
  179. _currentTokenType = GetType(currentCharacter);
  180. nextTokenType = GetType(nextCharacter);
  181. // handling of words with _
  182. if (isWord && currentCharacter=='_')
  183. {
  184. _currentTokenType= TokenType.Word;
  185. }
  186. // handing of words ending in numbers
  187. if (isWord && _currentTokenType==TokenType.Number)
  188. {
  189. _currentTokenType= TokenType.Word;
  190. }
  191. if (_currentTokenType==TokenType.Word && nextCharacter=='_')
  192. {
  193. //enable words with _ inbetween
  194. nextTokenType =  TokenType.Word;
  195. isWord=true;
  196. }
  197. if (_currentTokenType==TokenType.Word && nextTokenType==TokenType.Number)
  198. {
  199. //enable words ending with numbers
  200. nextTokenType =  TokenType.Word;
  201. isWord=true;
  202. }
  203. // handle negative numbers
  204. if (currentCharacter=='-' && nextTokenType==TokenType.Number && isNumber ==false)
  205. {
  206. _currentTokenType= TokenType.Number;
  207. nextTokenType =  TokenType.Number;
  208. //isNumber = true;
  209. }
  210. // this handles numbers with a decimal point
  211. if (isNumber && nextTokenType == TokenType.Number && currentCharacter=='.' )
  212. {
  213. _currentTokenType =  TokenType.Number;
  214. }
  215. if (_currentTokenType == TokenType.Number && nextCharacter=='.' && isNumber ==false)
  216. {
  217. nextTokenType =  TokenType.Number;
  218. isNumber = true;
  219. }
  220. _colNumber++;
  221. if (_currentTokenType==TokenType.Eol)
  222. {
  223. _lineNumber++;
  224. _colNumber=1;
  225. }
  226. _currentToken = _currentToken + currentCharacter;
  227. //if (_currentTokenType==TokenType.Word && nextCharacter=='_')
  228. //{
  229. // enable words with _ inbetween
  230. // finished = _reader.Read(chars,0,1);
  231. //}
  232. if (_currentTokenType!=nextTokenType)
  233. {
  234. finished = 0;
  235. }
  236. else if (_currentTokenType==TokenType.Symbol && currentCharacter!='-')
  237. {
  238. finished = 0;
  239. }
  240. else
  241. {
  242. finished = _reader.Read(chars,0,1);
  243. }
  244. }
  245. return _currentTokenType;
  246. }
  247. /// <summary>
  248. /// Determines a characters type (e.g. number, symbols, character).
  249. /// </summary>
  250. /// <param name="character">The character to determine.</param>
  251. /// <returns>The TokenType the character is.</returns>
  252. private TokenType GetType(char character)
  253. {
  254. if (Char.IsDigit(character))
  255. {
  256. return TokenType.Number;
  257. }
  258. else if (Char.IsLetter(character))
  259. {
  260. return TokenType.Word;
  261. }
  262. else if (character=='n')
  263. {
  264. return TokenType.Eol;
  265. }
  266. else if (Char.IsWhiteSpace(character) || Char.IsControl(character))
  267. {
  268. return TokenType.Whitespace;
  269. }
  270. else //(Char.IsSymbol(character))
  271. {
  272. return TokenType.Symbol;
  273. }
  274. }
  275. /// <summary>
  276. /// Returns next token that is not whitespace.
  277. /// </summary>
  278. /// <returns></returns>
  279. private TokenType NextNonWhitespaceToken()
  280. {
  281. TokenType tokentype = this.NextTokenAny();
  282. while (tokentype== TokenType.Whitespace || tokentype== TokenType.Eol)
  283. {
  284. tokentype = this.NextTokenAny();
  285. }
  286. return tokentype;
  287. }
  288. #endregion
  289. }
  290. }