Пример #1
0
        public virtual async ValueTask <ValueWebSocketReceiveResult> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken)
        {
            if (MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> arraySegment))
            {
                WebSocketReceiveResult r = await ReceiveAsync(arraySegment, cancellationToken).ConfigureAwait(false);

                return(new ValueWebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage));
            }

            byte[] array = ArrayPool <byte> .Shared.Rent(buffer.Length);

            try
            {
                WebSocketReceiveResult r = await ReceiveAsync(new ArraySegment <byte>(array, 0, buffer.Length), cancellationToken).ConfigureAwait(false);

                new Span <byte>(array, 0, r.Count).CopyTo(buffer.Span);
                return(new ValueWebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage));
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(array);
            }
        }
Пример #2
0
        public void Test_MemoryExtensions_FromArray_CastFromByteAndBack_WithSlice()
        {
            // Just like the equivalent test above, but with a slice thrown in too
            var            data           = new byte[512];
            Memory <byte>  memoryOfBytes  = data.AsMemory().Slice(128, 128);
            Memory <float> memoryOfFloats = memoryOfBytes.Cast <byte, float>();
            Memory <byte>  memoryBack     = memoryOfFloats.Cast <float, byte>();

            Assert.AreEqual(memoryOfBytes.Length, memoryBack.Length);

            // Here we now also have to validate the starting offset from the extracted array
            Assert.IsTrue(MemoryMarshal.TryGetArray <byte>(memoryBack, out var segment));
            Assert.AreSame(segment.Array !, data);
            Assert.AreEqual(segment.Offset, 128);
            Assert.AreEqual(segment.Count, 128);

            Assert.IsTrue(memoryOfBytes.Equals(memoryBack));

            Span <byte> span1 = memoryOfBytes.Span;
            Span <byte> span2 = memoryBack.Span;

            Assert.IsTrue(span1 == span2);
        }
Пример #3
0
        private ValueTask <int> DoReadBytesSync(Memory <byte> buffer)
        {
#if !NETSTANDARD2_1 && !NETCOREAPP2_1 && !NETCOREAPP3_0
            MemoryMarshal.TryGetArray <byte>(buffer, out var arraySegment);
#endif

            try
            {
                if (RemainingTimeout == Constants.InfiniteTimeout)
#if !NETSTANDARD2_1 && !NETCOREAPP2_1 && !NETCOREAPP3_0
                { return(new ValueTask <int>(m_socket.Receive(arraySegment.Array, arraySegment.Offset, arraySegment.Count, SocketFlags.None))); }
#else
                { return(new ValueTask <int>(m_socket.Receive(buffer.Span, SocketFlags.None))); }
#endif

                while (RemainingTimeout > 0)
                {
                    var startTime = Environment.TickCount;
                    if (m_socket.Poll(Math.Min(int.MaxValue / 1000, RemainingTimeout) * 1000, SelectMode.SelectRead))
                    {
#if !NETSTANDARD2_1 && !NETCOREAPP2_1 && !NETCOREAPP3_0
                        var bytesRead = m_socket.Receive(arraySegment.Array, arraySegment.Offset, arraySegment.Count, SocketFlags.None);
#else
                        var bytesRead = m_socket.Receive(buffer.Span, SocketFlags.None);
#endif
                        RemainingTimeout -= unchecked (Environment.TickCount - startTime);
                        return(new ValueTask <int>(bytesRead));
                    }
                    RemainingTimeout -= unchecked (Environment.TickCount - startTime);
                }
                return(ValueTaskExtensions.FromException <int>(MySqlException.CreateForTimeout()));
            }
            catch (Exception ex)
            {
                return(ValueTaskExtensions.FromException <int>(ex));
            }
        }
