示例#1
0
        unsafe void Allocate <TBodyReferenceGetter>(int constraintHandle, ref int constraintBodyHandles, int bodyCount, Bodies bodies,
                                                    int typeId, BufferPool pool, TBodyReferenceGetter bodyReferenceGetter, int minimumBodyCapacity, int minimumReferenceCapacity)
            where TBodyReferenceGetter : struct, IBodyReferenceGetter
        {
            var fallbackPool          = pool.SpecializeFor <FallbackReference>();
            var intPool               = pool.SpecializeFor <int>();
            var minimumReferencePower = SpanHelper.GetContainingPowerOf2(minimumReferenceCapacity);

            EnsureCapacity(Math.Max(bodyConstraintReferences.Count + bodyCount, minimumBodyCapacity), pool);
            for (int i = 0; i < bodyCount; ++i)
            {
                var bodyReference = bodyReferenceGetter.GetBodyReference(bodies, Unsafe.Add(ref constraintBodyHandles, i));

                var bodyAlreadyListed = bodyConstraintReferences.GetTableIndices(ref bodyReference, out var tableIndex, out var elementIndex);
                //If an entry for this body does not yet exist, we'll create one.
                if (!bodyAlreadyListed)
                {
                    elementIndex = bodyConstraintReferences.Count;
                }
                ref var constraintReferences = ref bodyConstraintReferences.Values[elementIndex];

                if (!bodyAlreadyListed)
                {
                    //The body is not already contained. Create a list for it.
                    QuickSet <FallbackReference, Buffer <FallbackReference>, Buffer <int>, FallbackReferenceComparer> .Create(fallbackPool, intPool, minimumReferencePower, 2, out constraintReferences);

                    bodyConstraintReferences.Keys[elementIndex] = bodyReference;
                    bodyConstraintReferences.Table[tableIndex]  = elementIndex + 1;
                    ++bodyConstraintReferences.Count;
                }
                var fallbackReference = new FallbackReference {
                    ConstraintHandle = constraintHandle, IndexInConstraint = i
                };
                constraintReferences.Add(ref fallbackReference, fallbackPool, intPool);
            }
示例#2
0
 protected override void ValidateRemoval(int index)
 {
     Debug.Assert(!SpanHelper.IsZeroed(ref shapes[index]),
                  "Either a shape was default constructed (which is almost certainly invalid), or this is attempting to remove a shape that was already removed.");
     //Don't have to actually clear out the shape set since everything is blittable. For debug purposes, we do, just to catch invalid usages.
     shapes[index] = default;
 }
示例#3
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Rectangle sourceRectangle, Configuration configuration)
        {
            // Handle resize dimensions identical to the original
            if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.CropRectangle)
            {
                // the cloned will be blank here copy all the pixel data over
                source.GetPixelSpan().CopyTo(destination.GetPixelSpan());
                return;
            }

            int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
            int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
            int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);

            Parallel.For(
                minY,
                maxY,
                configuration.ParallelOptions,
                y =>
            {
                Span <TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(minX);
                Span <TPixel> targetRow = destination.GetPixelRowSpan(y - minY);
                SpanHelper.Copy(sourceRow, targetRow, maxX - minX);
            });
        }
示例#4
0
 public void Resize <TKeyPool, TValuePool, TTablePool>(int newSize, TKeyPool keyPool, TValuePool valuePool, TTablePool tablePool)
     where TKeyPool : IMemoryPool <TKey, TKeySpan>
     where TValuePool : IMemoryPool <TValue, TValueSpan>
     where TTablePool : IMemoryPool <int, TTableSpan>
 {
     ResizeForPower(SpanHelper.GetContainingPowerOf2(newSize), keyPool, valuePool, tablePool);
 }
