#ifndef WinBuffer_hh #define WinBuffer_hh #include #include #include #include #include using std::cout; using std::endl; struct Buffer { explicit Buffer(unsigned int bufsize) : bufsize_(bufsize), vsize_(0), index_(0), recIndex_(0), minBytesAvailable_(0), bytesRemainingInMsg_(0) { if (bufsize_ > 0) { buf_ = new char[bufsize_]; } } ~Buffer() { if (bufsize_ > 0) { delete [] buf_; } } int PersistentWrite(const void* data, int len) { DWORD dwNumOfBytesWritten = 0; int rc; char* d2 = (char*) data; #if 10 while ((rc = send(sock_, d2, len, 0)) != len) { if (rc < 0) { ews_.SetErrorWords(WSAGetLastError(), __FILE__, __LINE__); return 0; } len -= rc; d2 += rc; } #else WriteFile(sock_, d2, len, &dwNumOfBytesWritten, NULL); if (dwNumOfBytesWritten == 0) { ews_.SetErrorWords(GetLastError(), __FILE__, __LINE__); return 0; } #endif return 1; } int PersistentRead(void* data, int len) { int rc; char* d2 = (char*) data; while ((rc = recv(sock_, d2, len, 0)) != len) { if (rc < 0) { ews_.SetErrorWords(WSAGetLastError(), __FILE__, __LINE__); return 0; } else { if (rc == 0) { ews_.SetErrorWords(0, __FILE__, __LINE__); return 0; } len -= rc; d2 += rc; } } return 1; } int SendStoredData() { if (index_ > 0) { if (!PersistentWrite(buf_, index_)) { return 0; } index_ = 0; } return 1; } int Resize(unsigned int newsize) { if (newsize < index_) { if (!SendStoredData()) { ews_.SetErrorWords(0, __FILE__, __LINE__); return 0; } } char* tmp = new char[newsize]; memcpy(tmp, buf_, index_); delete [] buf_; buf_ = tmp; bufsize_ = newsize; return 1; } int Receive(const void* data, unsigned int dlen) { if (dlen > bufsize_ - index_) { if (!SendStoredData()) { return 0; } if (dlen > bufsize_) { if (!PersistentWrite(data, dlen)) { return 0; } return 1; } } memcpy(buf_ + index_, data, dlen); index_ += dlen; return 1; } int Give(void* address, unsigned int len) { using std::min; if (len > bytesRemainingInMsg_) { ews_.SetErrorWords(0, __FILE__, __LINE__); return 0; } char * addr = static_cast (address); if (vsize_ > recIndex_) { if (len <= (vsize_ - recIndex_)) { memcpy(addr, buf_ + recIndex_, len); recIndex_ += len; } else { memcpy(addr, buf_ + recIndex_, vsize_ - recIndex_); addr += (vsize_ - recIndex_); len -= (vsize_ - recIndex_); bytesRemainingInMsg_ -= (vsize_ - recIndex_); recIndex_ = vsize_; goto pull; } } else { pull: int rc = 0; if (minBytesAvailable_ < len) { if ((rc = ioctlsocket(sock_, FIONREAD, &minBytesAvailable_)) == SOCKET_ERROR) { ews_.SetErrorWords(WSAGetLastError(), __FILE__, __LINE__); return 0; } } if (len > bufsize_ || len > minBytesAvailable_) { if (!PersistentRead(addr, len)) { return 0; } minBytesAvailable_ = 0; } else { vsize_ = min(min(bufsize_, bytesRemainingInMsg_), minBytesAvailable_); minBytesAvailable_ -= vsize_; if ((rc = recv(sock_, buf_, vsize_, 0)) != vsize_) { ews_.SetErrorWords(WSAGetLastError(), __FILE__, __LINE__); return 0; } memcpy(addr, buf_, len); recIndex_ = len; } } bytesRemainingInMsg_ -= len; return 1; } int Reset() { index_ = 0; recIndex_ = 0; vsize_ = 0; minBytesAvailable_ = 0; bytesRemainingInMsg_ = 0; return 1; } void SetMsgLength(unsigned int totLen) { bytesRemainingInMsg_ = totLen; } int Debug() { cout << "bufsize_ is " << bufsize_ << endl; cout << "vsize_ is " << vsize_ << endl; cout << "index_ is " << index_ << endl; cout << "recIndex_ is " << recIndex_ << endl; return 1; } //SOCKET sock2_; SOCKET sock_; ErrorWordsShepherd ews_; private: unsigned int bufsize_; unsigned int vsize_; unsigned int index_; unsigned int recIndex_; unsigned long minBytesAvailable_; unsigned int bytesRemainingInMsg_; char* buf_; Buffer(Buffer const&); Buffer& operator=(Buffer const&); }; #endif