Пример #4
0
        public static unsafe bool Equals24(this Memory <byte> a, Memory <byte> b)
        {
            if (a.Length != 24 || b.Length != 24)
            {
                throw new ArgumentOutOfRangeException("Equals24 can check only sizes of hash values multiple of 24");
            }

            if (!MemoryMarshal.TryGetArray(a, out ArraySegment <byte> byteArrayA))
            {
                throw new FailedToMarshalToByteArrayException(nameof(a));
            }

            if (!MemoryMarshal.TryGetArray(b, out ArraySegment <byte> byteArrayB))
            {
                throw new FailedToMarshalToByteArrayException(nameof(b));
            }

            fixed(byte *a1 = byteArrayA.Array)
            {
                byte *pa1 = a1 + byteArrayA.Offset;

                fixed(byte *b1 = byteArrayB.Array)
                {
                    byte *pb1  = b1 + byteArrayB.Offset;
                    long *pla1 = (long *)pa1;
                    long *pla2 = (long *)(pa1 + 8);
                    long *pla3 = (long *)(pa1 + 16);
                    long *plb1 = (long *)pb1;
                    long *plb2 = (long *)(pb1 + 8);
                    long *plb3 = (long *)(pb1 + 16);

                    return(*pla1 == *plb1 &&
                           *pla2 == *plb2 &&
                           *pla3 == *plb3);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Asynchronously commits the JSON text written so far which makes it visible to the output destination.
        /// </summary>
        /// <remarks>
        /// In the case of IBufferWriter, this advances the underlying <see cref="IBufferWriter{Byte}" /> based on what has been written so far.
        /// In the case of Stream, this writes the data to the stream and flushes it asynchronously, while monitoring cancellation requests.
        /// </remarks>
        /// <exception cref="ObjectDisposedException">
        ///   The instance of <see cref="Utf8JsonWriter"/> has been disposed.
        /// </exception>
        public async Task FlushAsync(CancellationToken cancellationToken = default)
        {
            CheckNotDisposed();

            if (_stream != null)
            {
                Debug.Assert(_arrayBufferWriter != null);
                if (BytesPending != 0)
                {
                    _arrayBufferWriter.Advance(BytesPending);
                    Debug.Assert(BytesPending == _arrayBufferWriter.WrittenCount);
#if BUILDING_INBOX_LIBRARY
                    await _stream.WriteAsync(_arrayBufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false);
#else
                    Debug.Assert(_arrayBufferWriter.WrittenMemory.Length == _arrayBufferWriter.WrittenCount);
                    bool result = MemoryMarshal.TryGetArray(_arrayBufferWriter.WrittenMemory, out ArraySegment <byte> underlyingBuffer);
                    Debug.Assert(underlyingBuffer.Offset == 0);
                    Debug.Assert(_arrayBufferWriter.WrittenCount == underlyingBuffer.Count);
                    await _stream.WriteAsync(underlyingBuffer.Array, underlyingBuffer.Offset, underlyingBuffer.Count, cancellationToken).ConfigureAwait(false);
#endif
                    _arrayBufferWriter.Clear();
                }
                await _stream.FlushAsync(cancellationToken).ConfigureAwait(false);
            }
            else
            {
                Debug.Assert(_output != null);
                if (BytesPending != 0)
                {
                    _output.Advance(BytesPending);
                }
            }

            _memory         = default;
            BytesCommitted += BytesPending;
            BytesPending    = 0;
        }
Пример #6
0
        /// <summary>
        /// Commits the JSON text written so far which makes it visible to the output destination.
        /// </summary>
        /// <remarks>
        /// In the case of IBufferWriter, this advances the underlying <see cref="IBufferWriter{Byte}" /> based on what has been written so far.
        /// In the case of Stream, this writes the data to the stream and flushes it.
        /// </remarks>
        /// <exception cref="ObjectDisposedException">
        ///   The instance of <see cref="Utf8JsonWriter"/> has been disposed.
        /// </exception>
        public void Flush()
        {
            CheckNotDisposed();

            if (_stream != null)
            {
                Debug.Assert(_arrayBufferWriter != null);
                if (BytesPending != 0)
                {
                    _arrayBufferWriter.Advance(BytesPending);
                    Debug.Assert(BytesPending == _arrayBufferWriter.WrittenCount);
#if BUILDING_INBOX_LIBRARY
                    _stream.Write(_arrayBufferWriter.WrittenSpan);
#else
                    Debug.Assert(_arrayBufferWriter.WrittenMemory.Length == _arrayBufferWriter.WrittenCount);
                    bool result = MemoryMarshal.TryGetArray(_arrayBufferWriter.WrittenMemory, out ArraySegment <byte> underlyingBuffer);
                    Debug.Assert(underlyingBuffer.Offset == 0);
                    Debug.Assert(_arrayBufferWriter.WrittenCount == underlyingBuffer.Count);
                    _stream.Write(underlyingBuffer.Array, underlyingBuffer.Offset, underlyingBuffer.Count);
#endif
                    _arrayBufferWriter.Clear();
                }
                _stream.Flush();
            }
            else
            {
                Debug.Assert(_output != null);
                if (BytesPending != 0)
                {
                    _output.Advance(BytesPending);
                }
            }

            _memory         = default;
            BytesCommitted += BytesPending;
            BytesPending    = 0;
        }
Пример #7
0
        public static void Copy <T>(SegmentedArray <T> sourceArray, Array destinationArray, int length)
        {
            if (destinationArray is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.destinationArray);
            }
            if (length == 0)
            {
                return;
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length));
            }
            if (length > sourceArray.Length)
            {
                throw new ArgumentException(SR.Arg_LongerThanSrcArray, nameof(sourceArray));
            }
            if (length > destinationArray.Length)
            {
                throw new ArgumentException(SR.Arg_LongerThanDestArray, nameof(destinationArray));
            }

            var copied = 0;

            foreach (var memory in sourceArray.GetSegments(0, length))
            {
                if (!MemoryMarshal.TryGetArray <T>(memory, out var segment))
                {
                    throw new NotSupportedException();
                }

                Array.Copy(segment.Array !, sourceIndex: segment.Offset, destinationArray: destinationArray, destinationIndex: copied, length: segment.Count);
                copied += segment.Count;
            }
        }
Пример #8
0
        /// Glb interface. bin is binary chunk
        public GltfStorage(FileInfo path, ArraySegment <byte> json, Memory <byte> bin)
        {
            OriginalJson = json;
            Gltf         = Generated.GltfDeserializer.Deserialize(json.ParseAsJson());

            Path = path;
            Json = new Utf8String(json);

            if (!bin.IsEmpty)
            {
                // glb
                MemoryMarshal.TryGetArray(bin, out ArraySegment <byte> segment);
                Buffers.Add(new SimpleBuffer(segment));
            }
            else
            {
                // gltf
                var baseDir = path.Directory.FullName;
                Buffers.AddRange(Gltf.buffers.Select(x => new UriByteBuffer(baseDir, x.uri)));
            }

            if (Gltf.extensions != null && Gltf.extensions.VRM != null)
            {
                // VRM
                if (Gltf.extensions.VRM.humanoid != null)
                {
                    Gltf.extensions.VRM.humanoid.humanBones =
                        Gltf.extensions.VRM.humanoid.humanBones.OrderBy(x => x.bone).ToList();
                }
            }

            if (!Gltf.materials.Any())
            {
                // default material
                Gltf.materials.Add(GltfMaterial.CreateDefault("__default__"));
            }
        }