示例#5
0
        public override void OnStopActivity(Activity activity, object payload)
        {
            if (activity.IsAllDataRequested)
            {
                var requestTaskStatus = this.stopRequestStatusFetcher.Fetch(payload) as TaskStatus?;

                if (requestTaskStatus.HasValue)
                {
                    if (requestTaskStatus != TaskStatus.RanToCompletion)
                    {
                        if (requestTaskStatus == TaskStatus.Canceled)
                        {
                            Status status = Status.Cancelled;
                            activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                        }
                        else if (requestTaskStatus != TaskStatus.Faulted)
                        {
                            // Faults are handled in OnException and should already have a span.Status of Unknown w/ Description.
                            Status status = Status.Unknown;
                            activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                        }
                    }
                }

                if (this.stopResponseFetcher.Fetch(payload) is HttpResponseMessage response)
                {
                    // response could be null for DNS issues, timeouts, etc...
                    activity.AddTag(SpanAttributeConstants.HttpStatusCodeKey, response.StatusCode.ToString());

                    Status status = SpanHelper.ResolveSpanStatusForHttpStatusCode((int)response.StatusCode);
                    activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                    activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, response.ReasonPhrase);
                }
            }
        }
示例#6
0
        /// <inheritdoc/>
        protected override void OnApply(ImageBase <TPixel> source, Rectangle sourceRectangle)
        {
            if (this.CropRectangle == sourceRectangle)
            {
                return;
            }

            int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
            int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
            int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);

            using (var targetPixels = new PixelAccessor <TPixel>(this.CropRectangle.Width, this.CropRectangle.Height))
            {
                Parallel.For(
                    minY,
                    maxY,
                    this.ParallelOptions,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetRowSpan(minX, y);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y - minY);
                    SpanHelper.Copy(sourceRow, targetRow, maxX - minX);
                });

                source.SwapPixelsBuffers(targetPixels);
            }
        }
示例#7
0
        /// <inheritdoc/>
        protected override void OnApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            if (this.CropRectangle == sourceRectangle)
            {
                return;
            }

            int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
            int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
            int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryManager.Allocate2D <TPixel>(this.CropRectangle.Size))
            {
                Parallel.For(
                    minY,
                    maxY,
                    configuration.ParallelOptions,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(minX);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y - minY);
                    SpanHelper.Copy(sourceRow, targetRow, maxX - minX);
                });

                Buffer2D <TPixel> .SwapContents(source.PixelBuffer, targetPixels);
            }
        }
示例#8
0
        public unsafe bool Allocate(ulong id, int vertexCount, out int start, out Buffer <Vector3> vertices)
        {
            if (allocator.TryGetAllocationRegion(id, out var allocation))
            {
                Debug.Assert(allocation.End - allocation.Start == vertexCount,
                             "If you're trying to allocate room for a bunch of triangles and we found it already, it better match the expected size.");
                start    = (int)allocation.Start;
                vertices = this.vertices.Slice(start, vertexCount);
                return(false);
            }
            if (allocator.Allocate(id, vertexCount, out var longStart))
            {
                start    = (int)longStart;
                vertices = this.vertices.Slice(start, vertexCount);
                pendingUploads.Add(new UploadRequest {
                    Start = start, Count = vertexCount
                }, Pool.SpecializeFor <UploadRequest>());
                return(true);
            }
            //Didn't fit. We need to resize.
            var copyCount = TriangleBuffer.Capacity + vertexCount;
            var newSize   = SpanHelper.GetContainingPowerOf2(copyCount);

            Pool.Resize(ref this.vertices, newSize, copyCount);
            allocator.Capacity = newSize;
            allocator.Allocate(id, vertexCount, out longStart);
            start    = (int)longStart;
            vertices = this.vertices.Slice(start, vertexCount);
            //A resize forces an upload of everything, so any previous pending uploads are unnecessary.
            pendingUploads.Count = 0;
            pendingUploads.Add(new UploadRequest {
                Start = 0, Count = copyCount
            }, Pool.SpecializeFor <UploadRequest>());
            return(true);
        }
        public override void OnException(Activity activity, object payload)
        {
            if (activity.IsAllDataRequested)
            {
                if (!(this.stopExceptionFetcher.Fetch(payload) is Exception exc))
                {
                    InstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnException));
                    return;
                }

                if (exc is HttpRequestException)
                {
                    if (exc.InnerException is SocketException exception)
                    {
                        switch (exception.SocketErrorCode)
                        {
                        case SocketError.HostNotFound:
                            Status status = Status.InvalidArgument;
                            activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                            activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, exc.Message);
                            return;
                        }
                    }

                    if (exc.InnerException != null)
                    {
                        Status status = Status.Unknown;
                        activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                        activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, exc.Message);
                    }
                }
            }
        }
