forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimpleCData.cs
More file actions
173 lines (144 loc) · 6.66 KB
/
SimpleCData.cs
File metadata and controls
173 lines (144 loc) · 6.66 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// 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.
#if FEATURE_CTYPES
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Microsoft.Scripting.Runtime;
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("_SimpleCData")]
public abstract class SimpleCData : CData, ICodeFormattable {
// members: __bool__ __new__ __repr__ __ctypes_from_outparam__ __doc__ __init__
protected SimpleCData() {
}
protected SimpleCData(params object[] args) {
}
public void __init__() {
_memHolder = new MemoryHolder(Size);
}
public void __init__(CodeContext/*!*/ context, object value) {
switch(((SimpleType)NativeType)._type) {
case SimpleTypeKind.Char:
{
if (value is IList<byte> t && t.Count == 1) {
value = Bytes.FromByte(t[0]);
} else if (value is int i) {
try {
value = Bytes.FromByte(checked((byte)i));
} catch (OverflowException) {
throw PythonOps.TypeError("one character bytes, bytearray or integer expected");
}
} else {
throw PythonOps.TypeError("one character bytes, bytearray or integer expected");
}
}
break;
case SimpleTypeKind.WChar: {
if (!(value is string t && t.Length == 1)) {
throw PythonOps.TypeError("one character unicode string expected");
}
}
break;
case SimpleTypeKind.SignedInt:
case SimpleTypeKind.SignedLong:
case SimpleTypeKind.SignedLongLong:
case SimpleTypeKind.SignedShort:
case SimpleTypeKind.UnsignedInt:
case SimpleTypeKind.UnsignedLong:
case SimpleTypeKind.UnsignedLongLong:
case SimpleTypeKind.UnsignedShort: {
object __int__ = null;
if (value is float || value is double) {
throw PythonOps.TypeError("int expected instead of float");
}
if (!(value is int || value is BigInteger || PythonOps.TryGetBoundAttr(value, "__int__", out __int__))) {
throw PythonOps.TypeError("an integer is required");
}
if (__int__ != null) {
value = PythonOps.CallWithContext(context, __int__);
}
}
break;
case SimpleTypeKind.Double:
case SimpleTypeKind.Single: {
object __float__ = null;
if (!(value is double || value is float || value is int || value is BigInteger || PythonOps.TryGetBoundAttr(value, "__float__", out __float__))) {
throw PythonOps.TypeError("a float is required");
}
if (value is BigInteger x) {
if (x > (BigInteger)double.MaxValue) {
throw PythonOps.OverflowError("long int too large to convert to float");
}
}
if (__float__ != null) {
value = PythonOps.CallWithContext(context, __float__);
}
}
break;
default:
break;
}
_memHolder = new MemoryHolder(Size);
NativeType.SetValue(_memHolder, 0, value);
if (IsString) {
_memHolder.AddObject("str", value);
}
}
// implemented as PropertyMethod's so that we can have delete
[PropertyMethod, SpecialName]
public void Setvalue(object value) {
NativeType.SetValue(_memHolder, 0, value);
if (IsString) {
_memHolder.AddObject("str", value);
}
}
[PropertyMethod, SpecialName]
public object Getvalue() {
return NativeType.GetValue(_memHolder, this, 0, true);
}
[PropertyMethod, SpecialName]
public void Deletevalue() {
throw PythonOps.TypeError("cannot delete value property from simple cdata");
}
public override object _objects {
get {
if (IsString) {
PythonDictionary objs = _memHolder.Objects;
if (objs != null) {
return objs["str"];
}
}
return _memHolder.Objects;
}
}
private bool IsString {
get {
SimpleTypeKind t = ((SimpleType)NativeType)._type;
return t == SimpleTypeKind.CharPointer || t == SimpleTypeKind.WCharPointer;
}
}
#region ICodeFormattable Members
public string __repr__(CodeContext context) {
if (DynamicHelpers.GetPythonType(this).BaseTypes[0] == _SimpleCData) {
// direct subtypes have a custom repr
return String.Format("{0}({1})", DynamicHelpers.GetPythonType(this).Name, GetDataRepr(context));
}
return ObjectOps.__repr__(this);
}
private string GetDataRepr(CodeContext/*!*/ context) {
return PythonOps.Repr(context, NativeType.GetValue(_memHolder, this, 0, false));
}
#endregion
}
}
}
#endif