text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Buffers.Binary;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.Http.HPack;
using System.Threading.Channels;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeWriterHelpers;

namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;

internal sealed class Http2FrameWriter
{
    // Literal Header Field without Indexing - Indexed Name (Index 8 - :status)
    // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
    private static ReadOnlySpan<byte> ContinueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' };

    private readonly object _writeLock = new object();
    private readonly Http2Frame _outgoingFrame;
    private readonly Http2HeadersEnumerator _headersEnumerator = new Http2HeadersEnumerator();
    private readonly ConcurrentPipeWriter _outputWriter;
    private readonly BaseConnectionContext _connectionContext;
    private readonly Http2Connection _http2Connection;
    private readonly string _connectionId;
    private readonly KestrelTrace _log;
    private readonly ITimeoutControl _timeoutControl;
    private readonly MinDataRate? _minResponseDataRate;
    private readonly TimingPipeFlusher _flusher;
    private readonly DynamicHPackEncoder _hpackEncoder;
    private readonly Channel<Http2OutputProducer> _channel;

    // This is only set to true by tests.
    private readonly bool _scheduleInline;

    private uint _maxFrameSize = Http2PeerSettings.MinAllowedMaxFrameSize;
    private byte[] _headerEncodingBuffer;
    private long _unflushedBytes;

    private bool _completed;
    private bool _aborted;

    private readonly object _windowUpdateLock = new();
    private long _connectionWindow;
    private readonly Queue<Http2OutputProducer> _waitingForMoreConnectionWindow = new();
    // This is the stream that consumed the last set of connection window
    private Http2OutputProducer? _lastWindowConsumer;
    private readonly Task _writeQueueTask;

    public Http2FrameWriter(
        PipeWriter outputPipeWriter,
        BaseConnectionContext connectionContext,
        Http2Connection http2Connection,
        int maxStreamsPerConnection,
        ITimeoutControl timeoutControl,
        MinDataRate? minResponseDataRate,
        string connectionId,
        MemoryPool<byte> memoryPool,
        ServiceContext serviceContext)
    {
        // Allow appending more data to the PipeWriter when a flush is pending.
        _outputWriter = new ConcurrentPipeWriter(outputPipeWriter, memoryPool, _writeLock);
        _connectionContext = connectionContext;
        _http2Connection = http2Connection;
        _connectionId = connectionId;
        _log = serviceContext.Log;
        _timeoutControl = timeoutControl;
        _minResponseDataRate = minResponseDataRate;
        _flusher = new TimingPipeFlusher(timeoutControl, serviceContext.Log);
        _flusher.Initialize(_outputWriter);
        _outgoingFrame = new Http2Frame();
        _headerEncodingBuffer = new byte[_maxFrameSize];

        _scheduleInline = serviceContext.Scheduler == PipeScheduler.Inline;

        _hpackEncoder = new DynamicHPackEncoder(serviceContext.ServerOptions.AllowResponseHeaderCompression);

        // This is bounded by the maximum number of concurrent Http2Streams per Http2Connection.
        // This isn't the same as SETTINGS_MAX_CONCURRENT_STREAMS, but typically double (with a floor of 100)
        // which is the max number of Http2Streams that can end up in the Http2Connection._streams dictionary.
        //
        // Setting a lower limit of SETTINGS_MAX_CONCURRENT_STREAMS might be sufficient because a stream shouldn't
        // be rescheduling itself after being completed or canceled, but we're going with the more conservative limit
        // in case there's some logic scheduling completed or canceled streams unnecessarily.
        _channel = Channel.CreateBounded<Http2OutputProducer>(new BoundedChannelOptions(maxStreamsPerConnection)
        {
            AllowSynchronousContinuations = _scheduleInline,
            SingleReader = true
        });

        _connectionWindow = Http2PeerSettings.DefaultInitialWindowSize;

        _writeQueueTask = Task.Run(WriteToOutputPipe);
    }

    public void Schedule(Http2OutputProducer producer)
    {
        if (!_channel.Writer.TryWrite(producer))
        {
            // It should not be possible to exceed the bound of the channel.
            var ex = new ConnectionAbortedException("HTTP/2 connection exceeded the output operations maximum queue size.");
            _log.Http2QueueOperationsExceeded(_connectionId, ex);
            _http2Connection.Abort(ex);
        }
    }

    private async Task WriteToOutputPipe()
    {
        while (await _channel.Reader.WaitToReadAsync())
        {
            // We need to handle the case where aborts can be scheduled while this loop is running and might be on the way to complete
            // the reader.
            while (_channel.Reader.TryRead(out var producer) && !producer.CompletedResponse)
            {
                try
                {
                    var reader = producer.PipeReader;
                    var stream = producer.Stream;

                    // We don't need to check the result because it's either
                    // - true because we have a result
                    // - false because we're flushing headers
                    reader.TryRead(out var readResult);
                    var buffer = readResult.Buffer;

                    // Check the stream window
                    var actual = producer.CheckStreamWindow(buffer.Length);

                    // Now check the connection window
                    actual = CheckConnectionWindow(actual);

                    // Write what we can
                    if (actual < buffer.Length)
                    {
                        buffer = buffer.Slice(0, actual);
                    }

                    // Consume the actual bytes resolved after checking both connection and stream windows
                    producer.ConsumeStreamWindow(actual);
                    ConsumeConnectionWindow(actual);

                    // Stash the unobserved state, we're going to mark this snapshot as observed
                    var observed = producer.UnobservedState;
                    var currentState = producer.CurrentState;

                    // Avoid boxing the enum (though the JIT optimizes this eventually)
                    static bool HasStateFlag(Http2OutputProducer.State state, Http2OutputProducer.State flags)
                        => (state & flags) == flags;

                    // Check if we need to write headers
                    var flushHeaders = HasStateFlag(observed, Http2OutputProducer.State.FlushHeaders) && !HasStateFlag(currentState, Http2OutputProducer.State.FlushHeaders);

                    (var hasMoreData, var reschedule, currentState, var waitingForWindowUpdates) = producer.ObserveDataAndState(buffer.Length, observed);

                    var aborted = HasStateFlag(currentState, Http2OutputProducer.State.Aborted);
                    var completed = HasStateFlag(currentState, Http2OutputProducer.State.Completed) && !hasMoreData;

                    FlushResult flushResult = default;

                    // We're not complete but we got the abort.
                    if (aborted && !completed)
                    {
                        // Response body is aborted, complete reader for this output producer.
                        if (flushHeaders)
                        {
                            // write headers
                            WriteResponseHeaders(stream.StreamId, stream.StatusCode, Http2HeadersFrameFlags.NONE, (HttpResponseHeaders)stream.ResponseHeaders);
                        }

                        if (actual > 0)
                        {
                            // actual > int.MaxValue should never be possible because it would exceed Http2PeerSettings.MaxWindowSize
                            // which is a protocol-defined limit. There's no way Kestrel would try to write more than that in one go.
                            Debug.Assert(actual <= int.MaxValue);

                            // If we got here it means we're going to cancel the write. Restore any consumed bytes to the connection window.
                            if (!TryUpdateConnectionWindow((int)actual))
                            {
                                // This branch can only ever be taken given both a buggy client and aborting streams mid-write. Even then, we're much more likely catch the
                                // error in Http2Connection.ProcessFrameAsync() before catching it here. This branch is technically possible though, so we defend against it.
                                await HandleFlowControlErrorAsync();
                                return;
                            }
                        }
                    }
                    else if (completed && stream.ResponseTrailers is { Count: > 0 })
                    {
                        // Output is ending and there are trailers to write
                        // Write any remaining content then write trailers and there's no
                        // flow control back pressure being applied (hasMoreData)

                        stream.ResponseTrailers.SetReadOnly();
                        stream.DecrementActiveClientStreamCount();

                        // It is faster to write data and trailers together. Locking once reduces lock contention.
                        flushResult = await WriteDataAndTrailersAsync(stream, buffer, flushHeaders, stream.ResponseTrailers);
                    }
                    else if (completed && producer.AppCompletedWithNoResponseBodyOrTrailers)
                    {
                        Debug.Assert(flushHeaders, "The app completed successfully without flushing headers!");

                        if (buffer.Length != 0)
                        {
                            _log.Http2UnexpectedDataRemaining(stream.StreamId, _connectionId);
                        }
                        else
                        {
                            stream.DecrementActiveClientStreamCount();

                            flushResult = await FlushEndOfStreamHeadersAsync(stream);
                        }
                    }
                    else
                    {
                        var endStream = completed;

                        if (endStream)
                        {
                            stream.DecrementActiveClientStreamCount();
                        }

                        flushResult = await WriteDataAsync(stream, buffer, buffer.Length, endStream, flushHeaders);
                    }

                    if (producer.IsTimingWrite)
                    {
                        _timeoutControl.StopTimingWrite();
                    }

                    reader.AdvanceTo(buffer.End);

                    if (completed || aborted)
                    {
                        await reader.CompleteAsync();

                        await producer.CompleteResponseAsync();
                    }
                    // We're not going to schedule this again if there's no remaining window.
                    // When the window update is sent, the producer will be re-queued if needed.
                    else if (hasMoreData && !aborted && !waitingForWindowUpdates)
                    {
                        // If we queued the connection for a window update or we were unable to schedule the next write
                        // then we're waiting for a window update to resume the scheduling.
                        if (TryQueueProducerForConnectionWindowUpdate(actual, producer) ||
                            !producer.TryScheduleNextWriteIfStreamWindowHasSpace())
                        {
                            // Include waiting for window updates in timing writes
                            if (_minResponseDataRate != null)
                            {
                                producer.IsTimingWrite = true;
                                _timeoutControl.StartTimingWrite();
                            }
                        }
                    }
                    else if (reschedule)
                    {
                        producer.Schedule();
                    }
                }
                catch (Exception ex)
                {
                    _log.Http2UnexpectedConnectionQueueError(_connectionId, ex);
                }
            }
        }

        _log.Http2ConnectionQueueProcessingCompleted(_connectionId);
    }

