void ReturnOtherThanLastBuffer() { var bufferList = m_ReceiveCache.GetAllCachedItems(); var count = bufferList.Count; var lastBufferItem = bufferList[count - 1].Key.Array; for (var i = count - 2; i >= 0; i--) { if (bufferList[i].Key.Array != lastBufferItem) { m_BufferRecycler.Return(bufferList, 0, i + 1); break; } } m_ReceiveCache.Clear(); }
/// <summary> /// Processes the input segment. /// </summary> /// <param name="segment">The input segment.</param> /// <param name="state">The buffer state.</param> /// <returns> /// the processing result /// </returns> public virtual ProcessResult Process(ArraySegment <byte> segment, IBufferState state) { m_ReceiveCache.Add(segment, state); var rest = 0; while (true) { var packageInfo = m_ReceiveFilter.Filter(m_ReceiveCache, out rest); if (m_ReceiveFilter.State == FilterState.Error) { m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count); return(ProcessResult.Create(ProcessState.Error)); } if (m_MaxPackageLength > 0) { var length = m_ReceiveCache.Total; if (length > m_MaxPackageLength) { m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count); return(ProcessResult.Create(ProcessState.Error, string.Format("Max package length: {0}, current processed length: {1}", m_MaxPackageLength, length))); } } //Receive continue if (packageInfo == null) { if (rest > 0) { PushResetData(segment, rest, state); continue; } return(ProcessResult.Create(ProcessState.Cached)); } m_ReceiveFilter.Reset(); var nextReceiveFilter = m_ReceiveFilter.NextReceiveFilter; if (nextReceiveFilter != null) { m_ReceiveFilter = nextReceiveFilter; } m_PackageHandler.Handle(packageInfo); if (packageInfo is IBufferedPackageInfo && // is a buffered package (packageInfo as IBufferedPackageInfo).Data is BufferList) // and it uses receive buffer directly { // so we need to create a new receive buffer container to use m_ReceiveCache = new BufferList(); if (rest <= 0) { return(ProcessResult.Create(ProcessState.Cached)); } } else { ReturnOtherThanLastBuffer(); if (rest <= 0) { return(ProcessResult.Create(ProcessState.Completed)); } } PushResetData(segment, rest, state); } }