PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Languages/IronPython/IronPython.Modules/cStringIO.cs

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