    private async Task HandleFlowControlErrorAsync()
    {
        var connectionError = new Http2ConnectionErrorException(CoreStrings.Http2ErrorWindowUpdateSizeInvalid, Http2ErrorCode.FLOW_CONTROL_ERROR);
        _log.Http2ConnectionError(_connectionId, connectionError);
        await WriteGoAwayAsync(int.MaxValue, Http2ErrorCode.FLOW_CONTROL_ERROR);

        // Prevent Abort() from writing an INTERNAL_ERROR GOAWAY frame after our FLOW_CONTROL_ERROR.
        Complete();
        // Stop processing any more requests and immediately close the connection.
        _http2Connection.Abort(new ConnectionAbortedException(CoreStrings.Http2ErrorWindowUpdateSizeInvalid, connectionError));
    }

    private bool TryQueueProducerForConnectionWindowUpdate(long actual, Http2OutputProducer producer)
    {
        lock (_windowUpdateLock)
        {
            // Check the connection window under a lock so that we don't miss window updates
            if (_connectionWindow == 0)
            {
                // We have no more connection window, put this producer in a queue waiting for
                // a window update to resume the producer.

                // In order to make scheduling more fair we want to make sure that streams that have data get a chance to run in a round robin manner.
                // To do this we will store the producer that consumed the window in a field and put it to the back of the queue.

                producer.SetWaitingForWindowUpdates();

                if (actual != 0 && _lastWindowConsumer is null)
                {
                    _lastWindowConsumer = producer;
                }
                else
                {
                    _waitingForMoreConnectionWindow.Enqueue(producer);
                }

                return true;
            }
        }

        return false;
    }

    public void UpdateMaxHeaderTableSize(uint maxHeaderTableSize)
    {
        lock (_writeLock)
        {
            _hpackEncoder.UpdateMaxHeaderTableSize(maxHeaderTableSize);
        }
    }

    public void UpdateMaxFrameSize(uint maxFrameSize)
    {
        lock (_writeLock)
        {
            if (_maxFrameSize != maxFrameSize)
            {
                _maxFrameSize = maxFrameSize;
                _headerEncodingBuffer = new byte[_maxFrameSize];
            }
        }
    }