Пример #9
0
        public void RunBenchmark(PocoSerializationFormat serializationFormat)
        {
            Newtonsoft.Json.JsonReader reader;
            switch (serializationFormat)
            {
            case PocoSerializationFormat.Text:
                reader = new CosmosDBToNewtonsoftReader(this.peoplePayload.Text);
                break;

            case PocoSerializationFormat.NewtonsoftText:
                if (!MemoryMarshal.TryGetArray(this.peoplePayload.Text, out ArraySegment <byte> segment))
                {
                    throw new InvalidOperationException("Failed to get segment");
                }

                reader = new Newtonsoft.Json.JsonTextReader(
                    new StreamReader(
                        new MemoryStream(segment.Array, index: segment.Offset, count: segment.Count)));
                break;

            case PocoSerializationFormat.Binary:
                reader = new CosmosDBToNewtonsoftReader(this.peoplePayload.Binary);
                break;

            case PocoSerializationFormat.BinaryWithDictionaryEncoding:
                reader = new CosmosDBToNewtonsoftReader(
                    this.peoplePayload.BinaryWithDictionaryEncoding.binary,
                    this.peoplePayload.BinaryWithDictionaryEncoding.dictionary);
                break;

            default:
                throw new ArgumentOutOfRangeException(serializationFormat.ToString());
            }

            Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
            _ = serializer.Deserialize <List <Person> >(reader);
        }
Пример #10
0
                /// <summary>
                /// Parses out a JSON object AST node with a jsonTextReader.
                /// </summary>
                /// <param name="jsonTextReader">The reader to use as a lexer / tokenizer</param>
                /// <returns>JSON object AST node</returns>
                private static ObjectNode ParseObjectNode(IJsonTextReaderPrivateImplementation jsonTextReader)
                {
                    List <ObjectProperty> properties = new List <ObjectProperty>();

                    ReadOnlyMemory <byte> bufferedObjectStartToken = jsonTextReader.GetBufferedJsonToken().Memory;

                    if (!MemoryMarshal.TryGetArray(bufferedObjectStartToken, out ArraySegment <byte> startObjectArraySegment))
                    {
                        throw new InvalidOperationException($"Failed to get {nameof(startObjectArraySegment)}.");
                    }

                    // consume the begin object token
                    jsonTextReader.Read();

                    while (jsonTextReader.CurrentTokenType != JsonTokenType.EndObject)
                    {
                        ObjectProperty property = Parser.ParsePropertyNode(jsonTextReader);
                        properties.Add(property);
                    }

                    ReadOnlyMemory <byte> bufferedObjectEndToken = jsonTextReader.GetBufferedJsonToken().Memory;

                    if (!MemoryMarshal.TryGetArray(bufferedObjectEndToken, out ArraySegment <byte> endObjectArraySegment))
                    {
                        throw new InvalidOperationException($"Failed to get {nameof(endObjectArraySegment)}.");
                    }

                    // consume the end object token
                    jsonTextReader.Read();

                    ReadOnlyMemory <byte> bufferedRawObject = startObjectArraySegment.Array;

                    bufferedRawObject = bufferedRawObject.Slice(start: startObjectArraySegment.Offset, length: endObjectArraySegment.Offset - startObjectArraySegment.Offset + 1);

                    return(ObjectNode.Create(properties, bufferedRawObject));
                }
Пример #11
0
            public override MemoryHandle Pin(int elementIndex = 0)
            {
                _pool.CheckDisposed();

                if (_owner is null)
                {
                    throw new NullReferenceException("_owner is null");
                }

                Interlocked.Increment(ref _referenceCount);

                if (!MemoryMarshal.TryGetArray(_owner.Memory, out ArraySegment <byte> segment))
                {
                    throw new InvalidOperationException();
                }

                unsafe
                {
                    try
                    {
                        if ((uint)elementIndex > (uint)segment.Count)
                        {
                            throw new ArgumentOutOfRangeException(nameof(elementIndex));
                        }

                        GCHandle handle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned);

                        return(new MemoryHandle(Unsafe.Add <byte>(((void *)handle.AddrOfPinnedObject()), elementIndex + segment.Offset), handle, this));
                    }
                    catch
                    {
                        Unpin();
                        throw;
                    }
                }
            }
Пример #12
0
            internal int ReadFrom(Stream source)
            {
                int bytes;

                if (MemoryMarshal.TryGetArray <byte>(_memory, out var segment))
                {
                    bytes = source.Read(segment.Array, segment.Offset + OffsetInCurrent, RemainingInCurrent);
                }
                else
                {
#if PLAT_SPAN_OVERLOADS
                    bytes = source.Read(Remaining);
#else
                    var arr = ArrayPool <byte> .Shared.Rent(RemainingInCurrent);

                    try
                    {
                        bytes = source.Read(arr, 0, RemainingInCurrent);
                        if (bytes > 0)
                        {
                            new Span <byte>(arr, 0, bytes).CopyTo(Remaining);
                        }
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(arr);
                    }
#endif
                }
                if (bytes > 0)
                {
                    OffsetInCurrent    += bytes;
                    RemainingInCurrent -= bytes;
                }
                return(bytes);
            }
        public static Stream Create(ReadOnlyMemory <byte> memory, bool isReadOnly)
        {
            if (memory.IsEmpty)
            {
                // Return an empty stream if the memory was empty
                return(new MemoryStream <ArrayOwner>(ArrayOwner.Empty, isReadOnly));
            }

            if (MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> segment))
            {
                var arraySpanSource = new ArrayOwner(segment.Array !, segment.Offset, segment.Count);

                return(new MemoryStream <ArrayOwner>(arraySpanSource, isReadOnly));
            }

            if (MemoryMarshal.TryGetMemoryManager <byte, MemoryManager <byte> >(memory, out var memoryManager, out int start, out int length))
            {
                MemoryManagerOwner memoryManagerSpanSource = new MemoryManagerOwner(memoryManager, start, length);

                return(new MemoryStream <MemoryManagerOwner>(memoryManagerSpanSource, isReadOnly));
            }

            return(ThrowNotSupportedExceptionForInvalidMemory());
        }
