예제 #1
0
        /// <summary>
        /// Return a tree that contains right trapezoid and 2 left trapezoids
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public Node To3TrapsRight_2Left(Segment segment)
        {
            // Vertex node
            Node root = new VertexNode(segment.RightVertex);

            // Segment node
            Node segmentNode = new SegmentNode(segment);

            // Trapezoid nodes
            Trapezoid higherTrap = new Trapezoid(segment.LeftVertex, segment.RightVertex, Trapezoid.Top, segment);
            Trapezoid lowerTrap  = new Trapezoid(segment.LeftVertex, segment.RightVertex, segment, Trapezoid.Bottom);
            Trapezoid rightTrap  = new Trapezoid(segment.RightVertex, Trapezoid.Rightp, Trapezoid.Top, Trapezoid.Bottom);

            Node higherTrapNode = new TrapezoidalNode(higherTrap);
            Node lowerTrapNode  = new TrapezoidalNode(higherTrap);
            Node rightTrapNode  = new TrapezoidalNode(rightTrap);

            higherTrap.SetNeighbor(null, null, rightTrap, rightTrap);
            higherTrap.Node = higherTrapNode;

            lowerTrap.SetNeighbor(null, null, rightTrap, rightTrap);
            lowerTrap.Node = lowerTrapNode;

            rightTrap.SetNeighbor(higherTrap, lowerTrap, Trapezoid.HigherRightNeighbor, Trapezoid.LowerRightNeighbor);
            rightTrap.Node = rightTrapNode;

            segmentNode.SetChildren(ref higherTrapNode, ref lowerTrapNode);
            root.SetChildren(ref segmentNode, ref rightTrapNode);

            return(root);
        }
예제 #2
0
        public void FirstTestName()
        {
            var route = new RouteNode <Uri>(new StubRoute <Uri>());

            var joinNode = new JoinNode <Uri>(_id++, new ConstantNode <Uri>());

            joinNode.Add(route);

            var alpha = new AlphaNode <Uri>(_id++);

            alpha.Add(joinNode);

            var equal = new EqualNode <Uri>(() => _id++);

            equal.Add("version", alpha);

            var segment = new SegmentNode <Uri>(1);

            segment.Add(equal);

            var engine = new MagnumRoutingEngine <Uri>(x => x);

            engine.Match <RootNode <Uri> >().Single().Add(segment);

            bool called = false;

            var uri = new Uri("http://localhost/version");

            engine.Route(uri, x =>
            {
                called = true;
            });

            called.ShouldBeTrue();
        }
예제 #3
0
        public void RemoveEndCapAtEnd()
        {
            SegmentNode node = _segmentNodes[_segmentNodes.Count - 1];

            node.hasEndCap = false;
            RemoveMeshEndCap(node);
        }
예제 #4
0
        /// <summary>
        ///     检查当前的包的可用总长度
        /// </summary>
        /// <param name="node">当前数据段节点</param>
        /// <returns>返回可用的下一个消息总长度</returns>
        private unsafe int CheckBytes(SegmentNode node)
        {
            int         headOffset = 0;
            SegmentNode nextNode;

            if (node.RemainingSize >= 4)
            {
                return(BitConverter.ToInt32(node.Args.GetStub().Segment.Segment.Array, node.Args.GetStub().Segment.UsedOffset));
            }
            byte *head = stackalloc byte[4];

            nextNode = node;
            while (headOffset < 3)
            {
                fixed(byte *pData = &nextNode.Args.GetStub().Segment.Segment.Array[nextNode.Args.GetStub().Segment.UsedOffset])
                {
                    for (int i = 0; i < nextNode.RemainingSize && headOffset < 4; i++)
                    {
                        head[headOffset++] = *(pData + i);
                    }
                }

                nextNode = nextNode.Next;
                if (headOffset > 3)
                {
                    break;
                }
                if (nextNode == null)
                {
                    return(-1);
                }
            }
            return(*(int *)head);
        }
        public void Remove(SegmentNode <TRequest, TResponse> segmentTree, Endpoint endpoint)
        {
            var targetNode = FindNodeByRoute(segmentTree, endpoint.Route);

            targetNode?.HandleRequestFunctions?.Remove(endpoint.Method);
            RemoveUnusedNodes(segmentTree, () => { });
        }
예제 #6
0
        public void AddEndCap(int strokePointIndex)
        {
            SegmentNode node = _segmentNodes[strokePointIndex];

            node.hasEndCap = true;
            AddMeshEndCap(node);
        }