    public void Complete()
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return;
            }

            _completed = true;
            AbortConnectionFlowControl();
            _outputWriter.Abort();
        }
    }

    public Task ShutdownAsync()
    {
        _channel.Writer.TryComplete();

        return _writeQueueTask;
    }

    public void Abort(ConnectionAbortedException error)
    {
        lock (_writeLock)
        {
            if (_aborted)
            {
                return;
            }

            _aborted = true;
            _connectionContext.Abort(error);

            Complete();
        }
    }

    private ValueTask<FlushResult> FlushEndOfStreamHeadersAsync(Http2Stream stream)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            WriteResponseHeadersUnsynchronized(stream.StreamId, stream.StatusCode, Http2HeadersFrameFlags.END_STREAM, (HttpResponseHeaders)stream.ResponseHeaders);

            var bytesWritten = _unflushedBytes;
            _unflushedBytes = 0;

            return _flusher.FlushAsync(_minResponseDataRate, bytesWritten);
        }
    }

    public ValueTask<FlushResult> Write100ContinueAsync(int streamId)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId);
            _outgoingFrame.PayloadLength = ContinueBytes.Length;
            WriteHeaderUnsynchronized();
            _outputWriter.Write(ContinueBytes);
            return TimeFlushUnsynchronizedAsync();
        }
    }

    // Optional header fields for padding and priority are not implemented.
    /* https://tools.ietf.org/html/rfc7540#section-6.2
        +---------------+
        |Pad Length? (8)|
        +-+-------------+-----------------------------------------------+
        |E|                 Stream Dependency? (31)                     |
        +-+-------------+-----------------------------------------------+
        |  Weight? (8)  |
        +-+-------------+-----------------------------------------------+
        |                   Header Block Fragment (*)                 ...
        +---------------------------------------------------------------+
        |                           Padding (*)                       ...
        +---------------------------------------------------------------+
    */
    public void WriteResponseHeaders(int streamId, int statusCode, Http2HeadersFrameFlags headerFrameFlags, HttpResponseHeaders headers)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return;
            }

            WriteResponseHeadersUnsynchronized(streamId, statusCode, headerFrameFlags, headers);
        }
    }

    private void WriteResponseHeadersUnsynchronized(int streamId, int statusCode, Http2HeadersFrameFlags headerFrameFlags, HttpResponseHeaders headers)
    {
        try
        {
            _headersEnumerator.Initialize(headers);
            _outgoingFrame.PrepareHeaders(headerFrameFlags, streamId);
            var buffer = _headerEncodingBuffer.AsSpan();
            var done = HPackHeaderWriter.BeginEncodeHeaders(statusCode, _hpackEncoder, _headersEnumerator, buffer, out var payloadLength);
            FinishWritingHeaders(streamId, payloadLength, done);
        }
        // Any exception from the HPack encoder can leave the dynamic table in a corrupt state.
        // Since we allow custom header encoders we don't know what type of exceptions to expect.
        catch (Exception ex)
        {
            _log.HPackEncodingError(_connectionId, streamId, ex);
            _http2Connection.Abort(new ConnectionAbortedException(ex.Message, ex));
        }
    }

    private ValueTask<FlushResult> WriteDataAndTrailersAsync(Http2Stream stream, in ReadOnlySequence<byte> data, bool writeHeaders, HttpResponseTrailers headers)
    {
        // The Length property of a ReadOnlySequence can be expensive, so we cache the value.
        var dataLength = data.Length;

        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            var streamId = stream.StreamId;

            if (writeHeaders)
            {
                WriteResponseHeadersUnsynchronized(streamId, stream.StatusCode, Http2HeadersFrameFlags.NONE, (HttpResponseHeaders)stream.ResponseHeaders);
            }

            if (dataLength > 0)
            {
                WriteDataUnsynchronized(streamId, data, dataLength, endStream: false);
            }

            try
            {
                _headersEnumerator.Initialize(headers);
                _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_STREAM, streamId);
                var buffer = _headerEncodingBuffer.AsSpan();
                var done = HPackHeaderWriter.BeginEncodeHeaders(_hpackEncoder, _headersEnumerator, buffer, out var payloadLength);
                FinishWritingHeaders(streamId, payloadLength, done);
            }
            // Any exception from the HPack encoder can leave the dynamic table in a corrupt state.
            // Since we allow custom header encoders we don't know what type of exceptions to expect.
            catch (Exception ex)
            {
                _log.HPackEncodingError(_connectionId, streamId, ex);
                _http2Connection.Abort(new ConnectionAbortedException(ex.Message, ex));
            }

            return TimeFlushUnsynchronizedAsync();
        }
    }

    private void FinishWritingHeaders(int streamId, int payloadLength, bool done)
    {
        var buffer = _headerEncodingBuffer.AsSpan();
        _outgoingFrame.PayloadLength = payloadLength;
        if (done)
        {
            _outgoingFrame.HeadersFlags |= Http2HeadersFrameFlags.END_HEADERS;
        }

        WriteHeaderUnsynchronized();
        _outputWriter.Write(buffer.Slice(0, payloadLength));

        while (!done)
        {
            _outgoingFrame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);

            done = HPackHeaderWriter.ContinueEncodeHeaders(_hpackEncoder, _headersEnumerator, buffer, out payloadLength);
            _outgoingFrame.PayloadLength = payloadLength;

            if (done)
            {
                _outgoingFrame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
            }

            WriteHeaderUnsynchronized();
            _outputWriter.Write(buffer.Slice(0, payloadLength));
        }
    }

    /*  Padding is not implemented
        +---------------+
        |Pad Length? (8)|
        +---------------+-----------------------------------------------+
        |                            Data (*)                         ...
        +---------------------------------------------------------------+
        |                           Padding (*)                       ...
        +---------------------------------------------------------------+
    */
    private void WriteDataUnsynchronized(int streamId, in ReadOnlySequence<byte> data, long dataLength, bool endStream)
    {
        Debug.Assert(dataLength == data.Length);

        // Note padding is not implemented
        _outgoingFrame.PrepareData(streamId);

        if (dataLength > _maxFrameSize) // Minus padding
        {
            TrimAndWriteDataUnsynchronized(in data, dataLength, endStream);
            return;
        }

        if (endStream)
        {
            _outgoingFrame.DataFlags |= Http2DataFrameFlags.END_STREAM;
        }

        _outgoingFrame.PayloadLength = (int)dataLength; // Plus padding

        WriteHeaderUnsynchronized();

        data.CopyTo(_outputWriter);

        // Plus padding
        return;

        void TrimAndWriteDataUnsynchronized(in ReadOnlySequence<byte> data, long dataLength, bool endStream)
        {
            Debug.Assert(dataLength == data.Length);

            var dataPayloadLength = (int)_maxFrameSize; // Minus padding

            Debug.Assert(dataLength > dataPayloadLength);

            var remainingData = data;
            do
            {
                var currentData = remainingData.Slice(0, dataPayloadLength);
                _outgoingFrame.PayloadLength = dataPayloadLength; // Plus padding

                WriteHeaderUnsynchronized();

                currentData.CopyTo(_outputWriter);

                // Plus padding
                dataLength -= dataPayloadLength;
                remainingData = remainingData.Slice(dataPayloadLength);

            } while (dataLength > dataPayloadLength);

            if (endStream)
            {
                _outgoingFrame.DataFlags |= Http2DataFrameFlags.END_STREAM;
            }

            _outgoingFrame.PayloadLength = (int)dataLength; // Plus padding

            WriteHeaderUnsynchronized();

            remainingData.CopyTo(_outputWriter);

            // Plus padding
        }
    }

    private ValueTask<FlushResult> WriteDataAsync(Http2Stream stream, ReadOnlySequence<byte> data, long dataLength, bool endStream, bool writeHeaders)
    {
        var writeTask = default(ValueTask<FlushResult>);

        lock (_writeLock)
        {
            if (_completed)
            {
                return ValueTask.FromResult<FlushResult>(default);
            }

            var shouldFlush = false;

            if (writeHeaders)
            {
                WriteResponseHeadersUnsynchronized(stream.StreamId, stream.StatusCode, Http2HeadersFrameFlags.NONE, (HttpResponseHeaders)stream.ResponseHeaders);

                shouldFlush = true;
            }

            if (dataLength > 0 || endStream)
            {
                WriteDataUnsynchronized(stream.StreamId, data, dataLength, endStream);

                shouldFlush = true;
            }

            if (_minResponseDataRate != null)
            {
                // Call BytesWrittenToBuffer before FlushAsync() to make testing easier, otherwise the Flush can cause test code to run before the timeout
                // control updates and if the test checks for a timeout it can fail
                _timeoutControl.BytesWrittenToBuffer(_minResponseDataRate, _unflushedBytes);
            }

            if (shouldFlush)
            {
                _unflushedBytes = 0;

                writeTask = _flusher.FlushAsync();
            }
        }

        if (writeTask.IsCompletedSuccessfully)
        {
            return new(writeTask.Result);
        }

        return FlushAsyncAwaited(writeTask, _timeoutControl, _minResponseDataRate);

        static async ValueTask<FlushResult> FlushAsyncAwaited(ValueTask<FlushResult> writeTask, ITimeoutControl timeoutControl, MinDataRate? minResponseDataRate)
        {
            if (minResponseDataRate != null)
            {
                timeoutControl.StartTimingWrite();
            }

            var flushResult = await writeTask;

            if (minResponseDataRate != null)
            {
                timeoutControl.StopTimingWrite();
            }
            return flushResult;
        }
    }

    /* https://tools.ietf.org/html/rfc7540#section-6.9
        +-+-------------------------------------------------------------+
        |R|              Window Size Increment (31)                     |
        +-+-------------------------------------------------------------+
    */
    public ValueTask<FlushResult> WriteWindowUpdateAsync(int streamId, int sizeIncrement)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareWindowUpdate(streamId, sizeIncrement);
            WriteHeaderUnsynchronized();
            var buffer = _outputWriter.GetSpan(4);
            Bitshifter.WriteUInt31BigEndian(buffer, (uint)sizeIncrement, preserveHighestBit: false);
            _outputWriter.Advance(4);
            return TimeFlushUnsynchronizedAsync();
        }
    }

    /* https://tools.ietf.org/html/rfc7540#section-6.4
        +---------------------------------------------------------------+
        |                        Error Code (32)                        |
        +---------------------------------------------------------------+
    */
    public ValueTask<FlushResult> WriteRstStreamAsync(int streamId, Http2ErrorCode errorCode)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareRstStream(streamId, errorCode);
            WriteHeaderUnsynchronized();
            var buffer = _outputWriter.GetSpan(4);
            BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)errorCode);
            _outputWriter.Advance(4);

            return TimeFlushUnsynchronizedAsync();
        }
    }

    /* https://tools.ietf.org/html/rfc7540#section-6.5.1
        List of:
        +-------------------------------+
        |       Identifier (16)         |
        +-------------------------------+-------------------------------+
        |                        Value (32)                             |
        +---------------------------------------------------------------+
    */
    public ValueTask<FlushResult> WriteSettingsAsync(List<Http2PeerSetting> settings)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareSettings(Http2SettingsFrameFlags.NONE);
            var settingsSize = settings.Count * Http2FrameReader.SettingSize;
            _outgoingFrame.PayloadLength = settingsSize;
            WriteHeaderUnsynchronized();

            var buffer = _outputWriter.GetSpan(settingsSize).Slice(0, settingsSize); // GetSpan isn't precise
            WriteSettings(settings, buffer);
            _outputWriter.Advance(settingsSize);

            return TimeFlushUnsynchronizedAsync();
        }
    }

    internal static void WriteSettings(List<Http2PeerSetting> settings, Span<byte> destination)
    {
        foreach (var setting in settings)
        {
            BinaryPrimitives.WriteUInt16BigEndian(destination, (ushort)setting.Parameter);
            BinaryPrimitives.WriteUInt32BigEndian(destination.Slice(2), setting.Value);
            destination = destination.Slice(Http2FrameReader.SettingSize);
        }
    }

    // No payload
    public ValueTask<FlushResult> WriteSettingsAckAsync()
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareSettings(Http2SettingsFrameFlags.ACK);
            WriteHeaderUnsynchronized();
            return TimeFlushUnsynchronizedAsync();
        }
    }

    /* https://tools.ietf.org/html/rfc7540#section-6.7
        +---------------------------------------------------------------+
        |                                                               |
        |                      Opaque Data (64)                         |
        |                                                               |
        +---------------------------------------------------------------+
    */
    public ValueTask<FlushResult> WritePingAsync(Http2PingFrameFlags flags, in ReadOnlySequence<byte> payload)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PreparePing(flags);
            Debug.Assert(payload.Length == _outgoingFrame.PayloadLength); // 8
            WriteHeaderUnsynchronized();
            foreach (var segment in payload)
            {
                _outputWriter.Write(segment.Span);
            }

            return TimeFlushUnsynchronizedAsync();
        }
    }

    /* https://tools.ietf.org/html/rfc7540#section-6.8
        +-+-------------------------------------------------------------+
        |R|                  Last-Stream-ID (31)                        |
        +-+-------------------------------------------------------------+
        |                      Error Code (32)                          |
        +---------------------------------------------------------------+
        |                  Additional Debug Data (*)                    | (not implemented)
        +---------------------------------------------------------------+
    */
    public ValueTask<FlushResult> WriteGoAwayAsync(int lastStreamId, Http2ErrorCode errorCode)
    {
        lock (_writeLock)
        {
            if (_completed)
            {
                return default;
            }

            _outgoingFrame.PrepareGoAway(lastStreamId, errorCode);
            WriteHeaderUnsynchronized();

            var buffer = _outputWriter.GetSpan(8);
            Bitshifter.WriteUInt31BigEndian(buffer, (uint)lastStreamId, preserveHighestBit: false);
            buffer = buffer.Slice(4);
            BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)errorCode);
            _outputWriter.Advance(8);

            return TimeFlushUnsynchronizedAsync();
        }
    }

    private void WriteHeaderUnsynchronized()
    {
        _log.Http2FrameSending(_connectionId, _outgoingFrame);
        WriteHeader(_outgoingFrame, _outputWriter);

        // We assume the payload will be written prior to the next flush.
        _unflushedBytes += Http2FrameReader.HeaderLength + _outgoingFrame.PayloadLength;
    }

    /* https://tools.ietf.org/html/rfc7540#section-4.1
        +-----------------------------------------------+
        |                 Length (24)                   |
        +---------------+---------------+---------------+
        |   Type (8)    |   Flags (8)   |
        +-+-------------+---------------+-------------------------------+
        |R|                 Stream Identifier (31)                      |
        +=+=============================================================+
        |                   Frame Payload (0...)                      ...
        +---------------------------------------------------------------+
    */
    internal static void WriteHeader(Http2Frame frame, PipeWriter output)
    {
        var buffer = output.GetSpan(Http2FrameReader.HeaderLength);

        Bitshifter.WriteUInt24BigEndian(buffer, (uint)frame.PayloadLength);
        buffer = buffer.Slice(3);

        buffer[0] = (byte)frame.Type;
        buffer[1] = frame.Flags;
        buffer = buffer.Slice(2);

        Bitshifter.WriteUInt31BigEndian(buffer, (uint)frame.StreamId, preserveHighestBit: false);

        output.Advance(Http2FrameReader.HeaderLength);
    }

    private ValueTask<FlushResult> TimeFlushUnsynchronizedAsync()
    {
        var bytesWritten = _unflushedBytes;
        _unflushedBytes = 0;

        return _flusher.FlushAsync(_minResponseDataRate, bytesWritten);
    }

    private long CheckConnectionWindow(long bytes)
    {
        lock (_windowUpdateLock)
        {
            return Math.Min(bytes, _connectionWindow);
        }
    }

    private void ConsumeConnectionWindow(long bytes)
    {
        lock (_windowUpdateLock)
        {
            _connectionWindow -= bytes;
        }
    }

    private void AbortConnectionFlowControl()
    {
        lock (_windowUpdateLock)
        {
            if (_lastWindowConsumer is { } producer)
            {
                _lastWindowConsumer = null;

                // Put the consumer of the connection window last
                _waitingForMoreConnectionWindow.Enqueue(producer);
            }

            while (_waitingForMoreConnectionWindow.TryDequeue(out producer))
            {
                // Abort the stream
                producer.Stop();
            }
        }
    }

    public bool TryUpdateConnectionWindow(int bytes)
    {
        lock (_windowUpdateLock)
        {
            var maxUpdate = Http2PeerSettings.MaxWindowSize - _connectionWindow;

            if (bytes > maxUpdate)
            {
                return false;
            }

            _connectionWindow += bytes;

            if (_lastWindowConsumer is { } producer)
            {
                _lastWindowConsumer = null;

                // Put the consumer of the connection window last
                _waitingForMoreConnectionWindow.Enqueue(producer);
            }

            while (_waitingForMoreConnectionWindow.TryDequeue(out producer))
            {
                producer.ScheduleResumeFromWindowUpdate();
            }
        }
        return true;
    }
}