示例#10
0
 public static void Encode(Span <byte> scanline, Span <byte> result)
 {
     // Insert a byte before the data.
     result[0] = 0;
     result    = result.Slice(1);
     SpanHelper.Copy(scanline, result);
 }
示例#11
0
        public override void OnException(Activity activity, object valueValue)
        {
            Status status = Status.Unknown;

            activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
            activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, valueValue?.ToString());
        }
示例#12
0
        private static void VerifyActivityData(Activity activity, bool isSet, EndPoint endPoint)
        {
            if (isSet)
            {
                Assert.Equal("SETEX", activity.DisplayName);
                Assert.Equal("SETEX", activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeDbStatement).Value);
            }
            else
            {
                Assert.Equal("GET", activity.DisplayName);
                Assert.Equal("GET", activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeDbStatement).Value);
            }

            Assert.Equal(SpanHelper.GetCachedCanonicalCodeString(StatusCanonicalCode.Ok), activity.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.StatusCodeKey).Value);
            Assert.Equal("redis", activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeDbSystem).Value);
            Assert.Equal("0", activity.Tags.FirstOrDefault(t => t.Key == StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName).Value);

            if (endPoint is IPEndPoint ipEndPoint)
            {
                Assert.Equal(ipEndPoint.Address.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeNetPeerIp).Value);
                Assert.Equal(ipEndPoint.Port.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeNetPeerPort).Value);
            }
            else if (endPoint is DnsEndPoint dnsEndPoint)
            {
                Assert.Equal(dnsEndPoint.Host, activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeNetPeerName).Value);
                Assert.Equal(dnsEndPoint.Port.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeNetPeerPort).Value);
            }
            else
            {
                Assert.Equal(endPoint.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributePeerService).Value);
            }
        }
            /// <inheritdoc />
            internal override unsafe void ToVector4(Span <RgbaVector> sourceColors, Span <Vector4> destVectors, int count)
            {
                Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
                Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors));

                SpanHelper.Copy(sourceColors.AsBytes(), destVectors.AsBytes(), count * sizeof(Vector4));
            }
示例#14
0
        public unsafe bool Allocate(ulong id, int vertexCount, out int start, out Buffer <Vector3> vertices)
        {
            if (TryGetExistingMesh(id, out start, out vertices))
            {
                return(false);
            }
            if (allocator.Allocate(id, vertexCount, out var longStart))
            {
                start    = (int)longStart;
                vertices = this.vertices.Slice(start, vertexCount);
                pendingUploads.Add(new UploadRequest {
                    Start = start, Count = vertexCount
                }, Pool);
                return(true);
            }
            //Didn't fit. We need to resize.
            var copyCount = TriangleBuffer.Capacity + vertexCount;
            var newSize   = 1 << SpanHelper.GetContainingPowerOf2(copyCount);

            Pool.ResizeToAtLeast(ref this.vertices, newSize, copyCount);
            allocator.Capacity = newSize;
            allocator.Allocate(id, vertexCount, out longStart);
            start    = (int)longStart;
            vertices = this.vertices.Slice(start, vertexCount);
            //A resize forces an upload of everything, so any previous pending uploads are unnecessary.
            pendingUploads.Count = 0;
            pendingUploads.Add(new UploadRequest {
                Start = 0, Count = copyCount
            }, Pool);
            return(true);
        }
示例#15
0
        private static void DoWork(IDatabase db, ActivitySource activitySource)
        {
            // Start another activity. If another activity was already started, it'll use that activity as the parent activity.
            // In this example, the main method already started a activity, so that'll be the parent activity, and this will be
            // a child activity.
            using (Activity activity = activitySource.StartActivity("DoWork"))
            {
                try
                {
                    db.StringSet("key", "value " + DateTime.Now.ToLongDateString());

                    System.Console.WriteLine("Doing busy work");
                    Thread.Sleep(1000);

                    // run a command, in this case a GET
                    var myVal = db.StringGet("key");

                    System.Console.WriteLine(myVal);
                }
                catch (ArgumentOutOfRangeException e)
                {
                    // Set status upon error
                    activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(Status.Internal.CanonicalCode));
                    activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, e.ToString());
                }

                // Annotate our activity to capture metadata about our operation
                var attributes = new Dictionary <string, object>
                {
                    { "use", "demo" },
                };
                activity.AddEvent(new ActivityEvent("Invoking DoWork", attributes));
            }
        }