Пример #14
0
    public static ValueTask SendAsync(this WebSocket webSocket, ReadOnlySequence <byte> buffer, WebSocketMessageType webSocketMessageType, CancellationToken cancellationToken = default)
    {
#if NETCOREAPP
        if (buffer.IsSingleSegment)
        {
            return(webSocket.SendAsync(buffer.First, webSocketMessageType, endOfMessage: true, cancellationToken));
        }
        else
        {
            return(SendMultiSegmentAsync(webSocket, buffer, webSocketMessageType, cancellationToken));
        }
#else
        if (buffer.IsSingleSegment)
        {
            var isArray = MemoryMarshal.TryGetArray(buffer.First, out var segment);
            Debug.Assert(isArray);
            return(new ValueTask(webSocket.SendAsync(segment, webSocketMessageType, endOfMessage: true, cancellationToken)));
        }
        else
        {
            return(SendMultiSegmentAsync(webSocket, buffer, webSocketMessageType, cancellationToken));
        }
#endif
    }
Пример #15
0
        /// <summary>
        /// Flushes the Buffer Writer, returning the current buffer (if possible) as an <see cref="AutoArraySegment{T}"/> and resetting the writer
        /// </summary>
        /// <param name="clearBuffers">True to clear the buffers when the <see cref="AutoArraySegment{T}"/> is disposed</param>
        /// <returns>A single array segment containing all written data</returns>
        /// <remarks>The Buffer Writer will be empty after this call, and can be safely written without affecting the result. Buffers will not be copied if the writer has only used a single array, and can be released using <see cref="AutoArraySegment{T}"/></remarks>
        public AutoArraySegment <T> FlushArray(bool clearBuffers)
        {
            if (TryGetMemory(out var Memory))
            {
                if (MemoryMarshal.TryGetArray(Memory, out var Segment))
                {
                    var Result = AutoArraySegment.Over(Segment, _Pool);

                    // Release the current buffer into the hands of the AutoSequence
                    _CurrentBuffer = Memory <T> .Empty;
                    _CurrentOffset = 0;
                    _TailSegment   = _HeadSegment = null;

                    return(Result);
                }

                // Should never happen
            }

            // More than one buffer is in use, so we need to copy to a single segment
            var BufferLength = (int)Length;
            var Buffer       = _Pool.Rent(BufferLength);

            // Copy our current chain of buffers into it
            new ReadOnlySequence <T>(_HeadSegment !, 0, _TailSegment !, _TailSegment !.Memory.Length).CopyTo(Buffer);

            // Copy the final segment (if any)
            if (_CurrentOffset > 0)
            {
                _CurrentBuffer.Slice(0, _CurrentOffset).CopyTo(Buffer.AsMemory((int)_TailSegment.RunningIndex + _TailSegment.Memory.Length));
            }

            Reset(clearBuffers);             // Reset the writer

            return(AutoArraySegment.Over(new ArraySegment <T>(Buffer, 0, BufferLength), _Pool));
        }
Пример #16
0
        public void SetBufferArrayIntInt_AvailableFromMemoryBuffer()
        {
            using (var saea = new SocketAsyncEventArgs())
            {
                byte[] array = new byte[42];

                saea.SetBuffer(array, 0, array.Length);
                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out ArraySegment <byte> result));
                Assert.Same(array, result.Array);
                Assert.Same(saea.Buffer, array);
                Assert.Equal(0, result.Offset);
                Assert.Equal(array.Length, result.Count);

                saea.SetBuffer(1, 2);
                Assert.Same(saea.Buffer, array);
                Assert.Equal(1, saea.Offset);
                Assert.Equal(2, saea.Count);

                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out result));
                Assert.Same(array, result.Array);
                Assert.Equal(0, result.Offset);
                Assert.Equal(array.Length, result.Count);
            }
        }
Пример #17
0
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken = default)
        {
            if (GetType() != typeof(FileStream))
            {
                // If this isn't a concrete FileStream, a derived type may have overridden ReadAsync(byte[],...),
                // which was introduced first, so delegate to the base which will delegate to that.
                return(base.ReadAsync(buffer, cancellationToken));
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return(new ValueTask <int>(Task.FromCanceled <int>(cancellationToken)));
            }

            if (IsClosed)
            {
                throw Error.GetFileNotOpen();
            }

            if (!_useAsyncIO)
            {
                // If we weren't opened for asynchronous I/O, we still call to the base implementation so that
                // Read is invoked asynchronously.  But if we have a byte[], we can do so using the base Stream's
                // internal helper that bypasses delegating to BeginRead, since we already know this is FileStream
                // rather than something derived from it and what our BeginRead implementation is going to do.
                return(MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> segment) ?
                       new ValueTask <int>((Task <int>)base.BeginReadInternal(segment.Array !, segment.Offset, segment.Count, null, null, serializeAsynchronously: true, apm: false)) :
                       base.ReadAsync(buffer, cancellationToken));
            }

            Task <int>?t = ReadAsyncInternal(buffer, cancellationToken, out int synchronousResult);

            return(t != null ?
                   new ValueTask <int>(t) :
                   new ValueTask <int>(synchronousResult));
        }