text:
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext, loader
from campuscollabapp.models import *

def index(request):
    ls = Post.objects.all()
    template = loader.get_template('campuscollabapp/index.html')
    context = RequestContext(request, {'posts': ls, })
    return HttpResponse(template.render(context))

def display(request, primary_key):

    template = loader.get_template('campuscollabapp/display.html')
    context = RequestContext(request, {
        })
    return HttpResponse("Currently viewing Category with Primary Key: " + primary_key)

redpajama_set_name: RedPajamaGithub


text:
package microsoft.exchange.webservices.data;

import microsoft.exchange.webservices.data.exception.ServiceValidationException;

/**
 * The Interface ISelfValidate.
 */
public interface ISelfValidate {

  /**
   * Validate.
   *
   * @throws microsoft.exchange.webservices.data.exception.ServiceValidationException the service validation exception
   * @throws Exception                  the exception
   */
  void validate() throws ServiceValidationException, Exception;
}


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

#if UNENG
namespace UnEngine {
#else
namespace UnityEngine {
#endif
    /// <summary>
    ///   <para>Class containing methods to ease debugging while developing a game.</para>
    /// </summary>
    public sealed class Debug {
        internal static ILogger s_Logger = (ILogger)new Logger((ILogHandler)new DebugLogHandler());

        /// <summary>
        ///   <para>Get default debug logger.</para>
        /// </summary>
        public static ILogger unityLogger {
            get {
                return Debug.s_Logger;
            }
        }

        /// <summary>
        ///   <para>Reports whether the development console is visible. The development console cannot be made to appear using:</para>
        /// </summary>
        public static bool developerConsoleVisible { get; set; } = false;

        /// <summary>
        ///   <para>In the Build Settings dialog there is a check box called "Development Build".</para>
        /// </summary>
        public static bool isDebugBuild {
            get {
#if DEBUG
                return true;
#else
                return false;
#endif
            }
        }

