Пример #1
0
        public IEnumerable <object> Unpack(Buffer buffer)
        {
            int index;

            while ((index = SearchTerminatorToEnd(buffer.Value, buffer.Position, buffer.Count - buffer.Position)) >= 0)
            {
                buffer.Read(_bufferStream, index);
                var bytes = new byte[_bufferStream.Position - _terminator.Length];
                _bufferStream.Position = 0;
                _bufferStream.Read(bytes, 0, bytes.Length);
                _bufferStream.Position = 0;

                yield return(this.Resolve(_encoding.GetString(bytes)));
            }

            buffer.Read(_bufferStream, buffer.Count);
        }
Пример #2
0
        public virtual IEnumerable <JF.Common.Buffer> Pack(JF.Common.Buffer buffer)
        {
            if (buffer == null || buffer.Count == 0)
            {
                //遍历返回字节组缓存信息
                yield return(new JF.Common.Buffer(new byte[HEAD_LENGTH], 0));
            }

            var sequenceId    = System.Threading.Interlocked.Increment(ref _sequenceId);
            var bytes         = new byte[_bufferEvaluator.GetBufferSize(buffer.Count)];
            int contentLength = 0;

            while ((contentLength = buffer.Read(bytes, HEAD_LENGTH, bytes.Length - HEAD_LENGTH)) > 0)
            {
                //设置包的头部字段
                this.SetPackageHead(bytes, sequenceId, buffer.Count, contentLength);

                //遍历返回字节组缓存信息
                yield return(new JF.Common.Buffer(bytes, 0, HEAD_LENGTH + contentLength));

                //注意:一定要重新分配缓存数组,不然同一个缓存在高速发送过程中肯定会发生写入覆盖
                bytes = new byte[_bufferEvaluator.GetBufferSize(buffer.Count)];
            }
        }
Пример #3
0
        public virtual IEnumerable <object> Unpack(JF.Common.Buffer buffer)
        {
            int availableLength;

            while (buffer.CanRead())
            {
                //如果当前头部缓存指针位置小于包头的长度,则必须先读取头部数据
                if (_contentLength == 0 && _headOffset < HEAD_LENGTH)
                {
                    //从当前接受缓存中读取剩下的包头数据
                    availableLength = buffer.Read(_headBuffer, _headOffset, HEAD_LENGTH - _headOffset);

                    //将当前头部缓存指针加上当前实际读取的长度
                    _headOffset += availableLength;

                    //如果当前头部缓存指针位置仍然小于包头长度,则说明当前接数据缓存区数据量不够,
                    //即本次接收到的缓存数据已被读完,故直接退出当前方法。
                    if (_headOffset < HEAD_LENGTH)
                    {
                        yield break;
                    }

                    //至此头部数据接收完毕,将头部缓存解析成包头实体
                    _head = this.ResolveHeader(_headBuffer);

                    //如果包头指示当前数据包的实际内容长度为零,则说明此包为空包
                    if (_head.TotalLength == 0 || _head.ContentLength == 0)
                    {
                        //重置缓存指针位置,以指示下次需要进行包头解析
                        _headOffset    = 0;
                        _contentLength = 0;

                        //接着处理下一个小包
                        continue;
                    }

                    //映射当前数据包对应的缓存区。
                    if (!_bufferStates.ContainsKey(_head.SequenceId))
                    {
                        var bufferManager = this.GetBufferManager();
                        var id            = bufferManager.Allocate(_head.TotalLength);
                        _bufferStates[_head.SequenceId] = new BufferState(bufferManager.GetStream(id));
                    }
                }

                //计算出本次要接受的内容长度
                int contentLength = _contentLength == 0 ? _head.ContentLength : _contentLength;

                //定义当前接收的数据包对应的缓存状态对象
                BufferState bufferState;

                //从缓存容器中获取当前大包的缓存状态对象
                if (!_bufferStates.TryGetValue(_head.SequenceId, out bufferState))
                {
                    throw new InvalidOperationException("Can not obtain the BufferCache with sequence-id.");
                }

                //将接收到的数据写入缓存区
                availableLength = buffer.Read(bufferState.BufferStream, contentLength);
                //更新当前缓存状态中的缓存数
                bufferState.BufferedSize += availableLength;
                //设置下次要接收的内容长度
                _contentLength = contentLength - availableLength;

                //如果下次要接收的内容长度为零,则指示下次接收要先进行包头的处理,即将头缓存偏移量置零
                if (_contentLength == 0)
                {
                    _headOffset = 0;
                }

                //如果整个大包全部接受完毕
                if (bufferState.BufferedSize == _head.TotalLength)
                {
                    //重置缓存指针位置,以指示下次需要进行包头解析
                    _headOffset    = 0;
                    _contentLength = 0;

                    //重置当前缓存区流的指针
                    bufferState.BufferStream.Position = 0;

                    //将当前接收的数据包从缓存映射中删除
                    _bufferStates.Remove(_head.SequenceId);

                    yield return(bufferState.BufferStream);
                }
            }
        }