/Languages/IronPython/IronPython.Modules/_io.cs
C# | 3242 lines | 2631 code | 543 blank | 68 comment | 588 complexity | 168cc533ecd4451efb57ef8f12aec1b3 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Microsoft Public License. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Microsoft Public License, please send an email to
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Microsoft Public License.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
- #if FEATURE_CORE_DLR
- using System.Linq.Expressions;
- #else
- using Microsoft.Scripting.Ast;
- #endif
- #if FEATURE_NUMERICS
- using System.Numerics;
- #else
- using Microsoft.Scripting.Math;
- #endif
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Dynamic;
- using System.IO;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Text;
- using Microsoft.Scripting;
- using Microsoft.Scripting.Runtime;
- using Microsoft.Scripting.Utils;
- using IronPython.Runtime;
- using IronPython.Runtime.Binding;
- using IronPython.Runtime.Exceptions;
- using IronPython.Runtime.Operations;
- using IronPython.Runtime.Types;
- [assembly: PythonModule("_io", typeof(IronPython.Modules.PythonIOModule))]
- namespace IronPython.Modules {
- public static partial class PythonIOModule {
- public const int DEFAULT_BUFFER_SIZE = 8192;
- private static readonly object _blockingIOErrorKey = new object();
- private static readonly object _unsupportedOperationKey = new object();
- [SpecialName]
- public static void PerformModuleReload(PythonContext/*!*/ context, PythonDictionary/*!*/ dict) {
- PythonType t = context.EnsureModuleException(
- _blockingIOErrorKey,
- PythonExceptions.IOError,
- typeof(BlockingIOError),
- dict,
- "BlockingIOError",
- "__builtin__",
- msg => new _BlockingIOErrorException(msg)
- );
- // this makes repr work correctly (gh878)
- t.IsSystemType = true;
- context.EnsureModuleException(
- _unsupportedOperationKey,
- new PythonType[] { PythonExceptions.ValueError, PythonExceptions.IOError },
- typeof(PythonExceptions.BaseException),
- dict,
- "UnsupportedOperation",
- "io"
- );
- }
- [PythonType]
- public class _IOBase : IDisposable, IEnumerator<object>, IEnumerable<object>, IWeakReferenceable, IDynamicMetaObjectProvider, IPythonExpandable {
- private bool _closed;
- internal CodeContext/*!*/ context;
- public _IOBase(CodeContext/*!*/ context) {
- this.context = context;
- }
- #region Public API
- public void __del__(CodeContext/*!*/ context) {
- close(context);
- }
- public _IOBase __enter__() {
- _checkClosed();
- return this;
- }
- public void __exit__(CodeContext/*!*/ context, params object[] excinfo) {
- close(context);
- }
- public void _checkClosed() {
- _checkClosed(null);
- }
- public void _checkClosed(string msg) {
- if (closed) {
- throw PythonOps.ValueError(msg ?? "I/O operation on closed file.");
- }
- }
- public void _checkReadable() {
- _checkReadable(null);
- }
- public void _checkReadable(string msg) {
- if (!readable(context)) {
- throw PythonOps.ValueError(msg ?? "File or stream is not readable.");
- }
- }
- public void _checkSeekable() {
- _checkSeekable(null);
- }
- public void _checkSeekable(string msg) {
- if (!seekable(context)) {
- throw PythonOps.ValueError(msg ?? "File or stream is not seekable.");
- }
- }
- public void _checkWritable() {
- _checkWritable(null);
- }
- public void _checkWritable(string msg) {
- if (!writable(context)) {
- throw PythonOps.ValueError(msg ?? "File or stream is not writable.");
- }
- }
- public virtual void close(CodeContext/*!*/ context) {
- try {
- if (!_closed) {
- flush(context);
- }
- } finally {
- _closed = true;
- }
- }
- public virtual bool closed {
- get { return _closed; }
- }
- public virtual int fileno(CodeContext/*!*/ context) {
- throw UnsupportedOperation(context, "fileno");
- }
- public virtual void flush(CodeContext/*!*/ context) {
- _checkClosed();
- }
- public virtual bool isatty(CodeContext/*!*/ context) {
- _checkClosed();
- return false;
- }
- [PythonHidden]
- public virtual Bytes peek(CodeContext/*!*/ context, [DefaultParameterValue(0)]int length) {
- _checkClosed();
- throw AttributeError("peek");
- }
- [PythonHidden]
- public virtual object read(CodeContext/*!*/ context, [DefaultParameterValue(null)]object length) {
- throw AttributeError("read");
- }
- [PythonHidden]
- public virtual Bytes read1(CodeContext/*!*/ context, [DefaultParameterValue(0)]int length) {
- throw AttributeError("read1");
- }
- public virtual bool readable(CodeContext/*!*/ context) {
- return false;
- }
- public virtual object readline(CodeContext/*!*/ context, int limit) {
- _checkClosed();
- List<Bytes> res = new List<Bytes>();
- int count = 0;
- while (limit < 0 || res.Count < limit) {
- object cur = read(context, 1);
- if (cur == null) {
- break;
- }
-
- Bytes curBytes = GetBytes(cur, "read()");
- if (curBytes.Count == 0) {
- break;
- }
- res.Add(curBytes);
- count += curBytes.Count;
- if (curBytes._bytes[curBytes.Count - 1] == (byte)'\n') {
- break;
- }
- }
- return Bytes.Concat(res, count);
- }
- public object readline(CodeContext/*!*/ context, [DefaultParameterValue(null)]object limit) {
- return readline(context, GetInt(limit, -1));
- }
- public virtual List readlines() {
- return readlines(null);
- }
- public virtual List readlines([DefaultParameterValue(null)]object hint) {
- int size = GetInt(hint, -1);
- List res = new List();
- if (size <= 0) {
- foreach (object line in this) {
- res.AddNoLock(line);
- }
- return res;
- }
- int count = 0;
- foreach (object line in this) {
- Bytes bytes = line as Bytes;
- if (bytes != null) {
- res.AddNoLock(line);
- count += bytes.Count;
- if (count >= size) {
- break;
- }
- continue;
- }
- string str = line as string;
- if (str != null) {
- res.AddNoLock(line);
- count += str.Length;
- if (count >= size) {
- break;
- }
- continue;
- }
- throw PythonOps.TypeError("next() should return string or bytes");
- }
- return res;
- }
- public virtual BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
- throw UnsupportedOperation(context, "seek");
- }
- public virtual bool seekable(CodeContext/*!*/ context) {
- return false;
- }
- public virtual BigInteger tell(CodeContext/*!*/ context) {
- return seek(context, 0, 1);
- }
- public virtual BigInteger truncate(CodeContext/*!*/ context, [DefaultParameterValue(null)]object pos) {
- throw UnsupportedOperation(context, "truncate");
- }
- public virtual bool writable(CodeContext/*!*/ context) {
- return false;
- }
- [PythonHidden]
- public virtual BigInteger write(CodeContext/*!*/ context, object buf) {
- throw AttributeError("write");
- }
- public virtual void writelines(CodeContext/*!*/ context, object lines) {
- _checkClosed();
- IEnumerator en = PythonOps.GetEnumerator(context, lines);
- while (en.MoveNext()) {
- write(context, en.Current);
- }
- }
- #endregion
- ~_IOBase() {
- try {
- close(context);
- } catch { }
- }
- #region IEnumerator<object> Members
- private object _current;
- object IEnumerator<object>.Current {
- get { return _current; }
- }
- #endregion
- #region IEnumerator Members
- object IEnumerator.Current {
- get { return _current; }
- }
- bool IEnumerator.MoveNext() {
- _current = readline(context, -1);
- if (_current == null) {
- return false;
- }
- Bytes bytes = _current as Bytes;
- if (bytes != null) {
- return bytes.Count > 0;
- }
- string str = _current as string;
- if (str != null) {
- return str.Length > 0;
- }
- return PythonOps.IsTrue(_current);
- }
- void IEnumerator.Reset() {
- _current = null;
- seek(context, 0, 0);
- }
- #endregion
- #region IEnumerable<object> Members
- [PythonHidden]
- public IEnumerator<object> GetEnumerator() {
- _checkClosed();
- return this;
- }
- #endregion
- #region IEnumerable Members
- IEnumerator IEnumerable.GetEnumerator() {
- _checkClosed();
- return this;
- }
- #endregion
- #region IDisposable Members
- void IDisposable.Dispose() { }
- #endregion
- #region IWeakReferenceable Members
- private WeakRefTracker _weakref;
- WeakRefTracker IWeakReferenceable.GetWeakRef() {
- return _weakref;
- }
- bool IWeakReferenceable.SetWeakRef(WeakRefTracker value) {
- _weakref = value;
- return true;
- }
- void IWeakReferenceable.SetFinalizer(WeakRefTracker value) {
- ((IWeakReferenceable)this).SetWeakRef(value);
- }
- #endregion
- #region IPythonExpandable Members
- private IDictionary<string, object> _customAttributes;
- IDictionary<string, object> IPythonExpandable.EnsureCustomAttributes() {
- return _customAttributes = new Dictionary<string, object>();
- }
- IDictionary<string, object> IPythonExpandable.CustomAttributes {
- get { return _customAttributes; }
- }
- CodeContext/*!*/ IPythonExpandable.Context {
- get { return context; }
- }
- #endregion
- #region IDynamicMetaObjectProvider Members
-
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<_IOBase>(parameter, this);
- }
-
- #endregion
- #region Private implementation details
- internal Exception UnsupportedOperation(CodeContext/*!*/ context, string attr) {
- throw PythonExceptions.CreateThrowable(
- (PythonType)PythonContext.GetContext(context).GetModuleState(_unsupportedOperationKey),
- string.Format("{0}.{1} not supported", PythonTypeOps.GetName(this), attr)
- );
- }
- internal Exception AttributeError(string attrName) {
- throw PythonOps.AttributeError("'{0}' object has no attribute '{1}'", PythonTypeOps.GetName(this), attrName);
- }
- internal Exception InvalidPosition(BigInteger pos) {
- return PythonOps.IOError("Raw stream returned invalid position {0}", pos);
- }
-
- #endregion
- }
- [PythonType]
- public class _RawIOBase : _IOBase, IDynamicMetaObjectProvider {
- public _RawIOBase(CodeContext/*!*/ context) : base(context) { }
- #region Public API
- public override object read(CodeContext/*!*/ context, [DefaultParameterValue(null)]object size) {
- int sizeInt = GetInt(size, -1);
- if (sizeInt < 0) {
- return readall(context);
- }
- ByteArray arr = new ByteArray(new List<byte>(sizeInt));
- sizeInt = (int)readinto(context, arr);
- List<byte> res = arr._bytes;
- if (sizeInt < res.Count) {
- res.RemoveRange(sizeInt, res.Count - sizeInt);
- }
- return new Bytes(res);
- }
- public Bytes readall(CodeContext/*!*/ context) {
- List<Bytes> res = new List<Bytes>();
- int count = 0;
- for (; ; ) {
- object cur = read(context, DEFAULT_BUFFER_SIZE);
- if (cur == null) {
- break;
- }
- Bytes curBytes = GetBytes(cur, "read()");
- if (curBytes.Count == 0) {
- break;
- }
- count += curBytes.Count;
- res.Add(curBytes);
- }
- return Bytes.Concat(res, count);
- }
- public virtual BigInteger readinto(CodeContext/*!*/ context, object buf) {
- throw UnsupportedOperation(context, "readinto");
- }
- public override BigInteger write(CodeContext/*!*/ context, object buf) {
- throw UnsupportedOperation(context, "write");
- }
- #endregion
-
- #region IDynamicMetaObjectProvider Members
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<_RawIOBase>(parameter, this);
- }
- #endregion
- }
- [PythonType]
- public class _BufferedIOBase : _IOBase, IDynamicMetaObjectProvider {
- public _BufferedIOBase(CodeContext/*!*/ context) : base(context) { }
- #region Public API
- public virtual object detach(CodeContext/*!*/ context) {
- throw UnsupportedOperation(context, "detach");
- }
- public override object read(CodeContext/*!*/ context, [DefaultParameterValue(null)]object length) {
- throw UnsupportedOperation(context, "read");
- }
- public virtual BigInteger readinto(CodeContext/*!*/ context, object buf) {
- int length = -1;
- if (PythonOps.HasAttr(context, buf, "__len__")) {
- length = PythonOps.Length(buf);
- }
- object dataObj = read(context, length);
- if (dataObj == null) {
- return BigInteger.Zero;
- }
- Bytes data = GetBytes(dataObj, "read()");
- IList<byte> bytes = buf as IList<byte>;
- if (bytes != null) {
- for (int i = 0; i < data.Count; i++) {
- bytes[i] = data._bytes[i];
- }
- GC.KeepAlive(this);
- return data.Count;
- }
- object setter;
- if (PythonOps.TryGetBoundAttr(buf, "__setslice__", out setter)) {
- PythonOps.CallWithContext(context, setter, new Slice(data.Count), data);
- GC.KeepAlive(this);
- return data.Count;
- }
- if (PythonOps.TryGetBoundAttr(buf, "__setitem__", out setter)) {
- for (int i = 0; i < data.Count; i++) {
- PythonOps.CallWithContext(context, setter, i, data[context, i]);
- }
- GC.KeepAlive(this);
- return data.Count;
- }
- throw PythonOps.TypeError("must be read-write buffer, not " + PythonTypeOps.GetName(buf));
- }
- public override BigInteger write(CodeContext/*!*/ context, object buf) {
- throw UnsupportedOperation(context, "write");
- }
- #endregion
- #region IDynamicMetaObjectProvider Members
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<_BufferedIOBase>(parameter, this);
- }
- #endregion
- }
- [PythonType]
- public class _TextIOBase : _IOBase, IDynamicMetaObjectProvider {
- public _TextIOBase(CodeContext/*!*/ context) : base(context) { }
- #region Public API
- public virtual object detach(CodeContext/*!*/ context) {
- throw UnsupportedOperation(context, "detach");
- }
- public virtual string encoding {
- get { return null; }
- }
- public virtual string errors {
- get { return null; }
- }
- public virtual object newlines {
- get { return null; }
- }
- public override object read(CodeContext/*!*/ context, [DefaultParameterValue(-1)]object length) {
- throw UnsupportedOperation(context, "read");
- }
- public override object readline(CodeContext/*!*/ context, [DefaultParameterValue(-1)]int limit) {
- throw UnsupportedOperation(context, "readline");
- }
- public override BigInteger truncate(CodeContext/*!*/ context, [DefaultParameterValue(null)]object pos) {
- throw UnsupportedOperation(context, "truncate");
- }
- public override BigInteger write(CodeContext/*!*/ context, object str) {
- throw UnsupportedOperation(context, "write");
- }
- #endregion
- #region IDynamicMetaObjectProvider Members
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<_TextIOBase>(parameter, this);
- }
- #endregion
- }
- [PythonType]
- public class BufferedReader : _BufferedIOBase, IDynamicMetaObjectProvider {
- private _IOBase _rawIO;
- private object _raw;
- private int _bufSize;
- private Bytes _readBuf;
- private int _readBufPos;
- internal static BufferedReader Create(CodeContext/*!*/ context, object raw, [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size) {
- var res = new BufferedReader(context, raw, buffer_size);
- res.__init__(context, raw, buffer_size);
- return res;
- }
- public BufferedReader(
- CodeContext/*!*/ context,
- object raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size
- ) : base(context) {
- }
- public void __init__(
- CodeContext/*!*/ context,
- object raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size
- ) {
- this.raw = raw;
- if (_rawIO != null) {
- if (!_rawIO.readable(context)) {
- throw PythonOps.IOError("\"raw\" argument must be readable.");
- }
- } else {
- if (PythonOps.Not(PythonOps.Invoke(context, _raw, "readable"))) {
- throw PythonOps.IOError("\"raw\" argument must be readable.");
- }
- }
- if (buffer_size <= 0) {
- throw PythonOps.ValueError("invalid buffer size (must be positive)");
- }
- _bufSize = buffer_size;
- _readBuf = Bytes.Empty;
- }
- #region Public API
- public object raw {
- get {
- return _raw;
- }
- set {
- _rawIO = value as _IOBase;
- _raw = value;
- }
- }
- #region _BufferedIOMixin
- public override BigInteger truncate(CodeContext/*!*/ context, [DefaultParameterValue(null)]object pos) {
- if (_rawIO != null) {
- return _rawIO.truncate(context, pos);
- }
- return GetBigInt(
- PythonOps.Invoke(context, _raw, "truncate", pos),
- "truncate() should return integer"
- );
- }
- public override void close(CodeContext/*!*/ context) {
- if (!closed) {
- try {
- flush(context);
- } finally {
- if (_rawIO != null) {
- _rawIO.close(context);
- } else {
- PythonOps.Invoke(context, _raw, "close");
- }
- }
- }
- }
- public override object detach(CodeContext/*!*/ context) {
- if (_raw == null) {
- throw PythonOps.ValueError("raw stream already detached");
- }
- flush(context);
- object res = _raw;
- raw = null;
- return res;
- }
- public override bool seekable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- return _rawIO.seekable(context);
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "seekable"));
- }
- public override bool readable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- return _rawIO.readable(context);
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "readable"));
- }
- public override bool writable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- return _rawIO.writable(context);
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "writable"));
- }
- public override bool closed {
- get {
- if (_rawIO != null) {
- return _rawIO.closed;
- }
- return PythonOps.IsTrue(PythonOps.GetBoundAttr(context, _raw, "closed"));
- }
- }
- public object name {
- get {
- return PythonOps.GetBoundAttr(context, _raw, "name");
- }
- }
- public object mode {
- get {
- return PythonOps.GetBoundAttr(context, _raw, "mode");
- }
- }
- public override int fileno(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- return _rawIO.fileno(context);
- }
- return GetInt(
- PythonOps.Invoke(context, _raw, "fileno"),
- "fileno() should return integer"
- );
- }
- public override bool isatty(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- return _rawIO.isatty(context);
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "isatty"));
- }
- #endregion
- public override object read(CodeContext/*!*/ context, [DefaultParameterValue(null)]object length) {
- int len = GetInt(length, -1);
- if (len < -1) {
- throw PythonOps.ValueError("invalid number of bytes to read");
- }
- lock (this) {
- return ReadNoLock(context, len);
- }
- }
- private Bytes ReadNoLock(CodeContext/*!*/ context, int length) {
- if (length == 0) {
- return Bytes.Empty;
- }
- if (length < 0) {
- List<Bytes> chunks = new List<Bytes>();
- int count = 0;
- if (_readBuf.Count > 0) {
- chunks.Add(ResetReadBuf());
- count += chunks[0].Count;
- }
- for (; ; ) {
- object chunkObj;
- if (_rawIO != null) {
- chunkObj = _rawIO.read(context, -1);
- } else {
- chunkObj = PythonOps.Invoke(context, _raw, "read", -1);
- }
- Bytes chunk = GetBytes(chunkObj, "read()");
- if (chunk == null || chunk.Count == 0) {
- if (count == 0) {
- return chunk;
- }
- break;
- }
- chunks.Add(chunk);
- count += chunk.Count;
- }
- GC.KeepAlive(this);
- return Bytes.Concat(chunks, count);
- }
- if (length < _readBuf.Count - _readBufPos) {
- // requested data is already buffered
- byte[] res = new byte[length];
- Array.Copy(_readBuf._bytes, _readBufPos, res, 0, length);
- _readBufPos += length;
- if (_readBufPos == _readBuf.Count) {
- ResetReadBuf();
- }
- GC.KeepAlive(this);
- return Bytes.Make(res);
- } else {
- // a read is required to provide requested amount of data
- List<Bytes> chunks = new List<Bytes>();
- int remaining = length;
- if (_readBuf.Count > 0) {
- chunks.Add(ResetReadBuf());
- remaining -= chunks[0].Count;
- }
- while (remaining > 0) {
- object chunkObj;
- if (_rawIO != null) {
- chunkObj = _rawIO.read(context, _bufSize);
- } else {
- chunkObj = PythonOps.Invoke(context, _raw, "read", _bufSize);
- }
- Bytes chunk = chunkObj != null ? GetBytes(chunkObj, "read()") : Bytes.Empty;
- _readBuf = chunk;
- if (_readBuf.Count == 0) {
- break;
- }
- if (remaining >= _readBuf.Count - _readBufPos) {
- remaining -= _readBuf.Count - _readBufPos;
- chunks.Add(ResetReadBuf());
- } else {
- byte[] bytes = new byte[remaining];
- Array.Copy(_readBuf._bytes, 0, bytes, 0, remaining);
- chunks.Add(Bytes.Make(bytes));
- _readBufPos = remaining;
- remaining = 0;
- break;
- }
- }
- GC.KeepAlive(this);
- return Bytes.Concat(chunks, length - remaining);
- }
- }
- public override Bytes peek(CodeContext/*!*/ context, [DefaultParameterValue(0)]int length) {
- _checkClosed();
- if (length <= 0 || length > _bufSize) {
- length = _bufSize;
- }
- lock (this) {
- return PeekNoLock(context, length);
- }
- }
- private Bytes PeekNoLock(CodeContext/*!*/ context, int length) {
- int bufLen = _readBuf.Count - _readBufPos;
- byte[] bytes = new byte[length];
- if (length <= bufLen) {
- Array.Copy(_readBuf._bytes, _readBufPos, bytes, 0, length);
- return Bytes.Make(bytes);
- }
- object nextObj;
- if (_rawIO != null) {
- nextObj = _rawIO.read(context, length - _readBuf.Count + _readBufPos);
- } else {
- nextObj = PythonOps.Invoke(context, _raw, "read", length - _readBuf.Count + _readBufPos);
- }
- Bytes next = nextObj != null ? GetBytes(nextObj, "read()") : Bytes.Empty;
- _readBuf = ResetReadBuf() + next;
- return _readBuf;
- }
- public override Bytes read1(CodeContext/*!*/ context, [DefaultParameterValue(0)]int length) {
- if (length == 0) {
- return Bytes.Empty;
- } else if (length < 0) {
- throw PythonOps.ValueError("number of bytes to read must be positive");
- }
- lock (this) {
- PeekNoLock(context, 1);
- return ReadNoLock(context, Math.Min(length, _readBuf.Count - _readBufPos));
- }
- }
- public override BigInteger tell(CodeContext/*!*/ context) {
- BigInteger res = _rawIO != null ?
- _rawIO.tell(context) :
- GetBigInt(
- PythonOps.Invoke(context, _raw, "tell"),
- "tell() should return integer"
- );
- if (res < 0) {
- throw InvalidPosition(res);
- }
- return res - _readBuf.Count + _readBufPos;
- }
- public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
- _checkClosed();
- throw PythonOps.TypeError("an integer is required");
- }
- public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
- int whenceInt = GetInt(whence);
- if (whenceInt < 0 || whenceInt > 2) {
- throw PythonOps.ValueError("invalid whence ({0}, should be 0, 1, or 2)", whenceInt);
- }
- lock (this) {
- if (whenceInt == 1) {
- pos -= _readBuf.Count - _readBufPos;
- }
- object posObj;
- if (_rawIO != null) {
- posObj = _rawIO.seek(context, pos, whenceInt);
- } else {
- posObj = PythonOps.Invoke(context, _raw, "seek", whenceInt);
- }
- pos = GetBigInt(posObj, "seek() should return integer");
- ResetReadBuf();
- if (pos < 0) {
- throw InvalidPosition(pos);
- }
- GC.KeepAlive(this);
- return pos;
- }
- }
- #endregion
- #region IDynamicMetaObjectProvider Members
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<BufferedReader>(parameter, this);
- }
- #endregion
- #region Private implementation details
- private Bytes ResetReadBuf() {
- Bytes res;
- if (_readBufPos == 0) {
- res = _readBuf;
- } else {
- byte[] bytes = new byte[_readBuf.Count - _readBufPos];
- Array.Copy(_readBuf._bytes, _readBufPos, bytes, 0, bytes.Length);
- res = Bytes.Make(bytes);
- _readBufPos = 0;
- }
- _readBuf = Bytes.Empty;
-
- return res;
- }
- #endregion
- }
- [PythonType]
- public class BufferedWriter : _BufferedIOBase, IDynamicMetaObjectProvider {
- private _IOBase _rawIO;
- private object _raw;
- private int _bufSize;
- private List<byte> _writeBuf;
- internal static BufferedWriter Create(CodeContext/*!*/ context,
- object raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size) {
- var res = new BufferedWriter(context, raw, buffer_size, max_buffer_size);
- res.__init__(context, raw, buffer_size, max_buffer_size);
- return res;
- }
- public BufferedWriter(
- CodeContext/*!*/ context,
- object raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size
- )
- : base(context) {
- }
- public void __init__(
- CodeContext/*!*/ context,
- object raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size
- ) {
- if (max_buffer_size != null) {
- PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "max_buffer_size is deprecated");
- }
- this.raw = raw;
- if (_rawIO != null) {
- if (!_rawIO.writable(context)) {
- throw PythonOps.IOError("\"raw\" argument must be writable.");
- }
- } else {
- if (PythonOps.Not(PythonOps.Invoke(context, _raw, "writable"))) {
- throw PythonOps.IOError("\"raw\" argument must be writable.");
- }
- }
- if (buffer_size <= 0) {
- throw PythonOps.ValueError("invalid buffer size (must be positive)");
- }
- _bufSize = buffer_size;
- _writeBuf = new List<byte>();
- }
- #region Public API
- public object raw {
- get {
- return _raw;
- }
- set {
- _rawIO = value as _IOBase;
- _raw = value;
- }
- }
- #region _BufferedIOMixin
- public override void close(CodeContext/*!*/ context) {
- if (!closed) {
- try {
- flush(context);
- } finally {
- if (_rawIO != null) {
- _rawIO.close(context);
- } else {
- PythonOps.Invoke(context, _raw, "close");
- }
- }
- }
- }
- public override object detach(CodeContext/*!*/ context) {
- if (_raw == null) {
- throw PythonOps.ValueError("raw stream already detached");
- }
- flush(context);
- object res = _raw;
- raw = null;
- return res;
- }
- public override bool seekable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- var res = _rawIO.seekable(context);
- GC.KeepAlive(this);
- return res;
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "seekable"));
- }
- public override bool readable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- var res = _rawIO.readable(context);
- GC.KeepAlive(this);
- return res;
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "readable"));
- }
- public override bool writable(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- var res = _rawIO.writable(context);
- GC.KeepAlive(this);
- return res;
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "writable"));
- }
- public override bool closed {
- get {
- if (_rawIO != null) {
- return _rawIO.closed;
- }
- return PythonOps.IsTrue(PythonOps.GetBoundAttr(context, _raw, "closed"));
- }
- }
- public object name {
- get {
- return PythonOps.GetBoundAttr(context, _raw, "name");
- }
- }
- public object mode {
- get {
- return PythonOps.GetBoundAttr(context, _raw, "mode");
- }
- }
- public override int fileno(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- var res = _rawIO.fileno(context);
- GC.KeepAlive(this);
- return res;
- }
- return GetInt(
- PythonOps.Invoke(context, _raw, "fileno"),
- "fileno() should return integer"
- );
- }
- public override bool isatty(CodeContext/*!*/ context) {
- if (_rawIO != null) {
- var res = _rawIO.isatty(context);
- GC.KeepAlive(this);
- return res;
- }
- return PythonOps.IsTrue(PythonOps.Invoke(context, _raw, "isatty"));
- }
- #endregion
- public override BigInteger write(CodeContext/*!*/ context, object buf) {
- _checkClosed("write to closed file");
- IList<byte> bytes = GetBytes(buf);
- lock (this) {
- if (_writeBuf.Count > _bufSize) {
- FlushNoLock(context);
- }
- int count = _writeBuf.Count;
- _writeBuf.AddRange(bytes);
- count = _writeBuf.Count - count;
- if (_writeBuf.Count > _bufSize) {
- try {
- FlushNoLock(context);
- } catch (_BlockingIOErrorException) {
- if (_writeBuf.Count > _bufSize) {
- // do a partial write
- int extra = _writeBuf.Count - _bufSize;
- count -= extra;
- _writeBuf.RemoveRange(_bufSize, extra);
- }
- throw;
- }
- }
- return count;
- }
- }
- public override BigInteger truncate(CodeContext/*!*/ context, [DefaultParameterValue(null)]object pos) {
- lock (this) {
- FlushNoLock(context);
- if (pos == null) {
- if (_rawIO != null) {
- pos = _rawIO.tell(context);
- } else {
- pos = GetBigInt(
- PythonOps.Invoke(context, _raw, "tell"),
- "tell() should return integer"
- );
- }
- }
- if (_rawIO != null) {
- return _rawIO.truncate(context, pos);
- }
- var res = GetBigInt(
- PythonOps.Invoke(context, _raw, "truncate", pos),
- "truncate() should return integer"
- );
- GC.KeepAlive(this);
- return res;
- }
- }
- public override void flush(CodeContext/*!*/ context) {
- lock (this) {
- FlushNoLock(context);
- }
- }
- private void FlushNoLock(CodeContext/*!*/ context) {
- _checkClosed("flush of closed file");
- int count = 0;
- try {
- while (_writeBuf.Count > 0) {
- object writtenObj;
- if (_rawIO != null) {
- writtenObj = _rawIO.write(context, _writeBuf);
- } else {
- writtenObj = PythonOps.Invoke(context, _raw, "write", _writeBuf);
- }
- int written = GetInt(writtenObj, "write() should return integer");
- if (written > _writeBuf.Count || written < 0) {
- throw PythonOps.IOError("write() returned incorrect number of bytes");
- }
- _writeBuf.RemoveRange(0, written);
- count += written;
- }
- } catch (_BlockingIOErrorException e) {
- object w;
- int written;
- if (!PythonOps.TryGetBoundAttr(e, "characters_written", out w) ||
- !TryGetInt(w, out written)) {
- throw;
- }
- _writeBuf.RemoveRange(0, written);
- count += written;
- throw;
- }
- }
- public override BigInteger tell(CodeContext/*!*/ context) {
- BigInteger res = _rawIO != null ?
- _rawIO.tell(context) :
- GetBigInt(
- PythonOps.Invoke(context, _raw, "tell"),
- "tell() should return integer"
- );
- if (res < 0) {
- throw InvalidPosition(res);
- }
- GC.KeepAlive(this);
- return res + _writeBuf.Count;
- }
- public BigInteger seek(double offset, [DefaultParameterValue(0)]object whence) {
- _checkClosed();
- throw PythonOps.TypeError("an integer is required");
- }
- public override BigInteger seek(CodeContext/*!*/ context, BigInteger pos, [DefaultParameterValue(0)]object whence) {
- int whenceInt = GetInt(whence);
- if (whenceInt < 0 || whenceInt > 2) {
- throw PythonOps.ValueError("invalid whence ({0}, should be 0, 1, or 2)", whenceInt);
- }
- lock (this) {
- FlushNoLock(context);
- BigInteger res = _rawIO != null ?
- _rawIO.seek(context, pos, whenceInt) :
- res = GetBigInt(
- PythonOps.Invoke(context, _raw, "seek", pos, whenceInt),
- "seek() should return integer"
- );
- if (res < 0) {
- throw InvalidPosition(pos);
- }
- GC.KeepAlive(this);
- return res;
- }
- }
- #endregion
- #region IDynamicMetaObjectProvider Members
- DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
- return new MetaExpandable<BufferedWriter>(parameter, this);
- }
- #endregion
- }
- [PythonType]
- public class BufferedRandom : _BufferedIOBase, IDynamicMetaObjectProvider {
- private _IOBase _inner;
-
- private int _bufSize;
- private Bytes _readBuf;
- private int _readBufPos;
- private List<byte> _writeBuf;
- internal static BufferedRandom Create(CodeContext/*!*/ context,
- _IOBase raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size) {
- var res = new BufferedRandom(context, raw, buffer_size, max_buffer_size);
- res.__init__(context, raw, buffer_size, max_buffer_size);
- return res;
- }
- public BufferedRandom(
- CodeContext/*!*/ context,
- _IOBase raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size
- ) : base(context) {
- }
- public void __init__(
- CodeContext/*!*/ context,
- _IOBase raw,
- [DefaultParameterValue(DEFAULT_BUFFER_SIZE)]int buffer_size,
- [DefaultParameterValue(null)]object max_buffer_size
- ) {
- if (max_buffer_size != null) {
- PythonOps.Warn(context, PythonExceptions.DeprecationWarning, "max_buffer_size is deprecated");
- }
- raw._checkSeekable();
- if (buffer_size <= 0) {
- throw PythonOps.ValueError("invalid buffer size (must be positive)");
- } else if (!raw.readable(context)) {
- throw PythonOps.IOError("\"raw\" argument must be readable.");
- } else if (!raw.writable(context)) {
- throw PythonOps.IOError("\"raw\" argument must be writable.");
- }
- _bufSize = buffer_size;
- _inner = raw;
- _readBuf = Bytes.Empty;
- _writeBuf = new List<byte>();
- }
- #region Public API
- public _IOBase raw {
- get {
- return _inner;
- }
- set {
- _inner = value;
- }
- }
- #region _BufferedIOMixin
- public override void close(CodeContext/*!*/ context) {
- if (!closed) {
- try {
- flush(context);
- } finally {
- _inner.close(context);
- }
- }
- }
- public override object detach(CodeContext/*!*/ context) {
- if (_inner == null) {
- throw PythonOps.ValueError("raw stream already detached");
- }
- flush(context);
- _IOBase res = _inner;
- _inner = null;
- return res;
- }
- public override bool seekable(CodeContext/*!*/ context) {
- var res = _inner.seekable(context);
- GC.KeepAlive(this);
- return res;
- }
- public override bool readable(CodeContext/*!*/ context) {
- var res = _inner.readable(context);
- GC.KeepAlive(this);
- return res;
- }
- public override bool writable(CodeContext/*!*/ context) {
- var res = _inner.writable(context);
- GC.KeepAlive(this);
- return res;
- }
- public override bool closed {
- get { return _inner.closed; }
- }
- public object name {
- get {
- return PythonOps.GetBoundAttr(context, _inner, "name");
- }
- }
- public object mode {
- get {
- return PythonOps.GetBoundAttr(context, _inner, "mode");
- }
- }
- public override int fileno(CodeContext/*!*/ context) {
- var res = _inner.fileno(context);
- …
Large files files are truncated, but you can click here to view the full file