示例#16
0
        public void LoadFromFile(string filePath, FileStream fileStream)
        {
            FilePath    = filePath;
            FileName    = Path.GetFileNameWithoutExtension(FilePath);
            FilePointer = 0;

            // Get file size
            RealFileSize    = fileStream.Length;
            VirtualFileSize = RealFileSize;

            // Read header to determine where the data starts & so we can read all of the headers
            DwPackHeader header = new DwPackHeader();

            fileStream.Read(SpanHelper.AsSpan <DwPackHeader, byte>(ref header));

            // Read the rest of the header data
            var length = sizeof(DwPackHeader) + (sizeof(DwPackEntry) * header.FileCount);
            var buffer = (byte *)Marshal.AllocHGlobal(length);

            fileStream.Seek(0, SeekOrigin.Begin);
            fileStream.Read(new Span <byte>(buffer, length));
            Native = new DwPackPtr(buffer);

            for (int i = 0; i < Native.Header->FileCount; i++)
            {
                var entry = new VirtualDwPackEntry(mLogger, this, Native.Entries + i, i);
                Entries.Add(entry);
                mMapper.Map(DataBaseOffset + entry.Native->DataOffset, entry.Native->CompressedSize, true);
            }
        }
示例#17
0
        void Add(char character)
        {
            if (characters.Length == count)
                Array.Resize(ref characters, SpanHelper.GetContainingPowerOf2(count * 2));
            characters[count++] = character;

        }
示例#18
0
    public static int GetRowStartBytes(int rowIndex, Span <byte> bytes)
    {
        var bytesWritten = SpanHelper.GetBytes(RowStart, bytes);

        bytesWritten += Utf8Helper.GetBytes(rowIndex, bytes.Slice(bytesWritten));
        bytesWritten += SpanHelper.GetBytes(RowStartEndTag, bytes.Slice(bytesWritten));
        return(bytesWritten);
    }
示例#19
0
 private static ReadOnlyMemory <char> Decode(ReadOnlyMemory <char> chars)
 {
     // If the value is short, it's cheap to check up front if it really needs decoding. If it doesn't,
     // then we can save some allocations.
     return(chars.Length < 16 && chars.Span.IndexOfAny('%', '+') < 0
         ? chars
         : Uri.UnescapeDataString(SpanHelper.ReplacePlusWithSpace(chars.Span)).AsMemory());
 }
        public SimulationProfiler(int initialStageCount = 8)
        {
            QuickDictionary <object, double, Array <object>, Array <double>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, doublePool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out stages);

            QuickDictionary <object, long, Array <object>, Array <long>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, longPool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out startTimeStamps);
        }
示例#21
0
        /// <summary>
        /// Helper method that populates span properties from http status code according
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="statusCode">Http status code.</param>
        /// <param name="reasonPhrase">Http reason phrase.</param>
        /// <returns>Span with populated properties.</returns>
        public static TelemetrySpan PutHttpStatusCode(this TelemetrySpan span, int statusCode, string reasonPhrase)
        {
            span.PutHttpStatusCodeAttribute(statusCode);

            span.Status = SpanHelper.ResolveSpanStatusForHttpStatusCode(statusCode).WithDescription(reasonPhrase);

            return(span);
        }
        public void Translate_TemplateBuilder_Write_IsNeverCalled()
        {
            ITemplateBuilder templateBuilder = new FailingTemplateBuilder();

            var sut = new IgnoreSpanTranslator();

            sut.Translate(SpanHelper.BuildSpan("a"), templateBuilder);
        }
示例#23
0
    private static int GetSheetElementBytes(string path, Span <byte> bytes)
    {
        var bytesWritten = SpanHelper.GetBytes(SheetStart, bytes);

        bytesWritten += Utf8Helper.GetBytes(path, bytes.Slice(bytesWritten));
        bytesWritten += SpanHelper.GetBytes(SheetEnd, bytes.Slice(bytesWritten));
        return(bytesWritten);
    }