Пример #18
0
        private async Task StartReceiving(WebSocket socket)
        {
            try
            {
                while (true)
                {
#if NETCOREAPP2_2
                    var result = await socket.ReceiveAsync(Memory <byte> .Empty, CancellationToken.None);

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        Log.WebSocketClosed(_logger, _webSocket.CloseStatus);

                        if (_webSocket.CloseStatus != WebSocketCloseStatus.NormalClosure)
                        {
                            throw new InvalidOperationException($"Websocket closed with error: {_webSocket.CloseStatus}.");
                        }

                        return;
                    }
#endif
                    var memory = _application.Output.GetMemory();
#if NETCOREAPP2_2
                    // Because we checked the CloseStatus from the 0 byte read above, we don't need to check again after reading
                    var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None);
#else
                    var isArray = MemoryMarshal.TryGetArray <byte>(memory, out var arraySegment);
                    Debug.Assert(isArray);

                    // Exceptions are handled above where the send and receive tasks are being run.
                    var receiveResult = await socket.ReceiveAsync(arraySegment, CancellationToken.None);
#endif
                    // Need to check again for NetCoreApp2.2 because a close can happen between a 0-byte read and the actual read
                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        Log.WebSocketClosed(_logger, _webSocket.CloseStatus);

                        if (_webSocket.CloseStatus != WebSocketCloseStatus.NormalClosure)
                        {
                            throw new InvalidOperationException($"Websocket closed with error: {_webSocket.CloseStatus}.");
                        }

                        return;
                    }

                    Log.MessageReceived(_logger, receiveResult.MessageType, receiveResult.Count, receiveResult.EndOfMessage);

                    _application.Output.Advance(receiveResult.Count);

                    var flushResult = await _application.Output.FlushAsync();

                    // We canceled in the middle of applying back pressure
                    // or if the consumer is done
                    if (flushResult.IsCanceled || flushResult.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Log.ReceiveCanceled(_logger);
            }
            catch (Exception ex)
            {
                if (!_aborted)
                {
                    _application.Output.Complete(ex);

                    // We re-throw here so we can communicate that there was an error when sending
                    // the close frame
                    throw;
                }
            }
            finally
            {
                // We're done writing
                _application.Output.Complete();

                Log.ReceiveStopped(_logger);
            }
        }
Пример #19
0
        private async Task StartReceiving(WebSocket socket)
        {
            try
            {
                while (true)
                {
#if NETCOREAPP2_2
                    // Do a 0 byte read so that idle connections don't allocate a buffer when waiting for a read
                    var result = await socket.ReceiveAsync(Memory <byte> .Empty, CancellationToken.None);

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        return;
                    }
#endif
                    var memory = _application.Output.GetMemory();

#if NETCOREAPP2_2
                    var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None);
#else
                    var isArray = MemoryMarshal.TryGetArray <byte>(memory, out var arraySegment);
                    Debug.Assert(isArray);

                    // Exceptions are handled above where the send and receive tasks are being run.
                    var receiveResult = await socket.ReceiveAsync(arraySegment, CancellationToken.None);
#endif
                    // Need to check again for NetCoreApp2.2 because a close can happen between a 0-byte read and the actual read
                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        return;
                    }

                    Log.MessageReceived(_logger, receiveResult.MessageType, receiveResult.Count, receiveResult.EndOfMessage);

                    _application.Output.Advance(receiveResult.Count);

                    var flushResult = await _application.Output.FlushAsync();

                    // We canceled in the middle of applying back pressure
                    // or if the consumer is done
                    if (flushResult.IsCanceled || flushResult.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (WebSocketException ex) when(ex.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
            {
                // Client has closed the WebSocket connection without completing the close handshake
                Log.ClosedPrematurely(_logger, ex);
            }
            catch (OperationCanceledException)
            {
                // Ignore aborts, don't treat them like transport errors
            }
            catch (Exception ex)
            {
                if (!_aborted)
                {
                    _application.Output.Complete(ex);

                    // We re-throw here so we can communicate that there was an error when sending
                    // the close frame
                    throw;
                }
            }
            finally
            {
                // We're done writing
                _application.Output.Complete();
            }
        }
        /// <summary>
        /// Converts a list of CosmosElements into a memory stream.
        /// </summary>
        /// <param name="containerRid">Container Rid</param>
        /// <param name="cosmosElements">The cosmos elements</param>
        /// <param name="resourceType">The resource type</param>
        /// <param name="cosmosSerializationOptions">The custom serialization options. This allows custom serialization types like BSON, JSON, or other formats</param>
        /// <returns>Returns a memory stream of cosmos elements. By default the memory stream will contain JSON.</returns>
        internal static MemoryStream ToStream(
            string containerRid,
            IEnumerable <CosmosElement> cosmosElements,
            ResourceType resourceType,
            CosmosSerializationFormatOptions cosmosSerializationOptions = null)
        {
            IJsonWriter jsonWriter;

            if (cosmosSerializationOptions != null)
            {
                jsonWriter = cosmosSerializationOptions.CreateCustomWriterCallback();
            }
            else
            {
                jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text);
            }

            // The stream contract should return the same contract as read feed.
            // {
            //    "_rid": "qHVdAImeKAQ=",
            //    "Documents": [{
            //        "id": "03230",
            //        "_rid": "qHVdAImeKAQBAAAAAAAAAA==",
            //        "_self": "dbs\/qHVdAA==\/colls\/qHVdAImeKAQ=\/docs\/qHVdAImeKAQBAAAAAAAAAA==\/",
            //        "_etag": "\"410000b0-0000-0000-0000-597916b00000\"",
            //        "_attachments": "attachments\/",
            //        "_ts": 1501107886
            //    }],
            //    "_count": 1
            // }

            jsonWriter.WriteObjectStart();

            // Write the rid field and value
            jsonWriter.WriteFieldName("_rid");
            jsonWriter.WriteStringValue(containerRid);

            // Write the array of elements
            string rootName = CosmosElementSerializer.GetRootNodeName(resourceType);

            jsonWriter.WriteFieldName(rootName);

            int count = 0;

            jsonWriter.WriteArrayStart();
            foreach (CosmosElement element in cosmosElements)
            {
                count++;
                element.WriteTo(jsonWriter);
            }

            jsonWriter.WriteArrayEnd();

            // Write the count field and value
            jsonWriter.WriteFieldName("_count");
            jsonWriter.WriteNumber64Value(count);

            jsonWriter.WriteObjectEnd();

            ReadOnlyMemory <byte> result = jsonWriter.GetResult();

            if (!MemoryMarshal.TryGetArray(result, out ArraySegment <byte> resultAsArray))
            {
                resultAsArray = new ArraySegment <byte>(result.ToArray());
            }

            return(new MemoryStream(resultAsArray.Array, resultAsArray.Offset, resultAsArray.Count));
        }