예제 #7
0
		public void FirstTestName()
		{
			var route = new RouteNode<Uri>(new StubRoute<Uri>());

			var joinNode = new JoinNode<Uri>(_id++, new ConstantNode<Uri>());
			joinNode.Add(route);

			var alpha = new AlphaNode<Uri>(_id++);
			alpha.Add(joinNode);

			var equal = new EqualNode<Uri>(() => _id++);
			equal.Add("version", alpha);

			var segment = new SegmentNode<Uri>(1);
			segment.Add(equal);

			var engine = new MagnumRoutingEngine<Uri>(x => x);
			engine.Match<RootNode<Uri>>().Single().Add(segment);

			bool called = false;

			var uri = new Uri("http://localhost/version");
			engine.Route(uri, x =>
				{
					called = true;
				});

			called.ShouldBeTrue();
		}
예제 #8
0
        /// <summary>
        ///    尝试读取一段字节数组类型的数据
        /// </summary>
        /// <param name="encoding">解析字符串所使用的编码集</param>
        /// <param name="length">需要读取的数据长度</param>
        /// <param name="data">如果返回True, 则这个字段携带了读取成功的数据</param>
        /// <returns>返回一个值,该值标示了当前是否读取成功。如果返回False, 则证明内部还没有足够的可用数据以供读取</returns>
        /// <exception cref="ArgumentNullException">参数不能为空</exception>
        /// <exception cref="IncorrectCalculationException">内部错误,应该终止业务程序</exception>
        public bool TryReadString(Encoding encoding, int length, out string data)
        {
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            int expectedDataLength = length;

            data = null;
            NetworkDataCheckResult chkResult;

            if (!InnerCheckEnoughSize(expectedDataLength, out chkResult))
            {
                return(false);
            }
            if (chkResult.SegmentCount == 1)
            {
                SegmentNode node = _curUsedHead;
                data           = encoding.GetString(node.Args.GetStub().Segment.Segment.Array, (node.Args.GetStub().Segment.UsedOffset + _curUsedCount), expectedDataLength);
                _curUsedCount += expectedDataLength;
                ReCalculateCurrentUsedSegment();
                return(true);
            }
            byte[] rawData;
            if (!TryReadBinaryData(length, out rawData))
            {
                throw new IncorrectCalculationException("#Incorrectly calculated internal network data offset.");
            }
            data = encoding.GetString(rawData, 0, rawData.Length);
            return(true);
        }
예제 #9
0
        /// <summary>
        /// Return a tree that contains left trapezoid and 2 right trapezoids
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public Node To3TrapsLeft_2Right(Segment segment)
        {
            // Vertex node
            Node root = new VertexNode(segment.LeftVertex);

            // Segment node
            Node segmentNode = new SegmentNode(segment);

            // Trapezoid nodes
            Trapezoid leftTrap   = new Trapezoid(Trapezoid.Leftp, segment.LeftVertex, Trapezoid.Top, Trapezoid.Bottom);
            Trapezoid higherTrap = new Trapezoid(segment.LeftVertex, segment.RightVertex, Trapezoid.Top, segment);
            Trapezoid lowerTrap  = new Trapezoid(segment.LeftVertex, segment.RightVertex, segment, Trapezoid.Bottom);

            Node higherTrapNode = new TrapezoidalNode(higherTrap);
            Node lowerTrapNode  = new TrapezoidalNode(lowerTrap);
            Node leftTrapNode   = new TrapezoidalNode(leftTrap);

            higherTrap.SetNeighbor(leftTrap, leftTrap, null, null);
            higherTrap.Node = higherTrapNode;

            lowerTrap.SetNeighbor(leftTrap, leftTrap, null, null);
            lowerTrap.Node = lowerTrapNode;

            leftTrap.SetNeighbor(Trapezoid.HigherLeftNeighbor, Trapezoid.LowerLeftNeighbor, higherTrap, lowerTrap);
            leftTrap.Node = leftTrapNode;

            segmentNode.SetChildren(ref higherTrapNode, ref lowerTrapNode);
            root.SetChildren(ref leftTrapNode, ref segmentNode);

            return(root);
        }
