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); } } }
public virtual IEnumerable<object> Unpack(Zongsoft.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; } } }