Пример #21
0
        public static void AddMetadataReader(WicProcessingContext ctx, bool basicOnly = false)
        {
            if (ctx.DecoderFrame.Frame is null)
            {
                return;
            }

            if (ctx.DecoderFrame.Frame.TryGetMetadataQueryReader(out var metareader))
            {
                ctx.AddRef(metareader);

                // Exif orientation
                var pvorient = default(PropVariant);
                if (ctx.Settings.OrientationMode != OrientationMode.Ignore && metareader.TryGetMetadataByName("System.Photo.Orientation", out pvorient))
                {
#pragma warning disable 0618 // VarEnum is obsolete
                    if (ctx.Settings.OrientationMode == OrientationMode.Normalize && pvorient.UnmanagedType == VarEnum.VT_UI2)
                    {
                        ctx.DecoderFrame.ExifOrientation = (Orientation)Math.Min(Math.Max((ushort)Orientation.Normal, (ushort)pvorient.Value), (ushort)Orientation.Rotate270);
                    }
#pragma warning restore 0618

                    var opt = ctx.DecoderFrame.ExifOrientation.ToWicTransformOptions();
                    if (ctx.DecoderFrame.SupportsPlanarPipeline && opt != WICBitmapTransformOptions.WICBitmapTransformRotate0 && ctx.DecoderFrame.Frame is IWICPlanarBitmapSourceTransform ptrans)
                    {
                        uint pw = 1, ph = 1;
                        var  desc = new WICBitmapPlaneDescription[2];
                        ctx.DecoderFrame.SupportsPlanarPipeline = ptrans.DoesSupportTransform(ref pw, ref ph, opt, WICPlanarOptions.WICPlanarOptionsDefault, planarPixelFormats, desc, 2);
                    }
                }

                if (basicOnly)
                {
                    return;
                }

                // other requested properties
                var propdic = new Dictionary <string, PropVariant>();
                foreach (string prop in ctx.Settings.MetadataNames ?? Enumerable.Empty <string>())
                {
                    if (metareader.TryGetMetadataByName(prop, out var pvar) && pvar.Value != null)
                    {
                        propdic[prop] = pvar;
                    }
                }

                if (ctx.Settings.OrientationMode == OrientationMode.Preserve && pvorient != null)
                {
                    propdic["System.Photo.Orientation"] = pvorient;
                }

                ctx.DecoderFrame.Metadata = propdic;
            }

            if (basicOnly)
            {
                return;
            }

            // ICC profiles
            //http://ninedegreesbelow.com/photography/embedded-color-space-information.html
            uint ccc      = ctx.DecoderFrame.Frame.GetColorContextCount();
            var  fmt      = ctx.Source.Format;
            var  profiles = new IWICColorContext[ccc];
            var  profile  = default(IWICColorContext);

            if (ccc > 0)
            {
                for (int i = 0; i < ccc; i++)
                {
                    profiles[i] = ctx.AddRef(Wic.Factory.CreateColorContext());
                }

                ctx.DecoderFrame.Frame.GetColorContexts(ccc, profiles);
            }

            foreach (var cc in profiles)
            {
                var cct = cc.GetType();
                if (cct == WICColorContextType.WICColorContextProfile)
                {
                    int ccs = (int)cc.GetProfileBytes(0, null);

                    // don't try to read giant profiles. 4MiB is more than enough
                    if ((uint)ccs > (1024 * 1024 * 4))
                    {
                        continue;
                    }

                    using (var ccb = MemoryPool <byte> .Shared.Rent(ccs))
                    {
                        MemoryMarshal.TryGetArray(ccb.Memory.Slice(0, ccs), out ArraySegment <byte> cca);
                        cc.GetProfileBytes((uint)cca.Count, cca.Array);
                        var cpi = ColorProfile.Cache.GetOrAdd(cca);

                        // match only color profiles that match our intended use. if we have a standard sRGB profile, don't save it; we don't need to convert
                        if (cpi.IsValid && (
                                (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Rgb && (fmt.ColorRepresentation == PixelColorRepresentation.Bgr || fmt.ColorRepresentation == PixelColorRepresentation.Rgb) && !cpi.IsSrgb) ||
                                (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Grey && fmt.ColorRepresentation == PixelColorRepresentation.Grey && !cpi.IsSrgbCurve) ||
                                (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Cmyk && fmt.ColorRepresentation == PixelColorRepresentation.Cmyk)
                                ))
                        {
                            profile = cc;
                            if (cpi.IsRgbMatrix || cpi.IsGreyTrc)
                            {
                                ctx.SourceColorProfile = cpi;
                            }
                            break;
                        }
                    }
                }
                else if (cct == WICColorContextType.WICColorContextExifColorSpace && cc.GetExifColorSpace() == ExifColorSpace.AdobeRGB)
                {
                    profile = cc;
                    break;
                }
            }

            var defaultColorContext = fmt.ColorRepresentation == PixelColorRepresentation.Grey ? Wic.GreyContext.Value : Wic.SrgbContext.Value;
            ctx.SourceColorContext = profile ?? (fmt.ColorRepresentation == PixelColorRepresentation.Cmyk ? Wic.CmykContext.Value : null);
            ctx.DestColorContext   = ctx.Settings.ColorProfileMode <= ColorProfileMode.NormalizeAndEmbed || ctx.SourceColorContext is null ? defaultColorContext : ctx.SourceColorContext;

            var defaultColorProfile = fmt.ColorRepresentation == PixelColorRepresentation.Grey ? ColorProfile.sGrey : ColorProfile.sRGB;
            ctx.SourceColorProfile = ctx.SourceColorProfile ?? defaultColorProfile;
            ctx.DestColorProfile   = ctx.Settings.ColorProfileMode <= ColorProfileMode.NormalizeAndEmbed ? defaultColorProfile : ctx.SourceColorProfile;
        }
        /// <summary>
        /// Generate a forward-only sequence of substreams based on bufferSize.
        /// </summary>
        /// <returns>StreamPartition</returns>
        private async Task <StreamPartition> GetNextPartitionAsync(Func <long, Stream> streamSource, bool disposeStream, Func <long> getStartPosition, Action <int> incrementStartPosition, int size = Constants.DefaultBufferSize, bool async = true, CancellationToken ct = default)
        {
            if (async)
            {
                await _getNextPartitionAsync_Semaphore.WaitAsync(ct).ConfigureAwait(false);
            }
            else
            {
                _getNextPartitionAsync_Semaphore.Wait();
            }

            var    startPosition = getStartPosition();
            Stream stream        = streamSource(startPosition);

            IMemoryOwner <byte> buffer;

            lock (_memoryPool)
            {
                // TODO these operations should be simplified with Memory- and Span-accepting APIs in future NET Standard
                buffer = _memoryPool.Rent(size);
            }

            //Console.WriteLine($"Rented buffer of size {size} bytes");
            //this.logger?.LogTrace($"Rented buffer of size {size} bytes");

            if (MemoryMarshal.TryGetArray <byte>(buffer.Memory, out ArraySegment <byte> segment))
            {
                var count =
                    async
                    ? await stream.ReadAsync(segment.Array, 0, segment.Count, ct).ConfigureAwait(false)
                    : stream.Read(segment.Array, 0, segment.Count);

                if (disposeStream)
                {
                    stream.Dispose();
                }

                incrementStartPosition(count);

                _getNextPartitionAsync_Semaphore.Release();

                //this.logger?.LogTrace($"Read {count} bytes");

                var partition = new StreamPartition(
                    buffer.Memory,
                    startPosition,
                    count,
                    () =>
                {
                    buffer.Dispose();
                    //Console.WriteLine($"Disposed buffer of size {size} bytes");
                    //this.logger?.LogTrace($"Disposed buffer of size {size} bytes");
                },
                    ct
                    );

                //Console.WriteLine($"Creating partition {partition.ParentPosition}");

                return(partition);
            }
            else
            {
                if (disposeStream)
                {
                    stream.Dispose();
                }

                _getNextPartitionAsync_Semaphore.Release();
                throw Errors.UnableAccessArray();
            }
        }