예제 #10
0
        /// <summary>
        ///    尝试检查当前剩余的可用数据长度是否满足指定数据长度的需求
        /// </summary>
        /// <param name="length">需要检查的数据长度</param>
        /// <param name="result">返回数据检测结果</param>
        /// <returns>如果返回False, 则证明内部还没有足够的可用数据以供读取</returns>
        private bool InnerCheckEnoughSize(int length, out NetworkDataCheckResult result)
        {
            result.SegmentCount = 0;
            if (_curUsedHead == null)
            {
                return(false);
            }
            int avaSize = _curUsedHead.RemainingSize - _curUsedCount;

            if (avaSize >= length)
            {
                result.SegmentCount = 1;
                return(true);
            }
            result.SegmentCount++;
            SegmentNode usedNode = _curUsedHead;
            SegmentNode nextNode = usedNode.Next;

            do
            {
                if (nextNode == null)
                {
                    return(false);
                }
                avaSize += nextNode.RemainingSize;
                result.SegmentCount++;
                if (avaSize >= length)
                {
                    return(true);
                }
            } while ((nextNode = nextNode.Next) != null);
            return(false);
        }
예제 #11
0
 private static SegmentNode <TRequest, TResponse>?FindSegmentInNode(SegmentNode <TRequest, TResponse>?node, ISegmentVariant segment)
 {
     return(segment switch
     {
         Root _ => node,
         Literal literal => FindSegmentInNodeList(node?.LiteralChildren, literal),
         Parameter parameter => FindSegmentInNodeList(node?.ParameterChildren, parameter),
         _ => throw new InvalidOperationException()
     });
예제 #12
0
 private void AddCrossSectionVerts(SegmentNode node)
 {
     node.hasCrossSectionVerts = true;
     node.crossSectionVertsIdx = _meshVerts.Count;
     for (int i = 0; i < _crossSectionVerts.Length; i++)
     {
         _meshVerts.Add(node.GetVertAt(i));
     }
 }
        private static void RegisterRequestHandler(
            SegmentNode <TRequest, TResponse> segmentTree,
            Endpoint endpoint,
            HandleRequest <TRequest, TResponse> handleRequest,
            IEnumerable <ISegmentVariant> segments)
        {
            var targetNode = FindTargetNode(segmentTree, segments);

            RegisterRequestHandlerOnNode(endpoint, handleRequest, targetNode);
        }
        public override bool Equals(object obj)
        {
            SegmentNode objSegNode = (SegmentNode)obj;

            if (!segment.Equals(objSegNode.segment))
            {
                return(false);
            }
            return(base.Equals(obj));
        }
예제 #15
0
        Match(
            SegmentNode <TRequest, TResponse> node,
            HttpMethod method,
            ICollection <string> segments,
            IDictionary <string, string> parameters)
        {
            var head = segments.First();

            var currentParameters = node.Matcher is Parameter {
                Key : var key
            }
        public void Register(
            SegmentNode <TRequest, TResponse> segmentTree,
            Endpoint endpoint,
            HandleRequest <TRequest, TResponse> handleRequest,
            ValidateParameterKeys validateParameterKeys)
        {
            var segments = ParseRoute(endpoint).ToList();

            RunParameterKeyValidation(validateParameterKeys, segments);
            RegisterRequestHandler(segmentTree, endpoint, handleRequest, segments);
        }
예제 #17
0
        private void ConnectCrossSectionVerts(SegmentNode nodeA, SegmentNode nodeB)
        {
            for (int i = 0; i < _crossSectionVerts.Length; i++)
            {
                int v_a0 = nodeA.GetCrossSectionVertIdx(i + 0), v_a1 = nodeA.GetCrossSectionVertIdx(i + 1);
                int v_b0 = nodeB.GetCrossSectionVertIdx(i + 0), v_b1 = nodeB.GetCrossSectionVertIdx(i + 1);

                AddTri(v_a0, v_a1, v_b0);
                AddTri(v_a1, v_b1, v_b0);
            }
        }
예제 #18
0
 private void RefreshMeshVerts(SegmentNode node, bool uploadImmediately = true)
 {
     for (int i = 0; i < node.CrossSectionVertsCount; i++)
     {
         _meshVerts[node.crossSectionVertsIdx + i] = node.GetVertAt(i);
     }
     if (uploadImmediately)
     {
         UploadMeshData();
     }
 }
예제 #19
0
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 /// <filterpriority>2</filterpriority>
 public void Dispose()
 {
     //give back all segments.
     while (_head != null)
     {
         //giveup current fixed stub.
         _head.Args.Complete();
         _head = _head.Next;
     }
     //release the end of segment ref.
     _tail = null;
 }
예제 #20
0
		public void Given_an_existing_segment_condition()
		{
			_engine = new MagnumRoutingEngine<Uri>(x => x);

			var segmentNode = new SegmentNode<Uri>(1);
			var equals = new EqualNode<Uri>(() => _id++);
			equals.Add("version", new AlphaNode<Uri>(_id++));
			segmentNode.Add(equals);


			_engine.Add(segmentNode);
		}
예제 #21
0
        public void AddPoint(StrokePoint strokePoint)
        {
            SegmentNode node = new SegmentNode(strokePoint, this);

            _segmentNodes.Add(node);
            if (_segmentNodes.Count > 1)
            {
                node.prevNode          = _segmentNodes[_segmentNodes.Count - 2];
                node.prevNode.nextNode = node;
                AddMeshSegment(node.prevNode, node);
            }
        }
예제 #22
0
        public RoutingEngineRoutingRunner()
        {
            _idGenerator = new SequentialNodeIdGenerator();

            _engine = new MagnumRoutingEngine <Uri>(x => x);

            _segment = new SegmentNode <Uri>(1);
            _engine.Match <RootNode <Uri> >().Single().Add(_segment);

            _equal = new EqualNode <Uri>(() => _id++);
            _segment.Add(_equal);
        }
예제 #23
0
		public RoutingEngineRoutingRunner()
		{
			_idGenerator = new SequentialNodeIdGenerator();

			_engine = new MagnumRoutingEngine<Uri>(x => x);

			_segment = new SegmentNode<Uri>(1);
			_engine.Match<RootNode<Uri>>().Single().Add(_segment);

			_equal = new EqualNode<Uri>(() => _id++);
			_segment.Add(_equal);
		}
예제 #24
0
        public void Given_an_existing_segment_condition()
        {
            _engine = new MagnumRoutingEngine <Uri>(x => x);

            var segmentNode = new SegmentNode <Uri>(1);
            var equals      = new EqualNode <Uri>(() => _id++);

            equals.Add("version", new AlphaNode <Uri>(_id++));
            segmentNode.Add(equals);


            _engine.Add(segmentNode);
        }
예제 #25
0
        private static void RemoveUnusedNodes(SegmentNode <TRequest, TResponse> node, Action removeFromParent)
        {
            bool HasParameterChildren() => node.ParameterChildren.Any();
            bool HasLiteralChildren() => node.LiteralChildren.Any();
            bool HasHandlersRegistered() => node.HandleRequestFunctions.Any();
            bool IsNodeUsed() => HasHandlersRegistered() || HasLiteralChildren() || HasParameterChildren();

            RemoveUnusedChildNodes(node.ParameterChildren);
            RemoveUnusedChildNodes(node.LiteralChildren);

            if (!IsNodeUsed())
            {
                removeFromParent();
            }
        }
예제 #26
0
        private void AddMeshSegment(SegmentNode node1, SegmentNode node2)
        {
            if (!node1.hasCrossSectionVerts)
            {
                AddCrossSectionVerts(node1);
            }
            if (!node2.hasCrossSectionVerts)
            {
                AddCrossSectionVerts(node2);
            }

            ConnectCrossSectionVerts(node1, node2);

            UploadMeshData();
        }
예제 #27
0
        public TResponse Route(SegmentNode <TRequest, TResponse> segmentTree, Endpoint endpoint, TRequest request)
        {
            var segments = _pathParser.Parse(endpoint.Route)?.ToList();

            if (segments is null)
            {
                return(_handleFallbackRequest(request));
            }

            var requestHandlingData = Match(segmentTree, endpoint.Method, segments, new Dictionary <string, string>());

            return(requestHandlingData is null
                ? _handleFallbackRequest(request)
                : requestHandlingData(request));
        }
예제 #28
0
        /// <summary>
        /// Return a tree that contains 2 trapezoids
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public Node To2Traps(Segment segment)
        {
            // Segment node
            Node root = new SegmentNode(segment);

            // Trapezoid nodes
            Trapezoid higherTrap = new Trapezoid(null, null, Trapezoid.Top, segment);
            Trapezoid lowerTrap  = new Trapezoid(null, null, segment, Trapezoid.Bottom);

            Node higherTrapNode = new TrapezoidalNode(higherTrap);
            Node lowerTrapNode  = new TrapezoidalNode(lowerTrap);

            root.SetChildren(ref higherTrapNode, ref lowerTrapNode);

            return(root);
        }
        /// <summary>
        /// Return a tree that contains 2 trapezoids
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public Node To2Traps(Segment segment)
        {
            // Segment node
            Node root = new SegmentNode(segment);

            // Trapezoid nodes
            Trapezoid higherTrap = new Trapezoid(null, null, Trapezoid.Top, segment);
            Trapezoid lowerTrap = new Trapezoid(null, null, segment, Trapezoid.Bottom);

            Node higherTrapNode = new TrapezoidalNode(higherTrap);
            Node lowerTrapNode = new TrapezoidalNode(lowerTrap);

            root.SetChildren(ref higherTrapNode, ref lowerTrapNode);

            return root;
        }
예제 #30
0
        /// <summary>
        ///    尝试读取一段字节数组类型的数据
        /// </summary>
        /// <param name="length">需要读取的数据长度</param>
        /// <param name="data">如果返回True, 则这个字段携带了读取成功的数据</param>
        /// <returns>返回一个值,该值标示了当前是否读取成功。如果返回False, 则证明内部还没有足够的可用数据以供读取</returns>
        public bool TryReadBinaryData(int length, out byte[] data)
        {
            int expectedDataLength = length;

            data = null;
            NetworkDataCheckResult chkResult;

            if (!InnerCheckEnoughSize(expectedDataLength, out chkResult))
            {
                return(false);
            }
            if (chkResult.SegmentCount == 1)
            {
                SegmentNode node = _curUsedHead;
                data = new byte[length];
                Buffer.BlockCopy(node.Args.GetStub().Segment.Segment.Array, (node.Args.GetStub().Segment.UsedOffset + _curUsedCount), data, 0, length);
                _curUsedCount += expectedDataLength;
                ReCalculateCurrentUsedSegment();
                return(true);
            }

            /* Specially optimized for value type.
             * What we expected is DO NOT to generates a new byte[] for undertaking those of 2 bytes data.
             *
             *        remaining only 1 byte data   next available data start here
             *                                          ↓   ↓
             *      ********************z   zzzzzzzzzz***********
             *                 Segment(1)                          Segment(2)
             */
            int offset = 0;
            int remainingDataLength = expectedDataLength;

            data = new byte[length];
            for (int i = 0; i < chkResult.SegmentCount; i++)
            {
                int segmentRemainingSize = _curUsedHead.Args.BytesTransferred - _curUsedCount;
                int remainingSize        = (segmentRemainingSize > remainingDataLength ? remainingDataLength : segmentRemainingSize);
                Buffer.BlockCopy(_curUsedHead.Args.GetStub().Segment.Segment.Array, (_curUsedHead.Args.GetStub().Segment.UsedOffset + _curUsedCount), data, offset, remainingSize);
                _curUsedCount       += remainingSize;
                offset              += remainingSize;
                remainingDataLength -= remainingSize;
                ReCalculateCurrentUsedSegment();
            }
            return(true);
        }
예제 #31
0
        /// <summary>
        ///    尝试读取一个字节的数据
        /// </summary>
        /// <param name="data">如果返回True, 则这个字段携带了读取成功的数据</param>
        /// <returns>返回一个值,该值标示了当前是否读取成功。如果返回False, 则证明内部还没有足够的可用数据以供读取</returns>
        /// <exception cref="IncorrectCalculationException">内部错误,应该终止业务程序</exception>
        public bool TryReadByte(out byte data)
        {
            data = 0xFF;
            NetworkDataCheckResult chkResult;

            if (!InnerCheckEnoughSize(1, out chkResult))
            {
                return(false);
            }
            if (chkResult.SegmentCount != 1)
            {
                throw new IncorrectCalculationException("#Incorrectly calculated internal network data offset.");
            }
            SegmentNode node = _curUsedHead;

            data = node.Args.GetStub().Segment.Segment.Array[node.Args.GetStub().Segment.UsedOffset + _curUsedCount++];
            ReCalculateCurrentUsedSegment();
            return(true);
        }
예제 #32
0
        /// <summary>
        ///    尝试读取一个Int64类型的数据
        /// </summary>
        /// <param name="data">如果返回True, 则这个字段携带了读取成功的数据</param>
        /// <returns>返回一个值,该值标示了当前是否读取成功。如果返回False, 则证明内部还没有足够的可用数据以供读取</returns>
        public unsafe bool TryReadInt64(out long data)
        {
            const int expectedDataLength = 8;

            data = 0xFF;
            NetworkDataCheckResult chkResult;

            if (!InnerCheckEnoughSize(expectedDataLength, out chkResult))
            {
                return(false);
            }
            if (chkResult.SegmentCount == 1)
            {
                SegmentNode node = _curUsedHead;
                fixed(byte *pData = node.Args.GetStub().Segment.Segment.Array)
                {
                    data           = *(long *)(pData + node.Args.GetStub().Segment.UsedOffset + _curUsedCount);
                    _curUsedCount += expectedDataLength;
                    ReCalculateCurrentUsedSegment();
                    return(true);
                }
            }

            /* Specially optimized for value type.
             * What we expected is DO NOT to generates a new byte[] for undertaking those of 2 bytes data.
             *
             *        remaining only 1 byte data   next available data start here
             *                                          ↓   ↓
             *      ********************z   zzzzzzz**************
             *                 Segment(1)                          Segment(2)
             */
            byte *tmpData = stackalloc byte[expectedDataLength];

            FillCrossSegmentData(tmpData, expectedDataLength);
            data = *(long *)tmpData;
            return(true);
        }
        /// <summary>
        /// Return a tree that contains 4 trapezoids
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        public Node To4Traps(Segment segment)
        {
            // Vertex nodes
            Node root = new VertexNode(segment.LeftVertex);
            Node rightVertexNode = new VertexNode(segment.RightVertex);

            // Segment node
            Node segmentNode = new SegmentNode(segment);

            // Trapezoid nodes
            Trapezoid leftTrap = new Trapezoid(Trapezoid.Leftp, segment.LeftVertex, Trapezoid.Top, Trapezoid.Bottom);
            Trapezoid higherCenterTrap = new Trapezoid(segment.LeftVertex, segment.RightVertex, Trapezoid.Top, segment);
            Trapezoid lowerCenterTrap = new Trapezoid(segment.LeftVertex, segment.RightVertex, segment, Trapezoid.Bottom);
            Trapezoid rightTrap = new Trapezoid(segment.RightVertex, Trapezoid.Rightp, Trapezoid.Top, Trapezoid.Bottom);

            Node leftTrapNode = new TrapezoidalNode(leftTrap);
            Node higherCenterTrapNode = new TrapezoidalNode(higherCenterTrap);
            Node lowerCenterTrapNode = new TrapezoidalNode(lowerCenterTrap);
            Node rightTrapNode = new TrapezoidalNode(rightTrap);

            leftTrap.SetNeighbor(Trapezoid.HigherLeftNeighbor, Trapezoid.LowerLeftNeighbor, higherCenterTrap, lowerCenterTrap);
            leftTrap.Node = leftTrapNode;

            higherCenterTrap.SetNeighbor(leftTrap, leftTrap, rightTrap, rightTrap);
            higherCenterTrap.Node = higherCenterTrapNode;

            lowerCenterTrap.SetNeighbor(leftTrap, leftTrap, rightTrap, rightTrap);
            lowerCenterTrap.Node = lowerCenterTrapNode;

            rightTrap.SetNeighbor(higherCenterTrap, lowerCenterTrap, Trapezoid.HigherRightNeighbor, Trapezoid.LowerRightNeighbor);
            rightTrap.Node = rightTrapNode;

            segmentNode.SetChildren(ref higherCenterTrapNode, ref lowerCenterTrapNode);
            rightVertexNode.SetChildren(ref segmentNode, ref rightTrapNode);
            root.SetChildren(ref leftTrapNode,ref rightVertexNode);

            return root;
        }
예제 #34
0
        /// <summary>
        ///     追加一个新的数据段
        /// </summary>
        /// <param name="args">数据段接受参数</param>
        public void Append(SegmentReceiveEventArgs args)
        {
            #region Step 1, check-on args.

            if (_head == null)
            {
                _head = _tail = new SegmentNode(args);
            }
            else
            {
                _tail.Next = new SegmentNode(args);
                _tail      = _tail.Next;
            }

            #endregion

            #region Step 2, check bytes enough & pickup data.

            int msgSize;
            //RESET next node for current expression.
            SegmentNode nextNode = _head;
            List <T>    msgs     = new List <T>();
            //check whatever bytes can be parse.
            while (nextNode != null && (msgSize = CheckBytes(nextNode)) > 0)
            {
                //direct parse.
                if (nextNode.RemainingSize >= msgSize)
                {
                    List <T> list = _protocolStack.Parse <T>(nextNode.Args.GetStub().Segment.Segment.Array, nextNode.Args.GetStub().Segment.UsedOffset, msgSize);
                    if (list != null)
                    {
                        msgs.AddRange(list);
                    }
                    nextNode.Args.GetStub().Segment.UsedBytes += msgSize;
                    //ChannelCounter.Instance.RateOfDirectParse.Increment();
                    if (nextNode.RemainingSize > 0)
                    {
                        continue;
                    }
                    //giveup current fixed stub.
                    nextNode.Args.Complete();
                    _head = nextNode = nextNode.Next;
                    if (_head != null)
                    {
                        continue;
                    }
                    //Tail node must be null, if the head node has no value.
                    _tail = null;
                    //publish messages.
                    if (msgs.Count > 0)
                    {
                        ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs));
                    }
                    return;
                }
                //create sub-list for all ava-data segment path.
                int         remainingSize     = msgSize - nextNode.RemainingSize;
                SegmentNode childHead         = (SegmentNode)nextNode.Clone();
                SegmentNode childTail         = (SegmentNode)nextNode.Clone();
                SegmentNode tempNode          = nextNode;
                SegmentNode lastRealNode      = null;
                SegmentNode cloneLastRealNode = null;
                do
                {
                    tempNode = tempNode.Next;
                    if (tempNode == null)
                    {
                        break;
                    }
                    remainingSize -= tempNode.RemainingSize;
                    //clone target node for child-list.
                    lastRealNode = tempNode;
                    SegmentNode cloneNode = (SegmentNode)tempNode.Clone();
                    cloneNode.Next = null;
                    childTail.Next = cloneNode;
                    childTail      = childTail.Next;
                } while (remainingSize > 0);
                //cannot get enough length for message really binary data.
                if (remainingSize > 0)
                {
                    if (msgs.Count > 0)
                    {
                        ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs));
                    }
                    return;
                }
                //copy data from child-list!
                int    dataOffset         = 0;
                byte[] data               = new byte[msgSize];
                int    dataRemainingCount = data.Length;
                int    usedBytes;
                int    lastUserBytes = 0;
                while (childHead != null && dataRemainingCount > 0)
                {
                    cloneLastRealNode = childHead;
                    Buffer.BlockCopy(childHead.Args.GetStub().Segment.Segment.Array,
                                     childHead.Args.GetStub().Segment.UsedOffset, data, dataOffset,
                                     (usedBytes = (childHead.RemainingSize > dataRemainingCount
                                                              ? dataRemainingCount
                                                              : childHead.RemainingSize)));
                    dataOffset         += usedBytes;
                    dataRemainingCount -= usedBytes;
                    childHead.Args.GetStub().Segment.UsedBytes += usedBytes;
                    lastUserBytes = childHead.Args.GetStub().Segment.UsedBytes;
                    if (childHead.RemainingSize <= 0)
                    {
                        //giveup current fixed stub.
                        childHead.Args.Complete();
                        childHead = childHead.Next;
                    }
                }
                if (cloneLastRealNode.RemainingSize - lastUserBytes == 0 && lastRealNode.Next == null)
                {
                    _head = nextNode = null;
                }
                else if (cloneLastRealNode.RemainingSize - lastUserBytes == 0 && lastRealNode.Next != null)
                {
                    _head = nextNode = lastRealNode.Next;
                }
                else
                {
                    lastRealNode.Args.GetStub().Segment.UsedBytes = lastUserBytes;
                    _head = nextNode = lastRealNode;
                }
                //_head = nextNode = ((cloneLastRealNode.RemainingSize == 0 && lastRealNode.Next == null) ? null : lastRealNode);
                List <T> list1 = _protocolStack.Parse <T>(data);
                if (list1 != null)
                {
                    msgs.AddRange(list1);
                }
            }
            //publish messages.
            if (msgs.Count > 0)
            {
                ParseSucceedHandler(new LightSingleArgEventArgs <List <T> >(msgs));
            }

            #endregion
        }
예제 #35
0
 public LineNode(SegmentNode node, Location locForward, Location locBackward)
 {
     _node = node;
     _location[Forward]  = locForward;
     _location[Backward] = locBackward;
 }