Exemplo n.º 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));
        }
Exemplo n.º 2
0
        private void SetItem(int offset, object?value)
        {
            if (value == null)
            {
                throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", format);
            }
            switch (_format)
            {
            case "d":     // double
            case "f":     // float
                double convertedValueDouble = 0;
                if (!Converter.TryConvertToDouble(value, out convertedValueDouble))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", format);
                }
                value = convertedValueDouble;
                break;

            case "c":     // char
            case "b":     // signed byte
            case "B":     // unsigned byte
            case "u":     // unicode char
            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 "q":     // signed long long
            case "P":     // pointer
            case "Q":     // unsigned long long
                if (!PythonOps.IsNumericObject(value))
                {
                    throw PythonOps.TypeError("memoryview: invalid type for format '{0}'", format);
                }

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

                if (format == "Q")
                {
                    value = Converter.ConvertToUInt64(value);
                }
                else
                {
                    value = Converter.ConvertToInt64(value);
                }
                break;

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

            unpackBytes(format, value, _buffer !.AsSpan().Slice(offset, _itemSize));
        }
Exemplo n.º 3
0
 private static object packBytes(string format, ReadOnlySpan <byte> bytes)
 {
     if (TypecodeOps.TryGetFromBytes(format, bytes, out object?result))
     {
         return(result);
     }
     else
     {
         return(Bytes.Make(bytes.ToArray()));
     }
 }
Exemplo n.º 4
0
 private void unpackBytes(string format, object o, Span <byte> dest)
 {
     if (TypecodeOps.TryGetBytes(format, o, dest))
     {
         return;
     }
     else
     {
         throw PythonOps.NotImplementedError("No conversion for type {0} to byte array", PythonOps.GetPythonTypeName(o));
     }
 }
Exemplo n.º 5
0
 private static object PackBytes(char typecode, ReadOnlySpan <byte> bytes)
 {
     // TODO: support non-native byteorder
     if (IsSupportedTypecode(typecode) && TypecodeOps.TryGetFromBytes(typecode, bytes, out object?result))
     {
         return(result);
     }
     else
     {
         throw PythonOps.NotImplementedError("memoryview: format {0} not supported", typecode);
     }
 }
Exemplo n.º 6
0
        private static void UnpackBytes(char typecode, object o, Span <byte> dest)
        {
            if (!IsSupportedTypecode(typecode))
            {
                throw PythonOps.NotImplementedError("memoryview: format {0} not supported", typecode);
            }

            // TODO: support non-native byteorder
            if (!TypecodeOps.TryGetBytes(typecode, o, dest))
            {
                throw PythonOps.NotImplementedError("No conversion for type {0} to byte array", PythonOps.GetPythonTypeName(o));
            }
        }
Exemplo n.º 7
0
        internal MemoryView(IBufferProtocol @object, int start, int?end, int step, string format, PythonTuple shape)
        {
            _buffer = @object;
            _format = format;
            _shape  = shape;
            _start  = start;
            _end    = end;
            _step   = step;

            if (!TypecodeOps.TryGetTypecodeWidth(format, out _itemsize))
            {
                _itemsize = (int)_buffer.ItemSize;
            }

            _matchesBuffer = _format == _buffer.Format && _start % itemsize == 0;
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
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));
            }
        }
Exemplo n.º 10
0
 private byte[] unpackBytes(string format, object o)
 {
     if (TypecodeOps.TryGetBytes(format, o, out byte[] bytes))
Exemplo n.º 11
0
        public MemoryView cast(object format, [NotNull] object shape)
        {
            if (!(format is string formatAsString))
            {
                throw PythonOps.TypeError("memoryview: format argument must be a string");
            }

            if (_step != 1)
            {
                throw PythonOps.TypeError("memoryview: casts are restricted to C-contiguous views");
            }

            if ((shape != null || ndim != 0) && this.shape.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 = PythonOps.MakeTupleFromSequence(shape);
                int newNDim = shapeAsTuple.Count;

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

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

            int newItemsize;

            if (!TypecodeOps.TryGetTypecodeWidth(formatAsString, out newItemsize))
            {
                throw PythonOps.ValueError(
                          "memoryview: destination format must be a native single character format prefixed with an optional '@'");
            }

            bool thisIsBytes  = this.format == "B" || this.format == "b" || this.format == "c";
            bool otherIsBytes = formatAsString == "B" || formatAsString == "b" || formatAsString == "c";

            if (!thisIsBytes && !otherIsBytes)
            {
                throw PythonOps.TypeError("memoryview: cannot cast between two non-byte formats");
            }

            int length = numberOfElements();

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

            int newLength = length * _itemsize / newItemsize;

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

                if (lengthGivenShape != newLength)
                {
                    throw PythonOps.TypeError("memoryview: product(shape) * itemsize != buffer size");
                }
            }

            return(new MemoryView(_buffer, _start, _end, _step, formatAsString, shapeAsTuple ?? PythonOps.MakeTuple(newLength)));
        }
Exemplo n.º 12
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));
        }
Exemplo n.º 13
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));
        }