Пример #23
0
 public static int Send(this Socket socket, ReadOnlyMemory <byte> data, SocketFlags flags)
 {
     MemoryMarshal.TryGetArray(data, out var arraySegment);
     return(socket.Send(arraySegment.Array, arraySegment.Offset, arraySegment.Count, flags));
 }
Пример #24
0
 public static void SetBuffer(this SocketAsyncEventArgs args, Memory <byte> buffer)
 {
     MemoryMarshal.TryGetArray <byte>(buffer, out var arraySegment);
     args.SetBuffer(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
 }
Пример #25
0
 protected override bool TryGetArray(out ArraySegment <byte> segment)
 {
     _pool.CheckDisposed();
     return(MemoryMarshal.TryGetArray(_owner.Memory, out segment));
 }
Пример #26
0
        public static async Task RewriteStreamAsTextAsync(ResponseMessage responseMessage, QueryRequestOptions requestOptions)
        {
            // Rewrite the payload to be in the specified format.
            // If it's already in the correct format, then the following will be a memcpy.
            MemoryStream memoryStream;

            if (responseMessage.Content is MemoryStream responseContentAsMemoryStream)
            {
                memoryStream = responseContentAsMemoryStream;
            }
            else
            {
                memoryStream = new MemoryStream();
                await responseMessage.Content.CopyToAsync(memoryStream);
            }

            ReadOnlyMemory <byte> buffer;

            if (memoryStream.TryGetBuffer(out ArraySegment <byte> segment))
            {
                buffer = segment.Array.AsMemory().Slice(start: segment.Offset, length: segment.Count);
            }
            else
            {
                buffer = memoryStream.ToArray();
            }

            IJsonNavigator jsonNavigator = JsonNavigator.Create(buffer);

            if (jsonNavigator.SerializationFormat == JsonSerializationFormat.Text)
            {
                // Exit to avoid the memory allocation.
                return;
            }

            IJsonWriter jsonWriter;

            if (requestOptions?.CosmosSerializationFormatOptions != null)
            {
                jsonWriter = requestOptions.CosmosSerializationFormatOptions.CreateCustomWriterCallback();
            }
            else
            {
                jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text);
            }

            jsonNavigator.WriteTo(jsonNavigator.GetRootNode(), jsonWriter);

            ReadOnlyMemory <byte> result = jsonWriter.GetResult();
            MemoryStream          rewrittenMemoryStream;

            if (MemoryMarshal.TryGetArray(result, out ArraySegment <byte> rewrittenSegment))
            {
                rewrittenMemoryStream = new MemoryStream(rewrittenSegment.Array, index: rewrittenSegment.Offset, count: rewrittenSegment.Count, writable: false, publiclyVisible: true);
            }
            else
            {
                byte[] toArray = result.ToArray();
                rewrittenMemoryStream = new MemoryStream(toArray, index: 0, count: toArray.Length, writable: false, publiclyVisible: true);
            }

            responseMessage.Content = rewrittenMemoryStream;
        }
