forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathByteArrayIterator.cs
More file actions
90 lines (63 loc) · 2.54 KB
/
ByteArrayIterator.cs
File metadata and controls
90 lines (63 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections;
using System.Collections.Generic;
using IronPython.Modules;
using IronPython.Runtime.Operations;
using Microsoft.Scripting.Utils;
namespace IronPython.Runtime {
[PythonType("bytearray_iterator")]
public sealed class ByteArrayIterator : IEnumerable, IEnumerator<int> {
private IList<byte>? _bytes;
private int _index;
internal ByteArrayIterator(ByteArray bytes) {
Assert.NotNull(bytes);
_bytes = bytes;
_index = -1;
}
public int __length_hint__()
=> _bytes is null ? 0 : _bytes.Count - _index - 1;
#region Pickling Protocol
public PythonTuple __reduce__(CodeContext context) {
// Using BuiltinModuleInstance rather than GetBuiltinsDict() or TryLookupBuiltin() matches CPython 3.8.2 behaviour
// Older versions of CPython may have a different behaviour
object? iter = PythonOps.GetBoundAttr(context, context.LanguageContext.BuiltinModuleInstance, nameof(Builtin.iter));
if (_bytes is null) {
return PythonTuple.MakeTuple(iter, PythonTuple.MakeTuple(PythonTuple.EMPTY)); // CPython 3.7 uses empty tuple
}
return PythonTuple.MakeTuple(iter, PythonTuple.MakeTuple(_bytes), _index + 1);
}
public void __setstate__(int state) {
if (_bytes is null) return;
_index = Math.Min(Math.Max(0, state), _bytes.Count) - 1;
}
#endregion
#region IEnumerator<T> Members
[PythonHidden]
public int Current => _bytes![_index];
#endregion
#region IDisposable Members
[PythonHidden]
public void Dispose() { }
#endregion
#region IEnumerator Members
object IEnumerator.Current => ((IEnumerator<int>)this).Current;
[PythonHidden]
public bool MoveNext() {
if (_bytes is null || ++_index >= _bytes.Count) {
_bytes = null; // free after iteration
return false;
}
return true;
}
void IEnumerator.Reset() => throw new NotSupportedException();
#endregion
#region IEnumerable Members
[PythonHidden]
public IEnumerator GetEnumerator() => this;
#endregion
}
}