示例#1
0
        internal static IList <byte> GetBytes(object?value, bool useHint, CodeContext?context = null)
        {
            switch (value)
            {
            case IList <byte> lob when !(lob is ListGenericWrapper <byte>):
                return(lob);

            case IBufferProtocol bp:
                using (IPythonBuffer buf = bp.GetBuffer()) {
                    return(buf.AsReadOnlySpan().ToArray());
                }

            case ReadOnlyMemory <byte> rom:
                return(rom.ToArray());

            case Memory <byte> mem:
                return(mem.ToArray());

            default:
                int len = 0;
                if (useHint)
                {
                    PythonOps.TryInvokeLengthHint(context ?? DefaultContext.Default, value, out len);
                }
                List <byte> ret = new List <byte>(len);
                IEnumerator ie  = PythonOps.GetEnumerator(value);
                while (ie.MoveNext())
                {
                    ret.Add(GetByte(ie.Current));
                }
                return(ret);
            }
        }
示例#2
0
        public static bool _compare_digest(object a, object b)
        {
            var aStr = a as string ?? (a as Extensible <string>)?.Value;
            var bStr = b as string ?? (b as Extensible <string>)?.Value;

            if (aStr != null && bStr != null)
            {
                if (!StringOps.TryEncodeAscii(aStr, out Bytes aBytes) || !StringOps.TryEncodeAscii(bStr, out Bytes bBytes))
                {
                    throw PythonOps.TypeError("comparing strings with non-ASCII characters is not supported");
                }
                return(CompareBytes(aBytes, bBytes));
            }
            else if (a is IBufferProtocol abp && b is IBufferProtocol bbp)
            {
                using IPythonBuffer aBuf = abp.GetBuffer();
                using IPythonBuffer bBuf = bbp.GetBuffer();
                if (aBuf.NumOfDims > 1 || bBuf.NumOfDims > 1)
                {
                    throw PythonOps.BufferError("Buffer must be single dimension");
                }

                return(CompareBytes(aBuf.AsReadOnlySpan().ToArray(), bBuf.AsReadOnlySpan().ToArray()));
            }
            throw PythonOps.TypeError("unsupported operand types(s) or combination of types: '{0}' and '{1}'", PythonOps.GetPythonTypeName(a), PythonOps.GetPythonTypeName(b));
        }
示例#3
0
        internal static byte[]? AsUnsafeArray(this IPythonBuffer buffer)
        {
            if (!buffer.IsCContiguous())
            {
                return(null);
            }

            if (buffer.Object is Bytes b)
            {
                return(b.UnsafeByteArray);
            }

            if (buffer.Object is Memory <byte> mem)
            {
                if (MemoryMarshal.TryGetArray(mem, out ArraySegment <byte> seg) && seg.Array != null && seg.Offset == 0 && seg.Count == seg.Array.Length)
                {
                    return(seg.Array);
                }
            }
            else if (buffer.Object is ReadOnlyMemory <byte> rom)
            {
                if (MemoryMarshal.TryGetArray(rom, out ArraySegment <byte> seg) && seg.Array != null && seg.Offset == 0 && seg.Count == seg.Array.Length)
                {
                    return(seg.Array);
                }
            }

            return(null);
        }
示例#4
0
        public BufferBytesEnumerator(IPythonBuffer buffer)
        {
            if (buffer.SubOffsets != null)
            {
                throw new NotImplementedException("buffers with suboffsets are not supported");
            }

            _span    = buffer.AsReadOnlySpan();
            _offsets = EnumerateDimension(buffer, buffer.Offset, 0).GetEnumerator();
        }
示例#5
0
 internal static IList <byte> CoerceBytes(object?obj)
 {
     if (obj is IList <byte> ret)
     {
         return(ret);
     }
     if (obj is IBufferProtocol bp)
     {
         using (IPythonBuffer buf = bp.GetBuffer()) {
             return(buf.AsReadOnlySpan().ToArray());
         }
     }
     throw PythonOps.TypeError("a bytes-like object is required, not '{0}'", PythonTypeOps.GetName(obj));
 }
示例#6
0
 public static void CopyTo(this IPythonBuffer buffer, Span <byte> dest)
 {
     if (buffer.IsCContiguous())
     {
         buffer.AsReadOnlySpan().CopyTo(dest);
     }
     else
     {
         int i = 0;
         foreach (byte b in buffer.EnumerateBytes())
         {
             dest[i++] = b;
         }
     }
 }
示例#7
0
 internal static void AppendJoin(object?value, int index, List <byte> byteList)
 {
     if (value is IList <byte> bytesValue)
     {
         byteList.AddRange(bytesValue);
     }
     else if (value is IBufferProtocol bp)
     {
         using (IPythonBuffer buf = bp.GetBuffer()) {
             byteList.AddRange(buf.AsReadOnlySpan().ToArray());
         }
     }
     else
     {
         throw PythonOps.TypeError("sequence item {0}: expected bytes or byte array, {1} found", index.ToString(), PythonOps.GetPythonTypeName(value));
     }
 }
示例#8
0
 public static byte[] ToArray(this IPythonBuffer buffer)
 {
     if (buffer.IsCContiguous())
     {
         return(buffer.AsReadOnlySpan().ToArray());
     }
     else
     {
         var bytes = new byte[buffer.NumBytes()];
         int i     = 0;
         foreach (byte b in buffer.EnumerateBytes())
         {
             bytes[i++] = b;
         }
         return(bytes);
     }
 }
