Пример #1
0
        private object GetItem(int offset)
        {
            TypecodeOps.DecomposeTypecode(_format, out char byteorder, out char typecode);
            object result = PackBytes(typecode, _buffer !.AsReadOnlySpan().Slice(offset, _itemSize));

            return(PythonOps.ConvertToPythonPrimitive(result));
        }
Пример #2
0
        public int __hash__(CodeContext context)
        {
            if (_storedHash != null)
            {
                return(_storedHash.Value);
            }

            CheckBuffer();
            if (!_isReadOnly)
            {
                throw PythonOps.ValueError("cannot hash writable memoryview object");
            }

            TypecodeOps.DecomposeTypecode(_format, out _, out char typecode);
            if (!TypecodeOps.IsByteCode(typecode))
            {
                throw PythonOps.ValueError("memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
            }

            _storedHash = tobytes().GetHashCode();
            return(_storedHash.Value);
        }
Пример #3
0
        public object tolist()
        {
            CheckBuffer();
            TypecodeOps.DecomposeTypecode(_format, out char byteorder, out char typecode);

            return(subdimensionToList(_buffer !.AsReadOnlySpan(), _offset, dim: 0));

            object subdimensionToList(ReadOnlySpan <byte> source, int ofs, int dim)
            {
                if (dim >= _shape.Count)
                {
                    // extract individual element (scalar)
                    return(PackBytes(typecode, source.Slice(ofs)));
                }

                object[] elements = new object[_shape[dim]];
                for (int i = 0; i < _shape[dim]; i++)
                {
                    elements[i] = subdimensionToList(source, ofs, dim + 1);
                    ofs        += _strides[dim];
                }
                return(PythonList.FromArrayNoCopy(elements));
            }
        }
Пример #4
0
        private void SetItem(int offset, object?value)
        {
            if (value == null)
            {
                throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);
            }
            TypecodeOps.DecomposeTypecode(_format, out char byteorder, out char typecode);
            switch (typecode)
            {
            case 'd':     // double
            case 'f':     // float
                if (!Converter.TryConvertToDouble(value, out double convertedValueDouble))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);
                }
                value = convertedValueDouble;
                break;

            case 'c':     // bytechar
                if (!(value is Bytes b))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);
                }
                if (b.Count != 1)
                {
                    throw PythonOps.ValueError("memoryview: invalid value for format '{0}'", _format);
                }
                break;

            case 'b':     // signed byte
            case 'B':     // unsigned byte
            case 'h':     // signed short
            case 'H':     // unsigned short
            case 'i':     // signed int
            case 'I':     // unsigned int
            case 'l':     // signed long
            case 'L':     // unsigned long
            case 'n':     // signed index
            case 'N':     // unsigned index
            case 'q':     // signed long long
            case 'Q':     // unsigned long long
                if (!PythonOps.IsNumericObject(value))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);
                }

                if (TypecodeOps.CausesOverflow(value, typecode))
                {
                    throw PythonOps.ValueError("memoryview: invalid value for format '{0}'", _format);
                }

                if (typecode == 'Q')
                {
                    value = Converter.ConvertToUInt64(value);
                }
                else
                {
                    value = Converter.ConvertToInt64(value);
                }
                break;

            case 'P':     // void pointer
                if (!PythonOps.IsNumericObject(value))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);
                }

                var bi = Converter.ConvertToBigInteger(value);
                if (TypecodeOps.CausesOverflow(bi, typecode))
                {
                    throw PythonOps.ValueError("memoryview: invalid value for format '{0}'", _format);
                }
                value = bi;
                break;

            case 'r':     // .NET signed pointer
            case 'R':     // .NET unsigned pointer
                if (value is UIntPtr uptr)
                {
                    if (typecode == 'r')
                    {
                        value = new IntPtr(unchecked ((Int64)uptr.ToUInt64()));
                    }
                    break;
                }

                if (value is IntPtr iptr)
                {
                    if (typecode == 'R')
                    {
                        value = new UIntPtr(unchecked ((UInt64)iptr.ToInt64()));
                    }
                    break;
                }
                throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", _format);

            default:
                break;     // This could be a variety of types, let the UnpackBytes decide
            }

            UnpackBytes(typecode, value, _buffer !.AsSpan().Slice(offset, _itemSize));
        }
Пример #5
0
        public MemoryView cast([NotNull] string format, [NotNull, AllowNull] object shape)
        {
            if (!_isCContig)
            {
                throw PythonOps.TypeError("memoryview: casts are restricted to C-contiguous views");
            }

            if (_shape.Contains(0) || _strides.Contains(0))
            {
                throw PythonOps.TypeError("memoryview: cannot cast view with zeros in shape or strides");
            }

            PythonTuple?shapeAsTuple = null;

            if (shape != null)
            {
                if (!(shape is PythonList) && !(shape is PythonTuple))
                {
                    throw PythonOps.TypeError("shape must be a list or a tuple");
                }

                shapeAsTuple = PythonTuple.Make(shape);
                int newNDim = shapeAsTuple.Count;

                if (newNDim > MaximumDimensions)
                {
                    throw PythonOps.TypeError("memoryview: number of dimensions must not exceed {0}", MaximumDimensions);
                }

                if (_numDims != 1 && newNDim != 1)
                {
                    throw PythonOps.TypeError("memoryview: cast must be 1D -> ND or ND -> 1D");
                }
            }

            if (!TypecodeOps.TryDecomposeTypecode(format, out char byteorder, out char typecode) ||
                !IsSupportedTypecode(typecode) ||
                byteorder != '@'
                )
            {
                throw PythonOps.ValueError(
                          "memoryview: destination format must be a native single character format prefixed with an optional '@'");
            }

            if (!TypecodeOps.IsByteCode(typecode))
            {
                TypecodeOps.DecomposeTypecode(_format, out _, out char thisTypecode);
                if (!TypecodeOps.IsByteCode(thisTypecode))
                {
                    throw PythonOps.TypeError("memoryview: cannot cast between two non-byte formats");
                }
            }

            int newItemsize = TypecodeOps.GetTypecodeWidth(typecode);

            if ((_numItems * _itemSize) % newItemsize != 0)
            {
                throw PythonOps.TypeError("memoryview: length is not a multiple of itemsize");
            }

            int newLength = _numItems * _itemSize / newItemsize;

            int[] newShape;
            if (shapeAsTuple != null)
            {
                newShape = new int[shapeAsTuple.Count];
                int lengthGivenShape = 1;
                for (int i = 0; i < shapeAsTuple.Count; i++)
                {
                    newShape[i]       = Converter.ConvertToInt32(shapeAsTuple[i]);
                    lengthGivenShape *= newShape[i];
                }

                if (lengthGivenShape != newLength)
                {
                    throw PythonOps.TypeError("memoryview: product(shape) * itemsize != buffer size");
                }
            }
            else
            {
                newShape = new int[] { newLength };
            }

            return(new MemoryView(this, format, newItemsize, newShape));
        }