        [Obsolete("Debug.logger is obsolete. Please use Debug.unityLogger instead (UnityUpgradable) -> unityLogger")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static ILogger logger {
            get {
                return Debug.s_Logger;
            }
        }

        /// <summary>
        ///   <para>Draws a line between specified start and end points.</para>
        /// </summary>
        /// <param name="start">Point in world space where the line should start.</param>
        /// <param name="end">Point in world space where the line should end.</param>
        /// <param name="color">Color of the line.</param>
        /// <param name="duration">How long the line should be visible for.</param>
        /// <param name="depthTest">Should the line be obscured by objects closer to the camera?</param>
        public static void DrawLine(Vector3 start, Vector3 end, [DefaultValue("Color.white")] Color color, [DefaultValue("0.0f")] float duration, [DefaultValue("true")] bool depthTest) {
            Debug.INTERNAL_CALL_DrawLine(ref start, ref end, ref color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line between specified start and end points.</para>
        /// </summary>
        /// <param name="start">Point in world space where the line should start.</param>
        /// <param name="end">Point in world space where the line should end.</param>
        /// <param name="color">Color of the line.</param>
        /// <param name="duration">How long the line should be visible for.</param>
        /// <param name="depthTest">Should the line be obscured by objects closer to the camera?</param>
        public static void DrawLine(Vector3 start, Vector3 end, Color color, float duration) {
            bool depthTest = true;
            Debug.INTERNAL_CALL_DrawLine(ref start, ref end, ref color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line between specified start and end points.</para>
        /// </summary>
        /// <param name="start">Point in world space where the line should start.</param>
        /// <param name="end">Point in world space where the line should end.</param>
        /// <param name="color">Color of the line.</param>
        /// <param name="duration">How long the line should be visible for.</param>
        /// <param name="depthTest">Should the line be obscured by objects closer to the camera?</param>
        public static void DrawLine(Vector3 start, Vector3 end, Color color) {
            bool depthTest = true;
            float duration = 0.0f;
            Debug.INTERNAL_CALL_DrawLine(ref start, ref end, ref color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line between specified start and end points.</para>
        /// </summary>
        /// <param name="start">Point in world space where the line should start.</param>
        /// <param name="end">Point in world space where the line should end.</param>
        /// <param name="color">Color of the line.</param>
        /// <param name="duration">How long the line should be visible for.</param>
        /// <param name="depthTest">Should the line be obscured by objects closer to the camera?</param>
        public static void DrawLine(Vector3 start, Vector3 end) {
            bool depthTest = true;
            float duration = 0.0f;
            Color white = Color.white;
            Debug.INTERNAL_CALL_DrawLine(ref start, ref end, ref white, duration, depthTest);
        }

        [MethodImpl(MethodImplOptions.InternalCall)]
        private static extern void INTERNAL_CALL_DrawLine(ref Vector3 start, ref Vector3 end, ref Color color, float duration, bool depthTest);

        /// <summary>
        ///   <para>Draws a line from start to start + dir in world coordinates.</para>
        /// </summary>
        /// <param name="start">Point in world space where the ray should start.</param>
        /// <param name="dir">Direction and length of the ray.</param>
        /// <param name="color">Color of the drawn line.</param>
        /// <param name="duration">How long the line will be visible for (in seconds).</param>
        /// <param name="depthTest">Should the line be obscured by other objects closer to the camera?</param>
        public static void DrawRay(Vector3 start, Vector3 dir, Color color, float duration) {
            bool depthTest = true;
            Debug.DrawRay(start, dir, color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line from start to start + dir in world coordinates.</para>
        /// </summary>
        /// <param name="start">Point in world space where the ray should start.</param>
        /// <param name="dir">Direction and length of the ray.</param>
        /// <param name="color">Color of the drawn line.</param>
        /// <param name="duration">How long the line will be visible for (in seconds).</param>
        /// <param name="depthTest">Should the line be obscured by other objects closer to the camera?</param>
        public static void DrawRay(Vector3 start, Vector3 dir, Color color) {
            bool depthTest = true;
            float duration = 0.0f;
            Debug.DrawRay(start, dir, color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line from start to start + dir in world coordinates.</para>
        /// </summary>
        /// <param name="start">Point in world space where the ray should start.</param>
        /// <param name="dir">Direction and length of the ray.</param>
        /// <param name="color">Color of the drawn line.</param>
        /// <param name="duration">How long the line will be visible for (in seconds).</param>
        /// <param name="depthTest">Should the line be obscured by other objects closer to the camera?</param>
        public static void DrawRay(Vector3 start, Vector3 dir) {
            bool depthTest = true;
            float duration = 0.0f;
            Color white = Color.white;
            Debug.DrawRay(start, dir, white, duration, depthTest);
        }

        /// <summary>
        ///   <para>Draws a line from start to start + dir in world coordinates.</para>
        /// </summary>
        /// <param name="start">Point in world space where the ray should start.</param>
        /// <param name="dir">Direction and length of the ray.</param>
        /// <param name="color">Color of the drawn line.</param>
        /// <param name="duration">How long the line will be visible for (in seconds).</param>
        /// <param name="depthTest">Should the line be obscured by other objects closer to the camera?</param>
        public static void DrawRay(Vector3 start, Vector3 dir, [DefaultValue("Color.white")] Color color, [DefaultValue("0.0f")] float duration, [DefaultValue("true")] bool depthTest) {
            Debug.DrawLine(start, start + dir, color, duration, depthTest);
        }

        /// <summary>
        ///   <para>Pauses the editor.</para>
        /// </summary>
        [MethodImpl(MethodImplOptions.InternalCall)]
        public static extern void Break();

        [MethodImpl(MethodImplOptions.InternalCall)]
        public static extern void DebugBreak();

        /// <summary>
        ///   <para>Logs message to the Unity Console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void Log(object message) {
            Debug.unityLogger.Log(LogType.Log, message);
        }

        /// <summary>
        ///   <para>Logs message to the Unity Console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void Log(object message, Object context) {
            Debug.unityLogger.Log(LogType.Log, message, context);
        }

        /// <summary>
        ///   <para>Logs a formatted message to the Unity Console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogFormat(string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Log, format, args);
        }

        /// <summary>
        ///   <para>Logs a formatted message to the Unity Console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogFormat(Object context, string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Log, context, format, args);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an error message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogError(object message) {
            Debug.unityLogger.Log(LogType.Error, message);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an error message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogError(object message, Object context) {
            Debug.unityLogger.Log(LogType.Error, message, context);
        }

        /// <summary>
        ///   <para>Logs a formatted error message to the Unity console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogErrorFormat(string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Error, format, args);
        }

        /// <summary>
        ///   <para>Logs a formatted error message to the Unity console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogErrorFormat(Object context, string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Error, context, format, args);
        }

        /// <summary>
        ///   <para>Clears errors from the developer console.</para>
        /// </summary>
        [MethodImpl(MethodImplOptions.InternalCall)]
        public static extern void ClearDeveloperConsole();

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an error message to the console.</para>
        /// </summary>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="exception">Runtime Exception.</param>
        public static void LogException(Exception exception) {
            Debug.unityLogger.LogException(exception, (Object)null);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an error message to the console.</para>
        /// </summary>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="exception">Runtime Exception.</param>
        public static void LogException(Exception exception, Object context) {
            Debug.unityLogger.LogException(exception, context);
        }

        [MethodImpl(MethodImplOptions.InternalCall)]
        internal static extern void LogPlayerBuildError(string message, string file, int line, int column);

        /// <summary>
        ///   <para>A variant of Debug.Log that logs a warning message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogWarning(object message) {
            Debug.unityLogger.Log(LogType.Warning, message);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs a warning message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogWarning(object message, Object context) {
            Debug.unityLogger.Log(LogType.Warning, message, context);
        }

        /// <summary>
        ///   <para>Logs a formatted warning message to the Unity Console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogWarningFormat(string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Warning, format, args);
        }

        /// <summary>
        ///   <para>Logs a formatted warning message to the Unity Console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        public static void LogWarningFormat(Object context, string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Warning, context, format, args);
        }

        /// <summary>
        ///   <para>Assert a condition and logs an error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, (object)"Assertion failed");
        }

        /// <summary>
        ///   <para>Assert a condition and logs an error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, Object context) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, (object)"Assertion failed", context);
        }

        /// <summary>
        ///   <para>Assert a condition and logs an error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, object message) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, message);
        }

        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, string message) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, (object)message);
        }

        /// <summary>
        ///   <para>Assert a condition and logs an error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="context">Object to which the message applies.</param>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, object message, Object context) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, message, context);
        }

        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, string message, Object context) {
            if (condition)
                return;
            Debug.unityLogger.Log(LogType.Assert, (object)message, context);
        }

        /// <summary>
        ///   <para>Assert a condition and logs a formatted error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void AssertFormat(bool condition, string format, params object[] args) {
            if (condition)
                return;
            Debug.unityLogger.LogFormat(LogType.Assert, format, args);
        }

        /// <summary>
        ///   <para>Assert a condition and logs a formatted error message to the Unity console on failure.</para>
        /// </summary>
        /// <param name="condition">Condition you expect to be true.</param>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void AssertFormat(bool condition, Object context, string format, params object[] args) {
            if (condition)
                return;
            Debug.unityLogger.LogFormat(LogType.Assert, context, format, args);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an assertion message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void LogAssertion(object message) {
            Debug.unityLogger.Log(LogType.Assert, message);
        }

        /// <summary>
        ///   <para>A variant of Debug.Log that logs an assertion message to the console.</para>
        /// </summary>
        /// <param name="message">String or object to be converted to string representation for display.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void LogAssertion(object message, Object context) {
            Debug.unityLogger.Log(LogType.Assert, message, context);
        }

        /// <summary>
        ///   <para>Logs a formatted assertion message to the Unity console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void LogAssertionFormat(string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Assert, format, args);
        }

        /// <summary>
        ///   <para>Logs a formatted assertion message to the Unity console.</para>
        /// </summary>
        /// <param name="format">A composite format string.</param>
        /// <param name="args">Format arguments.</param>
        /// <param name="context">Object to which the message applies.</param>
        [Conditional("UNITY_ASSERTIONS")]
        public static void LogAssertionFormat(Object context, string format, params object[] args) {
            Debug.unityLogger.LogFormat(LogType.Assert, context, format, args);
        }

        //[MethodImpl(MethodImplOptions.InternalCall)]
        //internal static void OpenConsoleFile() {
        //    throw new NotImplementedException();
        //}

        //[MethodImpl(MethodImplOptions.InternalCall)]
        //internal static void GetDiagnosticSwitches(List<DiagnosticSwitch> results) {
        //    throw new NotImplementedException();
        //}

        //[MethodImpl(MethodImplOptions.InternalCall)]
        //internal static void SetDiagnosticSwitch(string name, object value, bool setPersistent);

        [Obsolete("Assert(bool, string, params object[]) is obsolete. Use AssertFormat(bool, string, params object[]) (UnityUpgradable) -> AssertFormat(*)", true)]
        [Conditional("UNITY_ASSERTIONS")]
        public static void Assert(bool condition, string format, params object[] args) {
            if (condition)
                return;
            Debug.unityLogger.LogFormat(LogType.Assert, format, args);
        }
    }
}


text:
#include <aws/common/device_random.h>

#include <aws/common/byte_buf.h>

#include <aws/testing/aws_test_harness.h>

#include <math.h>

/* Number of random numbers to generate and put in buckets. Higher numbers mean more tolerance */
#define DISTRIBUTION_PUT_COUNT 1000000

/* Must be a power of 2. Lower numbers mean more tolerance. */
#define DISTRIBUTION_BUCKET_COUNT 16

