PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/DICK.B1/IronPython.Modules/_ctypes/Array.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 170 lines | 126 code | 27 blank | 17 comment | 26 complexity | bd1794ae893f2c4b194ced5a3ffa49f8 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. 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 Microsoft Public License, 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 Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System;
  16. using System.Collections;
  17. using System.Text;
  18. using Microsoft.Scripting.Runtime;
  19. using IronPython.Runtime;
  20. using IronPython.Runtime.Operations;
  21. using IronPython.Runtime.Types;
  22. using System.Collections.Generic;
  23. #if CLR2
  24. using Microsoft.Scripting.Math;
  25. #else
  26. using System.Numerics;
  27. #endif
  28. #if !SILVERLIGHT
  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. SimpleType elemType = ((ArrayType)NativeType).ElementType as SimpleType;
  102. slice.indices(size, out start, out stop, out step);
  103. int n = (int)(step > 0 ? (0L + stop - start + step - 1) / step : (0L + stop - start + step + 1) / step);
  104. IEnumerator ie = PythonOps.GetEnumerator(value);
  105. for (int i = 0, index = start; i < n; i++, index += step) {
  106. if (!ie.MoveNext()) {
  107. throw PythonOps.ValueError("sequence not long enough");
  108. }
  109. this[index] = ie.Current;
  110. }
  111. if (ie.MoveNext()) {
  112. throw PythonOps.ValueError("not all values consumed while slicing");
  113. }
  114. }
  115. }
  116. public int __len__() {
  117. return ((ArrayType)NativeType).Length;
  118. }
  119. private INativeType ElementType {
  120. get {
  121. return ((ArrayType)NativeType).ElementType;
  122. }
  123. }
  124. internal override PythonTuple GetBufferInfo() {
  125. INativeType elemType = ElementType;
  126. int dimensions = 1;
  127. List<object> shape = new List<object>();
  128. shape.Add((BigInteger)__len__());
  129. while (elemType is ArrayType) {
  130. dimensions++;
  131. shape.Add((BigInteger)((ArrayType)elemType).Length);
  132. elemType = ((ArrayType)elemType).ElementType;
  133. }
  134. return PythonTuple.MakeTuple(
  135. NativeType.TypeFormat,
  136. dimensions,
  137. PythonTuple.Make(shape)
  138. );
  139. }
  140. }
  141. }
  142. }
  143. #endif