Пример #27
0
            public override string GetContinuationToken()
            {
                IJsonWriter jsonWriter = JsonWriter.Create(JsonSerializationFormat.Binary);

                jsonWriter.WriteObjectStart();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.NumbersName);
                jsonWriter.WriteArrayStart();
                foreach (Number64 number in this.numbers)
                {
                    jsonWriter.WriteNumberValue(number);
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.StringsLength4Name);
                jsonWriter.WriteArrayStart();
                foreach (uint stringLength4 in this.stringsLength4)
                {
                    jsonWriter.WriteUInt32Value(stringLength4);
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.StringsLength8Name);
                jsonWriter.WriteArrayStart();
                foreach (ulong stringLength8 in this.stringsLength8)
                {
                    jsonWriter.WriteInt64Value((long)stringLength8);
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.StringsLength16Name);
                jsonWriter.WriteArrayStart();
                foreach (UInt128 stringLength16 in this.stringsLength16)
                {
                    jsonWriter.WriteBinaryValue(UInt128.ToByteArray(stringLength16));
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.StringsLength16PlusName);
                jsonWriter.WriteArrayStart();
                foreach (UInt128 stringLength16Plus in this.stringsLength16Plus)
                {
                    jsonWriter.WriteBinaryValue(UInt128.ToByteArray(stringLength16Plus));
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.ArraysName);
                jsonWriter.WriteArrayStart();
                foreach (UInt128 array in this.arrays)
                {
                    jsonWriter.WriteBinaryValue(UInt128.ToByteArray(array));
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.ObjectName);
                jsonWriter.WriteArrayStart();
                foreach (UInt128 objectHash in this.objects)
                {
                    jsonWriter.WriteBinaryValue(UInt128.ToByteArray(objectHash));
                }
                jsonWriter.WriteArrayEnd();

                jsonWriter.WriteFieldName(UnorderdDistinctMap.SimpleValuesName);
                jsonWriter.WriteStringValue(this.simpleValues.ToString());

                jsonWriter.WriteObjectEnd();

                ReadOnlyMemory <byte> memory = jsonWriter.GetResult();

                if (!MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> buffer))
                {
                    buffer = new ArraySegment <byte>(memory.ToArray());
                }

                return(Convert.ToBase64String(buffer.Array, buffer.Offset, buffer.Count));
            }
Пример #28
0
 public IList <TKey> Convert(ReadOnlyMemory <TKey> keys)
 {
     return(MemoryMarshal.TryGetArray(keys, out var arraySegment)
         ? (IList <TKey>)arraySegment
         : keys.ToArray());
 }
Пример #29
0
        private async Task InitSocket()
        {
            while (!_cancellationToken.IsCancellationRequested)
            {
                Socket clientSocket = null;
                try
                {
                    clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                    await clientSocket.ConnectAsync(_settings.Server, _settings.Port);

                    do
                    {
                        byte[]        array  = new byte[8192];
                        Memory <byte> memory = new Memory <byte>(array);
                        await clientSocket.ReceiveAsync(memory, SocketFlags.None, _cancellationToken);

                        ArraySegment <byte> segment = default;
                        bool leased = false;
                        try
                        {
                            if (!MemoryMarshal.TryGetArray <byte>(memory, out segment))
                            {
                                var arr = ArrayPool <byte> .Shared.Rent(memory.Length);

                                memory.CopyTo(arr);
                                segment = new ArraySegment <byte>(arr, 0, memory.Length);
                                leased  = true;
                            }
                            using (var ms = new MemoryStream(segment.Array, segment.Offset, segment.Count))
                            {
                                var settings = new XmlReaderSettings();
                                settings.Schemas.Add(xsd);
                                settings.ValidationType = ValidationType.None;
                                using (var xmlReader = XmlReader.Create(ms, _xmlReaderSettings, _context))
                                {
                                    var le = ParseLog4NetXmlLogEvent(xmlReader, "eds");
                                    if (le != null)
                                    {
                                        foreach (var log in le)
                                        {
                                            await _logProcessor.ProcessLog(log);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            if (leased)
                            {
                                ArrayPool <byte> .Shared.Return(segment.Array);
                            }
                        }
                    } while (!_cancellationToken.IsCancellationRequested);
                }
                catch (Exception ex)
                {
                    clientSocket?.Dispose();
                    //reconnect
                }
            }
        }
Пример #30
0
 public override string ToBase64(ReadOnlyMemory <byte> value)
 {
     return(MemoryMarshal.TryGetArray(value, out var segment)
         ? Convert.ToBase64String(segment.Array, 0, segment.Count)
         : Convert.ToBase64String(value.ToArray()));
 }