示例#24
0
    private static int GetStylesXmlElementBytes(int relationId, Span <byte> bytes)
    {
        var bytesWritten = SpanHelper.GetBytes(StylesStart, bytes);

        bytesWritten += SpanHelper.GetBytes(SharedMetadata.RelationIdPrefix, bytes.Slice(bytesWritten));
        bytesWritten += Utf8Helper.GetBytes(relationId, bytes.Slice(bytesWritten));
        bytesWritten += SpanHelper.GetBytes(RelationEnd, bytes.Slice(bytesWritten));
        return(bytesWritten);
    }
示例#25
0
 public PairCache(BufferPool pool, int minimumMappingSize = 2048, int minimumPendingSize = 128, int minimumPerTypeCapacity = 128)
 {
     this.minimumPendingSize     = minimumPendingSize;
     this.minimumPerTypeCapacity = minimumPerTypeCapacity;
     this.pool = pool;
     OverlapMapping.Create(
         pool.SpecializeFor <CollidablePair>(), pool.SpecializeFor <CollidablePairPointers>(), pool.SpecializeFor <int>(),
         SpanHelper.GetContainingPowerOf2(minimumMappingSize), 3, out Mapping);
 }
示例#26
0
        /// <summary>
        /// Copies the pixels to a <see cref="Buffer2D{TPixel}"/> of the same size.
        /// </summary>
        /// <param name="target">The target pixel buffer accessor.</param>
        internal void CopyTo(Buffer2D <TPixel> target)
        {
            if (this.Size() != target.Size())
            {
                throw new ArgumentException("ImageFrame<TPixel>.CopyTo(): target must be of the same size!", nameof(target));
            }

            SpanHelper.Copy(this.GetPixelSpan(), target.Span);
        }
示例#27
0
        private static void AddExceptionTags(Exception exception, Activity activity)
        {
            if (!activity.IsAllDataRequested)
            {
                return;
            }

            Status status;

            if (exception is WebException wexc)
            {
                if (wexc.Response is HttpWebResponse response)
                {
                    activity.SetTag(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode);

                    status = SpanHelper.ResolveSpanStatusForHttpStatusCode((int)response.StatusCode);
                }
                else
                {
                    switch (wexc.Status)
                    {
                    case WebExceptionStatus.Timeout:
                    case WebExceptionStatus.RequestCanceled:
                        status = Status.Error;
                        break;

                    case WebExceptionStatus.SendFailure:
                    case WebExceptionStatus.ConnectFailure:
                    case WebExceptionStatus.SecureChannelFailure:
                    case WebExceptionStatus.TrustFailure:
                    case WebExceptionStatus.ServerProtocolViolation:
                    case WebExceptionStatus.MessageLengthLimitExceeded:
                        status = Status.Error.WithDescription(exception.Message);
                        break;

                    default:
                        status = Status.Error.WithDescription(exception.Message);
                        break;
                    }
                }
            }
            else
            {
                status = Status.Error.WithDescription(exception.Message);
            }

            activity.SetStatus(status);

            try
            {
                Options.Enrich?.Invoke(activity, "OnException", exception);
            }
            catch (Exception ex)
            {
                HttpInstrumentationEventSource.Log.EnrichmentException(ex);
            }
        }
        public void Translate_CallsMatchOnCodeSpanTranslator()
        {
            var span = SpanHelper.BuildSpan("a");
            var sut  = new StatementTranslator(this._codeSpanTranslator.Object);

            sut.Translate(span, this._templateBuilder.Object);

            this._codeSpanTranslator.Verify(c => c.Match(span));
        }
示例#29
0
        public void Match_GivenContentNotEndCodeBlock_ReturnsFalse()
        {
            var span = SpanHelper.BuildSpan("@Html.HiddenFor(m => m.Id)");

            var sut = new EndCodeBlockTranslator();

            var result = sut.Match(span);

            Assert.IsFalse(result);
        }
示例#30
0
        public void Match_GivenEndCodeBlockContentStartingWithTabIndent_ReturnsTrue()
        {
            var span = SpanHelper.BuildSpan("\t}");

            var sut = new EndCodeBlockTranslator();

            var result = sut.Match(span);

            Assert.IsTrue(result);
        }