PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Languages/IronPython/IronPython.Modules/_ctypes/Array.cs

http://github.com/IronLanguages/main
C# | 204 lines | 153 code | 34 blank | 17 comment | 29 complexity | 807a2882a48b0333ecb39fc9d1ee69c7 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. #if FEATURE_NATIVE
  16. #if CLR2
  17. using Microsoft.Scripting.Math;
  18. #else
  19. using System.Numerics;
  20. #endif
  21. using System;
  22. using System.Collections;
  23. using System.Text;
  24. using Microsoft.Scripting.Runtime;
  25. using IronPython.Runtime;
  26. using IronPython.Runtime.Operations;
  27. using IronPython.Runtime.Types;
  28. using System.Collections.Generic;
  29. namespace IronPython.Modules {
  30. /// <summary>
  31. /// Provides support for interop with native code from Python code.
  32. /// </summary>
  33. public static partial class CTypes {
  34. [PythonType("Array")]
  35. public abstract class _Array : CData {
  36. public void __init__(params object[] args) {
  37. INativeType nativeType = NativeType;
  38. _memHolder = new MemoryHolder(nativeType.Size);
  39. if (args.Length > ((ArrayType)nativeType).Length) {
  40. throw PythonOps.IndexError("too many arguments");
  41. }
  42. nativeType.SetValue(_memHolder, 0, args);
  43. }
  44. public object this[int index] {
  45. get {
  46. index = PythonOps.FixIndex(index, ((ArrayType)NativeType).Length);
  47. INativeType elementType = ElementType;
  48. return elementType.GetValue(
  49. _memHolder,
  50. this,
  51. checked(index * elementType.Size),
  52. false
  53. );
  54. }
  55. set {
  56. index = PythonOps.FixIndex(index, ((ArrayType)NativeType).Length);
  57. INativeType elementType = ElementType;
  58. object keepAlive = elementType.SetValue(
  59. _memHolder,
  60. checked(index * elementType.Size),
  61. value
  62. );
  63. if (keepAlive != null) {
  64. _memHolder.AddObject(index.ToString(), keepAlive);
  65. }
  66. }
  67. }
  68. public object this[[NotNull]Slice slice] {
  69. get {
  70. int start, stop, step;
  71. int size = ((ArrayType)NativeType).Length;
  72. SimpleType elemType = ((ArrayType)NativeType).ElementType as SimpleType;
  73. slice.indices(size, out start, out stop, out step);
  74. if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
  75. if (elemType != null && (elemType._type == SimpleTypeKind.WChar || elemType._type == SimpleTypeKind.Char)) {
  76. return String.Empty;
  77. }
  78. return new List();
  79. }
  80. int n = (int)(step > 0 ? (0L + stop - start + step - 1) / step : (0L + stop - start + step + 1) / step);
  81. if (elemType != null && (elemType._type == SimpleTypeKind.WChar || elemType._type == SimpleTypeKind.Char)) {
  82. int elmSize = ((INativeType)elemType).Size;
  83. StringBuilder res = new StringBuilder(n);
  84. for (int i = 0, index = start; i < n; i++, index += step) {
  85. char c = elemType.ReadChar(_memHolder, checked(index * elmSize));
  86. res.Append(c);
  87. }
  88. return res.ToString();
  89. } else {
  90. object[] ret = new object[n];
  91. int ri = 0;
  92. for (int i = 0, index = start; i < n; i++, index += step) {
  93. ret[ri++] = this[index];
  94. }
  95. return new List(ret);
  96. }
  97. }
  98. set {
  99. int start, stop, step;
  100. int size = ((ArrayType)NativeType).Length;
  101. slice.indices(size, out start, out stop, out step);
  102. int n = (int)(step > 0 ? (0L + stop - start + step - 1) / step : (0L + stop - start + step + 1) / step);
  103. IEnumerator ie = PythonOps.GetEnumerator(value);
  104. for (int i = 0, index = start; i < n; i++, index += step) {
  105. if (!ie.MoveNext()) {
  106. throw PythonOps.ValueError("sequence not long enough");
  107. }
  108. this[index] = ie.Current;
  109. }
  110. if (ie.MoveNext()) {
  111. throw PythonOps.ValueError("not all values consumed while slicing");
  112. }
  113. }
  114. }
  115. public int __len__() {
  116. return ((ArrayType)NativeType).Length;
  117. }
  118. private INativeType ElementType {
  119. get {
  120. return ((ArrayType)NativeType).ElementType;
  121. }
  122. }
  123. internal override PythonTuple GetBufferInfo() {
  124. INativeType elemType = ElementType;
  125. int dimensions = 1;
  126. List<object> shape = new List<object>();
  127. shape.Add((BigInteger)__len__());
  128. while (elemType is ArrayType) {
  129. dimensions++;
  130. shape.Add((BigInteger)((ArrayType)elemType).Length);
  131. elemType = ((ArrayType)elemType).ElementType;
  132. }
  133. return PythonTuple.MakeTuple(
  134. NativeType.TypeFormat,
  135. dimensions,
  136. PythonTuple.Make(shape)
  137. );
  138. }
  139. #region IBufferProtocol
  140. public override int ItemCount {
  141. [PythonHidden]
  142. get {
  143. return __len__();
  144. }
  145. }
  146. public override BigInteger ItemSize {
  147. [PythonHidden]
  148. get {
  149. var curType = this.NativeType;
  150. while (curType is ArrayType) {
  151. curType = ((ArrayType)curType).ElementType;
  152. }
  153. return curType.Size;
  154. }
  155. }
  156. [PythonHidden]
  157. public override IList<BigInteger> GetShape(int start, int? end) {
  158. List<BigInteger> shape = new List<BigInteger>();
  159. var curType = this.NativeType as ArrayType;
  160. while (curType != null) {
  161. shape.Add(curType.Length);
  162. curType = curType.ElementType as ArrayType;
  163. }
  164. return shape;
  165. }
  166. #endregion
  167. }
  168. }
  169. }
  170. #endif