示例#9
0
        internal static object NewFloat(CodeContext /*!*/ context, PythonType type, object x)
        {
            string str;
            bool   replaceUnicode = true;

            if (x is string s)
            {
                str = s;
            }
            else if (x is char c)
            {
                str = ScriptingRuntimeHelpers.CharToString(c);
            }
            else if (TryToFloat(context, x, out var d))
            {
                return(d);
            }
            else if (x is Extensible <string> es)
            {
                str = es.Value;
            }
            else if (x is IBufferProtocol bufferProtocol)
            {
                using IPythonBuffer buf = bufferProtocol.GetBufferNoThrow()
                                          ?? throw PythonOps.TypeErrorForBadInstance($"{type.Name}() argument must be a string or a number, not '{{0}}'", x);
                str            = buf.AsReadOnlySpan().MakeString();
                replaceUnicode = false;
            }
            else
            {
                throw PythonOps.TypeErrorForBadInstance($"{type.Name}() argument must be a string or a number, not '{{0}}'", x);
            }

            if (LiteralParser.TryParseFloat(str, out var res, replaceUnicode: replaceUnicode))
            {
                return(res);
            }

            throw PythonOps.ValueError($"could not convert string to {type.Name}: {PythonOps.Repr(context, x)}");
        }
示例#10
0
            public void load_verify_locations(CodeContext context, [DefaultParameterValue(null)] string cafile, [DefaultParameterValue(null)] string capath, [DefaultParameterValue(null)] object cadata)
            {
                if (cafile == null && capath == null && cadata == null)
                {
                    throw PythonOps.TypeError("cafile, capath and cadata cannot be all omitted");
                }

                if (cafile != null)
                {
                    _cert_store.Add(ReadCertificate(context, cafile));
                    _cafile = cafile;
                }

                if (capath != null)
                {
                }

                if (cadata != null)
                {
                    var cabuf = cadata as IBufferProtocol;
                    if (cabuf != null)
                    {
                        int    pos = 0;
                        byte[] contents;
                        using (IPythonBuffer buf = cabuf.GetBuffer()) {
                            contents = buf.AsReadOnlySpan().ToArray();
                        }
                        while (pos < contents.Length)
                        {
                            byte[] curr = new byte[contents.Length - pos];
                            Array.Copy(contents, pos, curr, 0, contents.Length - pos);
                            var cert = new X509Certificate2(curr);
                            _cert_store.Add(cert);
                            pos += cert.GetRawCertData().Length;
                        }
                    }
                }
            }
示例#11
0
        public MemoryHolder(IPythonBuffer buffer, int offset, int size)
        {
            if (buffer.IsReadOnly)
            {
                throw new ArgumentException("Buffer must be writable.");
            }
            if (!buffer.IsCContiguous())
            {
                throw new ArgumentException("Buffer must be c-contiguous.");
            }
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(size), size, "Non-negative number required.");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), offset, "Non-negative number required.");
            }

            int bufSize = buffer.NumBytes();
            ReadOnlySpan <byte> memblock = buffer.AsSpan();

            if (memblock.Length != bufSize)
            {
                new ArgumentException("Invalid buffer.");
            }
            if (size > bufSize - offset)
            {
                throw new ArgumentException("Requested memory block exceeds buffer boundaries.");
            }


            _buffer = buffer;
            _handle = buffer.Pin();
            unsafe { _data = (IntPtr)_handle.Pointer + offset; }
            _size = size;
        }
示例#12
0
        private static IEnumerable <int> EnumerateDimension(IPythonBuffer buffer, int ofs, int dim)
        {
            IReadOnlyList <int>?shape   = buffer.Shape;
            IReadOnlyList <int>?strides = buffer.Strides;

            if (shape == null || strides == null)
            {
                // simple C-contiguous case
                Debug.Assert(buffer.Offset == 0);
                int len = buffer.NumBytes();
                for (int i = 0; i < len; i++)
                {
                    yield return(i);
                }
            }
            else if (dim >= shape.Count)
            {
                // iterate individual element (scalar)
                for (int i = 0; i < buffer.ItemSize; i++)
                {
                    yield return(ofs + i);
                }
            }
            else
            {
                for (int i = 0; i < shape[dim]; i++)
                {
                    // iterate all bytes from a subdimension
                    foreach (int j in EnumerateDimension(buffer, ofs, dim + 1))
                    {
                        yield return(j);
                    }
                    ofs += strides[dim];
                }
            }
        }
示例#13
0
 public Bytes([NotNull] IBufferProtocol source)
 {
     using IPythonBuffer buffer = source.GetBuffer(BufferFlags.FullRO);
     _bytes = buffer.ToArray();
 }
示例#14
0
 public static bool IsCContiguous(this IPythonBuffer buffer)
 {
     Debug.Assert(buffer.Strides != null || buffer.Offset == 0);
     return(buffer.Strides == null);
 }
示例#15
0
 public static BufferBytesEnumerator EnumerateBytes(this IPythonBuffer buffer)
 => new BufferBytesEnumerator(buffer);
示例#16
0
 public static int NumBytes(this IPythonBuffer buffer)
 => buffer.ItemCount * buffer.ItemSize;