Repository navigation
Expand file tree
/
Copy pathPointer.cs
More file actions
139 lines (120 loc) · 5.5 KB
/
Copy pathPointer.cs
File metadata and controls
139 lines (120 loc) · 5.5 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* [email protected]. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
#if FEATURE_NATIVE
using System;
using System.Text;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using IronPython.Runtime.Types;
namespace IronPython.Modules {
/// <summary>
/// Provides support for interop with native code from Python code.
/// </summary>
public static partial class CTypes {
[PythonType("_Pointer")]
public abstract class Pointer : CData {
#pragma warning disable 414 // unused field - we need to keep the object alive
private readonly CData _object;
#pragma warning restore 414
public Pointer() {
_memHolder = new MemoryHolder(IntPtr.Size);
}
public Pointer(CData value) {
_object = value; // Keep alive the object, more to do here.
_memHolder = new MemoryHolder(IntPtr.Size);
_memHolder.WriteIntPtr(0, value._memHolder);
_memHolder.AddObject("1", value);
if (value._objects != null) {
_memHolder.AddObject("0", value._objects);
}
}
public object contents {
get {
PythonType elementType = (PythonType)((PointerType)NativeType)._type;
CData res = (CData)elementType.CreateInstance(elementType.Context.SharedContext);
res._memHolder = _memHolder.ReadMemoryHolder(0);
if(res._memHolder.UnsafeAddress == IntPtr.Zero) {
throw PythonOps.ValueError("NULL value access");
}
return res;
}
set {
}
}
public object this[int index] {
get {
INativeType type = ((PointerType)NativeType)._type;
MemoryHolder address = _memHolder.ReadMemoryHolder(0);
return type.GetValue(address, this, checked(type.Size * index), false);
}
set {
MemoryHolder address = _memHolder.ReadMemoryHolder(0);
INativeType type = ((PointerType)NativeType)._type;
object keepAlive = type.SetValue(address, checked(type.Size * index), value);
if (keepAlive != null) {
_memHolder.AddObject(index.ToString(), keepAlive);
}
}
}
public bool __nonzero__() {
return _memHolder.ReadIntPtr(0) != IntPtr.Zero;
}
public object this[Slice index] {
get {
if (index.stop == null) {
throw PythonOps.ValueError("slice stop is required");
}
int start = index.start != null ? (int)index.start : 0;
int stop = index.stop != null ? (int)index.stop : 0;
int step = index.step != null ? (int)index.step : 1;
if (step < 0 && index.start == null) {
throw PythonOps.ValueError("slice start is required for step < 0");
}
if (start < 0) {
start = 0;
}
INativeType type = ((PointerType)NativeType)._type;
SimpleType elemType = type as SimpleType;
if ((stop < start && step > 0) || (start < stop && step < 0)) {
if (elemType != null && (elemType._type == SimpleTypeKind.WChar || elemType._type == SimpleTypeKind.Char)) {
return String.Empty;
}
return new List();
}
MemoryHolder address = _memHolder.ReadMemoryHolder(0);
if (elemType != null && (elemType._type == SimpleTypeKind.WChar || elemType._type == SimpleTypeKind.Char)) {
int elmSize = ((INativeType)elemType).Size;
StringBuilder res = new StringBuilder();
for (int i = start; stop > start ? i < stop : i > stop; i += step) {
res.Append(
elemType.ReadChar(address, checked(i * elmSize))
);
}
return res.ToString();
} else {
List res = new List((stop - start) / step);
for (int i = start; stop > start ? i < stop : i > stop; i += step) {
res.AddNoLock(
type.GetValue(address, this, checked(type.Size * i), false)
);
}
return res;
}
}
}
}
}
}
#endif