// Processes the data in the buffer previously allocated using // get_buffer function. size_ argument specifies nemuber of bytes // actually filled into the buffer. Function returns number of // bytes actually processed. public int ProcessBuffer(ByteArraySegment data, int size) { // Check if we had an error in previous attempt. if (State < 0) { return(-1); } // In case of zero-copy simply adjust the pointers, no copying // is required. Also, run the state machine in case all the data // were processed. if (data != null && data.Equals(m_readPos)) { m_readPos.AdvanceOffset(size); m_toRead -= size; while (m_toRead == 0) { if (!Next()) { if (State < 0) { return(-1); } return(size); } } return(size); } int pos = 0; while (true) { // Try to get more space in the message to fill in. // If none is available, return. while (m_toRead == 0) { if (!Next()) { if (State < 0) { return(-1); } return(pos); } } // If there are no more data in the buffer, return. if (pos == size) { return(pos); } // Copy the data from buffer to the message. int toCopy = Math.Min(m_toRead, size - pos); data.CopyTo(pos, m_readPos, 0, toCopy); m_readPos.AdvanceOffset(toCopy); pos += toCopy; m_toRead -= toCopy; } }
public void GetData(ref ByteArraySegment data, ref int size, ref int offset) { ByteArraySegment buffer = data ?? new ByteArraySegment(m_buf); int bufferSize = data == null ? m_buffersize : size; int pos = 0; while (pos < bufferSize) { // If there are no more data to return, run the state machine. // If there are still no data, return what we already have // in the buffer. if (m_toWrite == 0) { // If we are to encode the beginning of a new message, // adjust the message offset. if (m_beginning) { if (offset == -1) { offset = pos; } } if (!Next()) { break; } } // If there are no data in the buffer yet and we are able to // fill whole buffer in a single go, let's use zero-copy. // There's no disadvantage to it as we cannot stuck multiple // messages into the buffer anyway. Note that subsequent // write(s) are non-blocking, thus each single write writes // at most SO_SNDBUF bytes at once not depending on how large // is the chunk returned from here. // As a consequence, large messages being sent won't block // other engines running in the same I/O thread for excessive // amounts of time. if (pos == 0 && data == null && m_toWrite >= bufferSize) { data = m_writePos; size = m_toWrite; m_writePos = null; m_toWrite = 0; return; } // Copy data to the buffer. If the buffer is full, return. int toCopy = Math.Min(m_toWrite, bufferSize - pos); if (toCopy != 0) { m_writePos.CopyTo(0, buffer, pos, toCopy); pos += toCopy; m_writePos.AdvanceOffset(toCopy); m_toWrite -= toCopy; } } data = buffer; size = pos; }
/// <summary> /// Processes the data in the buffer previously allocated using /// get_buffer function. size argument specifies the number of bytes /// actually filled into the buffer. Function returns number of /// bytes actually processed. /// </summary> public int ProcessBuffer(ByteArraySegment data, int size) { // Check if we had an error in previous attempt. if (State < 0) { return -1; } // In case of zero-copy simply adjust the pointers, no copying // is required. Also, run the state machine in case all the data // were processed. if (data != null && data.Equals(m_readPos)) { m_readPos.AdvanceOffset(size); m_toRead -= size; while (m_toRead == 0) { if (!Next()) { if (State < 0) { return -1; } return size; } } return size; } int pos = 0; while (true) { // Try to get more space in the message to fill in. // If none is available, return. while (m_toRead == 0) { if (!Next()) { if (State < 0) { return -1; } return pos; } } // If there are no more data in the buffer, return. if (pos == size) return pos; // Copy the data from buffer to the message. int toCopy = Math.Min(m_toRead, size - pos); data.CopyTo(pos, m_readPos, 0, toCopy); m_readPos.AdvanceOffset(toCopy); pos += toCopy; m_toRead -= toCopy; } }