/IronPython_2_0/Src/IronPython.Modules/cStringIO.cs

# · C# · 529 lines · 430 code · 84 blank · 15 comment · 62 complexity · 0d3d116420f2ea2436a0e5e07c51e511 MD5 · raw file

  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.IO;
  19. using System.Text;
  20. using IronPython.Runtime;
  21. using IronPython.Runtime.Operations;
  22. using IronPython.Runtime.Types;
  23. [assembly: PythonModule("cStringIO", typeof(IronPython.Modules.PythonStringIO))]
  24. namespace IronPython.Modules {
  25. class StringStream {
  26. private string _data;
  27. private int _position;
  28. private int _length;
  29. public StringStream(string data) {
  30. this._data = data;
  31. this._position = 0;
  32. this._length = data == null ? 0 : data.Length;
  33. }
  34. public bool EOF {
  35. get { return _position >= _length; }
  36. }
  37. public int Position {
  38. get { return _position; }
  39. }
  40. public string Data {
  41. get {
  42. return _data;
  43. }
  44. set {
  45. _data = value;
  46. if (_data == null) {
  47. _length = _position = 0;
  48. } else {
  49. _length = _data.Length;
  50. if (_position > _length) {
  51. _position = _length;
  52. }
  53. }
  54. }
  55. }
  56. public string Prefix {
  57. get {
  58. return _data.Substring(0, _position);
  59. }
  60. }
  61. public int Read() {
  62. if (_position < _length) {
  63. return _data[_position++];
  64. } else {
  65. return -1;
  66. }
  67. }
  68. public string Read(int i) {
  69. if (_position + i > _length) {
  70. i = _length - _position;
  71. }
  72. string ret = _data.Substring(_position, i);
  73. _position += i;
  74. return ret;
  75. }
  76. public string ReadLine(int size) {
  77. if (size < 0) {
  78. size = Int32.MaxValue;
  79. }
  80. int i = _position;
  81. int count = 0;
  82. while (i < _length && count < size) {
  83. char c = _data[i];
  84. if (c == '\n' || c == '\r') {
  85. i++;
  86. if (c == '\r' && _position < _length && _data[i] == '\n') {
  87. i++;
  88. }
  89. // preserve newline character like StringIO
  90. string res = _data.Substring(_position, i - _position);
  91. _position = i;
  92. return res;
  93. }
  94. i++;
  95. count++;
  96. }
  97. if (i > _position) {
  98. string res = _data.Substring(_position, i - _position);
  99. _position = i;
  100. return res;
  101. }
  102. return "";
  103. }
  104. public string ReadToEnd() {
  105. if (_position < _length) {
  106. string res = _data.Substring(_position);
  107. _position = _length;
  108. return res;
  109. } else return "";
  110. }
  111. public void Reset() {
  112. _position = 0;
  113. }
  114. public int Seek(int offset, SeekOrigin origin) {
  115. switch (origin) {
  116. case SeekOrigin.Begin:
  117. _position = offset; break;
  118. case SeekOrigin.Current:
  119. _position = _position + offset; break;
  120. case SeekOrigin.End:
  121. _position = _length + offset; break;
  122. default:
  123. throw new ArgumentException("origin");
  124. }
  125. return _position;
  126. }
  127. public void Truncate() {
  128. _data = _data.Substring(0, _position);
  129. _length = _data.Length;
  130. }
  131. public void Truncate(int size) {
  132. if (size > _data.Length) {
  133. size = _data.Length;
  134. } else if (size < 0) {
  135. size = 0;
  136. }
  137. _data = _data.Substring(0, size);
  138. _position = size;
  139. _length = _data.Length;
  140. }
  141. internal void Write(string s) {
  142. string newData;
  143. int newPosition;
  144. if (_position > 0) {
  145. newData = _data.Substring(0, _position) + s;
  146. } else {
  147. newData = s;
  148. }
  149. newPosition = newData.Length;
  150. if (_position + s.Length < _length) {
  151. newData = newData + _data.Substring(_position + s.Length);
  152. }
  153. _data = newData;
  154. _position = newPosition;
  155. _length = _data.Length;
  156. }
  157. }
  158. public static class PythonStringIO {
  159. public static PythonType InputType = DynamicHelpers.GetPythonTypeFromType(typeof(StringI));
  160. public static PythonType OutputType = DynamicHelpers.GetPythonTypeFromType(typeof(StringO));
  161. public class StringI : IEnumerable<string>, IEnumerable {
  162. private StringStream _sr;
  163. internal StringI(string data) {
  164. _sr = new StringStream(data);
  165. }
  166. public void close() {
  167. _sr = null;
  168. }
  169. public bool closed {
  170. get {
  171. return _sr == null;
  172. }
  173. }
  174. public void flush() {
  175. ThrowIfClosed();
  176. }
  177. public string getvalue() {
  178. ThrowIfClosed();
  179. return _sr.Data;
  180. }
  181. public string getvalue(bool usePos) {
  182. return _sr.Prefix;
  183. }
  184. public object __iter__() {
  185. return this;
  186. }
  187. public string next() {
  188. ThrowIfClosed();
  189. if (_sr.EOF) {
  190. throw PythonOps.StopIteration();
  191. }
  192. return readline();
  193. }
  194. public string read() {
  195. ThrowIfClosed();
  196. return _sr.ReadToEnd();
  197. }
  198. public string read(int s) {
  199. ThrowIfClosed();
  200. return (s < 0) ? _sr.ReadToEnd() : _sr.Read(s);
  201. }
  202. public string readline() {
  203. ThrowIfClosed();
  204. return _sr.ReadLine(-1);
  205. }
  206. public string readline(int size) {
  207. ThrowIfClosed();
  208. return _sr.ReadLine(size);
  209. }
  210. public List readlines() {
  211. ThrowIfClosed();
  212. List list = PythonOps.MakeList();
  213. while (!_sr.EOF) {
  214. list.AddNoLock(readline());
  215. }
  216. return list;
  217. }
  218. public List readlines(int size) {
  219. ThrowIfClosed();
  220. List list = PythonOps.MakeList();
  221. while (!_sr.EOF) {
  222. string line = readline();
  223. list.AddNoLock(line);
  224. if (line.Length >= size) break;
  225. size -= line.Length;
  226. }
  227. return list;
  228. }
  229. public void reset() {
  230. ThrowIfClosed();
  231. _sr.Reset();
  232. }
  233. public void seek(int position) {
  234. seek(position, 0);
  235. }
  236. public void seek(int position, int mode) {
  237. ThrowIfClosed();
  238. SeekOrigin so;
  239. switch (mode) {
  240. case 1: so = SeekOrigin.Current; break;
  241. case 2: so = SeekOrigin.End; break;
  242. default: so = SeekOrigin.Begin; break;
  243. }
  244. _sr.Seek(position, so);
  245. }
  246. public int tell() {
  247. ThrowIfClosed();
  248. return _sr.Position;
  249. }
  250. public void truncate() {
  251. ThrowIfClosed();
  252. _sr.Truncate();
  253. }
  254. public void truncate(int size) {
  255. ThrowIfClosed();
  256. _sr.Truncate(size);
  257. }
  258. private void ThrowIfClosed() {
  259. if (closed) {
  260. throw PythonOps.ValueError("I/O operation on closed file");
  261. }
  262. }
  263. #region IEnumerable Members
  264. IEnumerator IEnumerable.GetEnumerator() {
  265. while (!_sr.EOF) {
  266. yield return readline();
  267. }
  268. }
  269. #endregion
  270. #region IEnumerable<string> Members
  271. IEnumerator<string> IEnumerable<string>.GetEnumerator() {
  272. while (!_sr.EOF) {
  273. yield return readline();
  274. }
  275. }
  276. #endregion
  277. }
  278. public class StringO : IEnumerable<string>, IEnumerable {
  279. private StringWriter _sw = new StringWriter();
  280. private StringStream _sr = new StringStream("");
  281. private int _softspace;
  282. internal StringO() {
  283. }
  284. public object __iter__() {
  285. return this;
  286. }
  287. public void close() {
  288. if (_sw != null) { _sw.Close(); _sw = null; }
  289. if (_sr != null) { _sr = null; }
  290. }
  291. public bool closed {
  292. get {
  293. return _sw == null || _sr == null;
  294. }
  295. }
  296. public void flush() {
  297. FixStreams();
  298. }
  299. public string getvalue() {
  300. ThrowIfClosed();
  301. FixStreams();
  302. return _sr.Data;
  303. }
  304. public string getvalue(bool usePos) {
  305. ThrowIfClosed();
  306. FixStreams();
  307. return _sr.Prefix;
  308. }
  309. public string next() {
  310. ThrowIfClosed();
  311. FixStreams();
  312. if (_sr.EOF) {
  313. throw PythonOps.StopIteration();
  314. }
  315. return readline();
  316. }
  317. public string read() {
  318. ThrowIfClosed();
  319. FixStreams();
  320. return _sr.ReadToEnd();
  321. }
  322. public string read(int i) {
  323. ThrowIfClosed();
  324. FixStreams();
  325. return (i < 0) ? _sr.ReadToEnd() : _sr.Read(i);
  326. }
  327. public string readline() {
  328. ThrowIfClosed();
  329. FixStreams();
  330. return _sr.ReadLine(-1);
  331. }
  332. public string readline(int size) {
  333. ThrowIfClosed();
  334. FixStreams();
  335. return _sr.ReadLine(size);
  336. }
  337. public List readlines() {
  338. ThrowIfClosed();
  339. List list = PythonOps.MakeList();
  340. while (!_sr.EOF) {
  341. list.AddNoLock(readline());
  342. }
  343. return list;
  344. }
  345. public List readlines(int size) {
  346. ThrowIfClosed();
  347. List list = PythonOps.MakeList();
  348. while (!_sr.EOF) {
  349. string line = readline();
  350. list.AddNoLock(line);
  351. if (line.Length >= size) break;
  352. size -= line.Length;
  353. }
  354. return list;
  355. }
  356. public void reset() {
  357. ThrowIfClosed();
  358. FixStreams();
  359. _sr.Reset();
  360. }
  361. public void seek(int position) {
  362. seek(position, 0);
  363. }
  364. public void seek(int offset, int origin) {
  365. ThrowIfClosed();
  366. FixStreams();
  367. SeekOrigin so;
  368. switch (origin) {
  369. case 1: so = SeekOrigin.Current; break;
  370. case 2: so = SeekOrigin.End; break;
  371. default: so = SeekOrigin.Begin; break;
  372. }
  373. _sr.Seek(offset, so);
  374. }
  375. public int softspace {
  376. get { return _softspace; }
  377. set { _softspace = value; }
  378. }
  379. public int tell() {
  380. ThrowIfClosed();
  381. FixStreams();
  382. return _sr.Position;
  383. }
  384. public void truncate() {
  385. ThrowIfClosed();
  386. FixStreams();
  387. _sr.Truncate();
  388. }
  389. public void truncate(int size) {
  390. ThrowIfClosed();
  391. FixStreams();
  392. _sr.Truncate(size);
  393. }
  394. public void write(string s) {
  395. ThrowIfClosed();
  396. _sw.Write(s);
  397. }
  398. public void writelines(object o) {
  399. ThrowIfClosed();
  400. IEnumerator e = PythonOps.GetEnumerator(o);
  401. while (e.MoveNext()) {
  402. string s = e.Current as string;
  403. if (s == null) {
  404. throw PythonOps.ValueError("string expected");
  405. }
  406. write(s);
  407. }
  408. }
  409. private void FixStreams() {
  410. if (_sr != null) {
  411. StringBuilder sb = _sw.GetStringBuilder();
  412. if (sb != null && sb.Length > 0) {
  413. _sr.Write(sb.ToString());
  414. sb.Length = 0;
  415. }
  416. }
  417. }
  418. private void ThrowIfClosed() {
  419. if (closed) {
  420. throw PythonOps.ValueError("I/O operation on closed file");
  421. }
  422. }
  423. #region IEnumerable Members
  424. IEnumerator IEnumerable.GetEnumerator() {
  425. while (!_sr.EOF) {
  426. yield return readline();
  427. }
  428. }
  429. #endregion
  430. #region IEnumerable<string> Members
  431. IEnumerator<string> IEnumerable<string>.GetEnumerator() {
  432. while (!_sr.EOF) {
  433. yield return readline();
  434. }
  435. }
  436. #endregion
  437. }
  438. public static object StringIO() {
  439. return new StringO();
  440. }
  441. public static object StringIO(string data) {
  442. return new StringI(data);
  443. }
  444. }
  445. }