/* Fail if a bucket's contents vary from expected by more than this ratio. Higher ratio means more tolerance.
 * For example, if putting 1000 numbers into 10 buckets, we expect 100 in each bucket.
 * If ratio is 0.25 than accept 75 -> 125 numbers per bucket. */
#define DISTRIBUTION_ACCEPTED_DEVIATION_RATIO 0.05

/* For testing that random number generator has a uniform distribution.
 * They're RANDOM numbers, so to avoid RANDOM failures use lots of inputs and be tolerate some deviance */
struct distribution_tester {
    uint64_t max_value;
    uint64_t buckets[DISTRIBUTION_BUCKET_COUNT];
    uint64_t num_puts;
};

static int s_distribution_tester_put(struct distribution_tester *tester, uint64_t rand_num) {
    ASSERT_TRUE(rand_num <= tester->max_value);
    uint64_t bucket_size = (tester->max_value / DISTRIBUTION_BUCKET_COUNT) + 1;
    uint64_t bucket_idx = rand_num / bucket_size;
    ASSERT_TRUE(bucket_idx < DISTRIBUTION_BUCKET_COUNT);
    tester->buckets[bucket_idx]++;
    tester->num_puts++;
    return AWS_OP_SUCCESS;
}

static int s_distribution_tester_check_results(const struct distribution_tester *tester) {
    ASSERT_TRUE(tester->num_puts == DISTRIBUTION_PUT_COUNT);

    double expected_numbers_per_bucket = (double)DISTRIBUTION_PUT_COUNT / DISTRIBUTION_BUCKET_COUNT;

    uint64_t max_acceptable_numbers_per_bucket =
        (uint64_t)ceil(expected_numbers_per_bucket * (1.0 + DISTRIBUTION_ACCEPTED_DEVIATION_RATIO));

    uint64_t min_acceptable_numbers_per_bucket =
        (uint64_t)floor(expected_numbers_per_bucket * (1.0 - DISTRIBUTION_ACCEPTED_DEVIATION_RATIO));

    for (uint64_t i = 0; i < DISTRIBUTION_BUCKET_COUNT; ++i) {
        uint64_t numbers_in_bucket = tester->buckets[i];
        ASSERT_TRUE(numbers_in_bucket <= max_acceptable_numbers_per_bucket);
        ASSERT_TRUE(numbers_in_bucket >= min_acceptable_numbers_per_bucket);
    }

    return AWS_OP_SUCCESS;
}

static int s_device_rand_u64_distribution_fn(struct aws_allocator *allocator, void *ctx) {
    (void)allocator;
    (void)ctx;
    struct distribution_tester tester = {.max_value = UINT64_MAX};

    for (size_t i = 0; i < DISTRIBUTION_PUT_COUNT; ++i) {
        uint64_t next_value = 0;
        ASSERT_SUCCESS(aws_device_random_u64(&next_value));
        ASSERT_SUCCESS(s_distribution_tester_put(&tester, next_value));
    }

    ASSERT_SUCCESS(s_distribution_tester_check_results(&tester));
    return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(device_rand_u64_distribution, s_device_rand_u64_distribution_fn)

static int s_device_rand_u32_distribution_fn(struct aws_allocator *allocator, void *ctx) {
    (void)allocator;
    (void)ctx;
    struct distribution_tester tester = {.max_value = UINT32_MAX};

    for (size_t i = 0; i < DISTRIBUTION_PUT_COUNT; ++i) {
        uint32_t next_value = 0;
        ASSERT_SUCCESS(aws_device_random_u32(&next_value));
        ASSERT_SUCCESS(s_distribution_tester_put(&tester, next_value));
    }

    ASSERT_SUCCESS(s_distribution_tester_check_results(&tester));
    return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(device_rand_u32_distribution, s_device_rand_u32_distribution_fn)

static int s_device_rand_u16_distribution_fn(struct aws_allocator *allocator, void *ctx) {
    (void)allocator;
    (void)ctx;
    struct distribution_tester tester = {.max_value = UINT16_MAX};

    for (size_t i = 0; i < DISTRIBUTION_PUT_COUNT; ++i) {
        uint16_t next_value = 0;
        ASSERT_SUCCESS(aws_device_random_u16(&next_value));
        ASSERT_SUCCESS(s_distribution_tester_put(&tester, next_value));
    }

    ASSERT_SUCCESS(s_distribution_tester_check_results(&tester));
    return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(device_rand_u16_distribution, s_device_rand_u16_distribution_fn)

static int s_device_rand_buffer_distribution_fn(struct aws_allocator *allocator, void *ctx) {
    (void)allocator;
    (void)ctx;

    uint8_t array[DISTRIBUTION_PUT_COUNT] = {0};
    struct aws_byte_buf buf = aws_byte_buf_from_empty_array(array, sizeof(array));
    ASSERT_SUCCESS(aws_device_random_buffer(&buf));

    /* Test each byte in the buffer */
    struct distribution_tester tester = {.max_value = UINT8_MAX};

    for (size_t i = 0; i < DISTRIBUTION_PUT_COUNT; ++i) {
        ASSERT_SUCCESS(s_distribution_tester_put(&tester, array[i]));
    }

    ASSERT_SUCCESS(s_distribution_tester_check_results(&tester));
    return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(device_rand_buffer_distribution, s_device_rand_buffer_distribution_fn)


text:
package org.fseek.simon.swing.filetable.ui;

import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import org.fseek.thedeath.os.util.OSUtil;

public class FileTableHeaderCellRenderer extends DefaultTableCellRenderer
{
    private final TableCellRenderer delegateRenderer;

    public FileTableHeaderCellRenderer(TableCellRenderer delegateRenderer)
    {
        if(delegateRenderer instanceof JLabel == false){
            throw new IllegalArgumentException("Only JLabels are allowed as delegate renderers");
        }
        this.delegateRenderer = delegateRenderer;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column)
    {
        JLabel label = (JLabel)delegateRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        label.setHorizontalAlignment(SwingConstants.LEFT);
        // durchsichtig
        label.setOpaque(false);
        Font font = OSUtil.getOSAppearance().getFont();
        if(font != null)
        {
            label.setFont(font);
        }
        label.setForeground(OSUtil.getOSAppearance().getLightFontColor());
        return label;
    }
}


text:
/* Addon: Custom Snoo */
#header-img.default-header, #header-img {
    background: url(%%snoo%%) no-repeat 0px 0px;
}

    #header-img.default-header:hover, #header-img:hover {
        background-position: 0px 0px;
    }
/* End Addon */


text:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using System.Collections.ObjectModel;
using System.Linq;
using System.Globalization;
using Microsoft.VisualStudio.Debugger.Interop;

namespace MICore
{
    internal class ClrdbgMICommandFactory : MICommandFactory
    {
        private readonly static Guid s_exceptionCategory_CLR = new Guid("449EC4CC-30D2-4032-9256-EE18EB41B62B");
        private readonly static Guid s_exceptionCategory_MDA = new Guid("6ECE07A9-0EDE-45C4-8296-818D8FC401D4");
        private readonly static ReadOnlyCollection<Guid> s_exceptionCategories = new ReadOnlyCollection<Guid>(new Guid[] { s_exceptionCategory_CLR, s_exceptionCategory_MDA });

        public override string Name
        {
            get { return "CLRDBG"; }
        }

        public override bool SupportsStopOnDynamicLibLoad()
        {
            return false;
        }

        // CLRDBG supports frame formatting itself
        override public bool SupportsFrameFormatting
        {
            get { return true; }
        }

        public override bool AllowCommandsWhileRunning()
        {
            return true;
        }

        public override async Task<bool> SetJustMyCode(bool enabled)
        {
            string command = "-gdb-set just-my-code " + (enabled ? "1" : "0");
            Results results = await _debugger.CmdAsync(command, ResultClass.None);
            return results.ResultClass == ResultClass.done;
        }

        public override Task<TupleValue[]> StackListArguments(PrintValues printValues, int threadId, uint lowFrameLevel, uint hiFrameLevel)
        {
            // CLRDBG supports stack frame formatting, so this should not be used
            throw new NotImplementedException();
        }

        protected override async Task<Results> ThreadFrameCmdAsync(string command, ResultClass expectedResultClass, int threadId, uint frameLevel)
        {
            string threadFrameCommand = string.Format(@"{0} --thread {1} --frame {2}", command, threadId, frameLevel);

            return await _debugger.CmdAsync(threadFrameCommand, expectedResultClass);
        }

        protected override async Task<Results> ThreadCmdAsync(string command, ResultClass expectedResultClass, int threadId)
        {
            string threadCommand = string.Format(@"{0} --thread {1}", command, threadId);

            return await _debugger.CmdAsync(threadCommand, expectedResultClass);
        }
        public override Task<List<ulong>> StartAddressesForLine(string file, uint line)
        {
            return Task.FromResult<List<ulong>>(null);
        }

        public override Task EnableTargetAsyncOption()
        {
            // clrdbg is always in target-async mode
            return Task.FromResult((object)null);
        }

        public override IEnumerable<Guid> GetSupportedExceptionCategories()
        {
            return s_exceptionCategories;
        }

        public override async Task<IEnumerable<ulong>> SetExceptionBreakpoints(Guid exceptionCategory, /*OPTIONAL*/ IEnumerable<string> exceptionNames, ExceptionBreakpointState exceptionBreakpointState)
        {
            List<string> commandTokens = new List<string>();
            commandTokens.Add("-break-exception-insert");

            if (exceptionCategory == s_exceptionCategory_MDA)
            {
                commandTokens.Add("--mda");
            }
            else if (exceptionCategory != s_exceptionCategory_CLR)
            {
                throw new ArgumentOutOfRangeException("exceptionCategory");
            }

            if (exceptionBreakpointState.HasFlag(ExceptionBreakpointState.BreakThrown))
            {
                if (exceptionBreakpointState.HasFlag(ExceptionBreakpointState.BreakUserHandled))
                    commandTokens.Add("throw+user-unhandled");
                else
                    commandTokens.Add("throw");
            }
            else
            {
                if (exceptionBreakpointState.HasFlag(ExceptionBreakpointState.BreakUserHandled))
                    commandTokens.Add("user-unhandled");
                else
                    commandTokens.Add("unhandled");
            }

            if (exceptionNames == null)
                commandTokens.Add("*");
            else
                commandTokens.AddRange(exceptionNames);

            string command = string.Join(" ", commandTokens);

            Results results = await _debugger.CmdAsync(command, ResultClass.done);
            ResultValue bkpt;
            if (results.TryFind("bkpt", out bkpt))
            {
                if (bkpt is ValueListValue)
                {
                    MICore.ValueListValue list = bkpt as MICore.ValueListValue;
                    return list.Content.Select((x) => x.FindAddr("number"));
                }
                else
                {
                    return new ulong[1] { bkpt.FindAddr("number") };
                }
            }
            else
            {
                return new ulong[0];
            }
        }

        public override Task RemoveExceptionBreakpoint(Guid exceptionCategory, IEnumerable<ulong> exceptionBreakpointIds)
        {
            string breakpointIds = string.Join(" ", exceptionBreakpointIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));

            string command = "-break-exception-delete " + breakpointIds;
            return _debugger.CmdAsync(command, ResultClass.done);
        }

        public override void DecodeExceptionReceivedProperties(Results miExceptionResult, out Guid? exceptionCategory, out ExceptionBreakpointState state)
        {
            string category = miExceptionResult.FindString("exception-category");
            if (category == "mda")
            {
                exceptionCategory = s_exceptionCategory_MDA;
            }
            else
            {
                Debug.Assert(category == "clr");
                exceptionCategory = s_exceptionCategory_CLR;
            }

            string stage = miExceptionResult.FindString("exception-stage");
            switch (stage)
            {
                case "throw":
                    state = ExceptionBreakpointState.BreakThrown;
                    break;

                case "user-unhandled":
                    state = ExceptionBreakpointState.BreakUserHandled;
                    break;

                case "unhandled":
                    state = ExceptionBreakpointState.None;
                    break;

                default:
                    Debug.Fail("Unknown exception-stage value");
                    state = ExceptionBreakpointState.None;
                    break;
            }
        }

        override public async Task Terminate()
        {
            string command = "-exec-abort";
            await _debugger.CmdAsync(command, ResultClass.done);
        }

        public override async Task<Results> VarCreate(string expression, int threadId, uint frameLevel, enum_EVALFLAGS dwFlags, ResultClass resultClass = ResultClass.done)
        {
            string command = string.Format("-var-create - * \"{0}\" --evalFlags {1}", expression, (uint)dwFlags);
            Results results = await ThreadFrameCmdAsync(command, resultClass, threadId, frameLevel);

            return results;
        }

        public override async Task<Results> VarListChildren(string variableReference, enum_DEBUGPROP_INFO_FLAGS dwFlags, ResultClass resultClass = ResultClass.done)
        {
            // Limit the number of children expanded to 1000 in case memory is uninitialized
            string command = string.Format("-var-list-children --simple-values \"{0}\" --propertyInfoFlags {1} 0 1000", variableReference, (uint)dwFlags);
            Results results = await _debugger.CmdAsync(command, resultClass);

            return results;
        }
    }
}


text:
layout: post
date:	2010-05-25 18:48:00
title:  One Vegetable Ive not taken to...
tags: [archived-posts]
categories: archives
permalink: /:categories/:year/:month/:day/:title/
---
I've never eaten

 Artichokes

before, so when D bought some, I wanted to try them out. He cooked them in the pressure cooker and we had them with some sour cream sauce.

I must say, the vegetable looks aesthetically so pleasing...it's like a green lotus! But as I was taught how to eat it...pull off the leaves one by one, eat the lower, fleshy parts, setting them aside, and then finally coming to the heart set in a thicket of spines...I was far less enchanted.

I feel eating an artichoke is a lot of work to get very little of actual stuff to eat, and those spines could get into your gum, too....

Reminds me of the

 Custard Apple  or Seetaphal, which, to me, also represents a lot of work to get at a little bit of snot-like substance that I don't like the taste of, anyway!

If someone reading this does like artichokes or custard apples...tell me how you eat them!


text:
'use strict';

define(

  [
    'flight/lib/component',
    'components/mustache/mustache',
    'app/data',
    'app/templates'
  ],

  function(defineComponent, Mustache, dataStore, templates) {
    return defineComponent(composeBox);

    function composeBox() {

      this.defaultAttrs({
        dataStore: dataStore,
        recipientHintId: 'recipient_hint',
        subjectHint: 'Subject',
        messageHint: 'Message',
        toHint: 'To',
        forwardPrefix: 'Fw',
        replyPrefix: 'Re'
      });

      this.serveComposeBox = function(ev, data) {
        this.trigger("dataComposeBoxServed", {
          markup: this.renderComposeBox(data.type, data.relatedMailId),
          type: data.type});
      };

      this.getSubject = function(type, relatedMailId) {
        var relatedMail = this.attr.dataStore.mail.filter(function(each) {
          return each.id ==  relatedMailId;
        })[0];

        var subject = relatedMail && relatedMail.subject;

        var subjectLookup = {
          newMail: this.attr.subjectHint,
          forward: this.attr.forwardPrefix + ": " + subject,
          reply: this.attr.replyPrefix + ": " + subject
        }

        return subjectLookup[type];
      };

      this.renderComposeBox = function(type, relatedMailId) {
        var recipientId = this.getRecipientId(type, relatedMailId);
        var contacts = this.attr.dataStore.contacts.map(function(contact) {
          contact.recipient = (contact.id == recipientId);
          return contact;
        });

        return Mustache.render(templates.composeBox, {
          newMail: type == 'newMail',
          reply: type == 'reply',
          subject: this.getSubject(type, relatedMailId),
          message: this.attr.messageHint,
          contacts: contacts
        });
      };

      this.getRecipientId = function(type, relatedMailId) {
        var relatedMail = (type == 'reply') && this.attr.dataStore.mail.filter(function(each) {
          return each.id ==  relatedMailId;
        })[0];

        return relatedMail && relatedMail.contact_id || this.attr.recipientHintId;
      };

      this.send = function(ev, data) {
        this.attr.dataStore.mail.push({
          id: String(Date.now()),
          contact_id: data.to_id,
          folders: ["sent"],
          time: Date.now(),
          subject: data.subject,
          message: data.message
        });
        this.trigger('dataMailItemsRefreshRequested', {folder: data.currentFolder});
      };

      this.after("initialize", function() {
        this.on("uiComposeBoxRequested", this.serveComposeBox);
        this.on("uiSendRequested", this.send);
      });
    }

  }
);


text:
import doctest

import silk
doctest.testmod(silk)

import silk.webdoc
doctest.testmod(silk.webdoc)
doctest.testmod(silk.webdoc.node)
doctest.testmod(silk.webdoc.css)
doctest.testmod(silk.webdoc.html)
doctest.testmod(silk.webdoc.html.common)
import silk.webdoc.stencil
doctest.testmod(silk.webdoc.stencil)
import silk.webdoc.html.v4
import silk.webdoc.html.v5
doctest.testmod(silk.webdoc.html.v4)
doctest.testmod(silk.webdoc.html.v5)

import silk.webreq
doctest.testmod(silk.webreq)

import silk.webdb
doctest.testmod(silk.webdb)
doctest.testmod(silk.webdb.drivers)
doctest.testmod(silk.webdb.drivers.base)


text:
namespace Dusk {

enum class FrontFace
{
    Clockwise,
    CounterClockwise,

}; // enum class FrontFace

enum class CullMode
{
    None,
    Front,
    Back,

}; // enum class CullMode

enum class FillMode
{
    Fill,
    Line,

}; // enum class FillMode

enum class DepthBiasMode
{
    Clamp,
    Clip,

}; // enum class DepthBiasMode

enum class BlendOperation
{
    Add,
    Subtract,
    ReverseSubtract,
    Min,
    Max,

}; // enum class BlendOperation

enum class BlendFactor
{
    Zero,
    One,
    SrcColor,
    OneMinusSrcColor,
    SrcAlpha,
    OneMinusSrcAlpha,
    DstColor,
    OneMinusDstColor,
    DstAlpha,
    OneMinusDstAlpha,
    ConstantColor,
    OneMinusConstantColor,
    ConstantAlpha,
    OneMinusConstantAlpha,
    SrcAlphaSaturated, // TODO: Investigate

}; // enum class BlendFactor

enum class CompareOperation
{
    Never,
    Less,
    LessOrEqual,
    Greater,
    GreaterOrEqual,
    Equal,
    NotEqual,
    Always,

}; // enum class CompareOperation

class DUSK_CORE_API Pipeline : public Object
{
public:

    DISALLOW_COPY_AND_ASSIGN(Pipeline)

    Pipeline() = default;

    virtual ~Pipeline() = default;

    inline virtual bool Initialize(std::shared_ptr<Shader> shader) {
        _shader = shader;
        return true;
    }

    inline virtual void Terminate() {
        _shader.reset();
    }

    inline void SetShader(std::shared_ptr<Shader> shader) {
        _shader = shader;
        // Reset?
    }

    inline void SetPrimitiveTopology(PrimitiveTopology primitiveTopology) {
        _primitiveTopology = primitiveTopology;
    }

    inline void SetFrontFace(FrontFace frontFace) {
        _frontFace = frontFace;
    }

    inline void SetCullMode(CullMode mode) {
        _cullMode = mode;
    }

    inline void SetFillMode(FillMode mode) {
        _fillMode = mode;
    }

    inline void SetDepthBiasFactor(float factor) {
        _depthBiasFactor = factor;
    }

    inline void SetDepthBiasSlopeFactor(float factor) {
        _depthBiasSlopeFactor = factor;
    }

    inline void SetDepthBiasClamp(float clamp) {
        _depthBiasClamp = clamp;
    }

    inline void SetDepthBiasMode(DepthBiasMode mode) {
        _depthBiasMode = mode;
    }

    inline void SetDepthCompareOperation(CompareOperation op) {
        _depthCompareOperation = op;
    }

protected:

    std::shared_ptr<Shader> _shader = nullptr;

    PrimitiveTopology _primitiveTopology = PrimitiveTopology::TriangleList;

    FrontFace _frontFace = FrontFace::CounterClockwise;

    CullMode _cullMode = CullMode::None;

    FillMode _fillMode = FillMode::Fill;

    float _depthBiasFactor = 0.0f;

    float _depthBiasSlopeFactor = 0.0f;

    float _depthBiasClamp = 0.0f;

    DepthBiasMode _depthBiasMode = DepthBiasMode::Clip;

    CompareOperation _depthCompareOperation = CompareOperation::Less;

    bool _blendEnabled = false;

    BlendOperation _colorBlendOp = BlendOperation::Add;

    BlendOperation _alphaBlendOp = BlendOperation::Add;

    BlendFactor _srcColorFactor = BlendFactor::One;

    BlendFactor _dstColorFactor = BlendFactor::One;

    BlendFactor _srcAlphaFactor = BlendFactor::One;

    BlendFactor _dstAlphaFactor = BlendFactor::One;

}; // class Pipeline

inline string FrontFaceToString(FrontFace frontFace)
{
    switch (frontFace) {
    case FrontFace::Clockwise:
        return "Clockwise";
    case FrontFace::CounterClockwise:
        return "CounterClockwise";
    }

    return "Unknown";
}

inline string CullModeToString(CullMode cullMode)
{
    switch (cullMode) {
    case CullMode::None:
        return "None";
    case CullMode::Front:
        return "Front";
    case CullMode::Back:
        return "Back";
    }

    return "Unknown";
}

inline string CullModeToString(FillMode fillMode)
{
    switch (fillMode) {
    case FillMode::Fill:
        return "Fill";
    case FillMode::Line:
        return "Line";
    }

    return "Unknown";
}

inline string DepthBiasModeToString(DepthBiasMode depthBiasMode)
{
    switch (depthBiasMode) {
    case DepthBiasMode::Clamp:
        return "Clamp";
    case DepthBiasMode::Clip:
        return "Clip";
    }

    return "Unknown";
}

inline string BlendOperationToString(BlendOperation blendOperation)
{
    switch (blendOperation) {
    case BlendOperation::Add:
        return "Add";
    case BlendOperation::Subtract:
        return "Subtract";
    case BlendOperation::ReverseSubtract:
        return "ReverseSubtract";
    case BlendOperation::Min:
        return "Min";
    case BlendOperation::Max:
        return "Max";
    }

    return "Unknown";
}

inline string BlendFactorToString(BlendFactor blendFactor)
{
    switch (blendFactor) {
        case BlendFactor::Zero:
            return "Zero";
        case BlendFactor::One:
            return "One";
        case BlendFactor::SrcColor:
            return "SrcColor";
        case BlendFactor::OneMinusSrcColor:
            return "OneMinusSrcColor";
        case BlendFactor::SrcAlpha:
            return "SrcAlpha";
        case BlendFactor::OneMinusSrcAlpha:
            return "OneMinusSrcAlpha";
        case BlendFactor::DstColor:
            return "DstColor";
        case BlendFactor::OneMinusDstColor:
            return "OneMinusDstColor";
        case BlendFactor::DstAlpha:
            return "DstAlpha";
        case BlendFactor::OneMinusDstAlpha:
            return "OneMinusDstAlpha";
        case BlendFactor::ConstantColor:
            return "ConstantColor";
        case BlendFactor::OneMinusConstantColor:
            return "OneMinusConstantColor";
        case BlendFactor::ConstantAlpha:
            return "ConstantAlpha";
        case BlendFactor::OneMinusConstantAlpha:
            return "OneMinusConstantAlpha";
        case BlendFactor::SrcAlphaSaturated:
            return "SrcAlphaSaturated";
    }

    return "Unknown";
}

inline string CompareOperationToString(CompareOperation compareOperation)
{
    switch (compareOperation) {
        case CompareOperation::Never:
            return "Never";
        case CompareOperation::Less:
            return "Less";
        case CompareOperation::LessOrEqual:
            return "LessOrEqual";
        case CompareOperation::Greater:
            return "Greater";
        case CompareOperation::GreaterOrEqual:
            return "GreaterOrEqual";
        case CompareOperation::Equal:
            return "Equal";
        case CompareOperation::NotEqual:
            return "NotEqual";
        case CompareOperation::Always:
            return "Always";
    }

    return "Unknown";
}

} // namespace Dusk

#endif // DUSK_PIPELINE_HPP


text:
workspace-mechanic-preferences
==============================

My take on Eclipse preferences using Workspace Mechanic plugin

* all_tasks.json - for those who prefer to use url in configuration
* close_old_open_editors.epf - keep maximum of 15 editors. There is really no need for more.
* do_not_activate_plugins_on_startup.epf - This improves startup time and does not load plugins and modules you might not even use. These additions will be loaded anyway when you first open a related editor or view.
* guess_method_arguments.epf - Instructs Eclipse to well, guess method arguments.
* replace_on_autocompletion.epf - I like it. You can always hold down ctrl to insert but I usually need to replace.
* save_actions.epf - no code should be saved without formatting. And if you have portions of code you don't want to format then those should be annotated with //formatting@off See formatting options
* smart_semicolon_braces.epf - I have no idea why these are not enabled by default
* spaces_for_tabs_in_xml.epf - I just don't like tabs
* type_filters.epf - I don't need everything Java has to offer so I filter out some things
* use_utf8_encoding.epf - Use UTF-8 for workspace default, properties, jsp, css, html, xml