+ char* org = buf;
+ int nRes = 1;
+
+ if ((iFlags & MSG_WAITALL) == 0)
+ return recv(socket, buf, iLength, iFlags);
+
+ iFlags &= ~MSG_WAITALL;
+ while(iLength > 0 && nRes > 0)
+ {
+ nRes = recv(socket, buf, iLength, iFlags);
+ if (nRes < 0)
+ return nRes;
+
+ buf += nRes;
+ iLength -= nRes;
+ }
+ return buf - org;
+ }
+
+ inline int32_t SocketRead(socket_t socket, void *buf, uint32_t nLen)
+ {
+ int x = SocketReadFixed(socket, (char *)buf, nLen, MSG_WAITALL);
+
+ if (x == -1)
+ return GetSocketError();
+ if (x != (int)nLen)
+ return ECONNRESET;
+
+ return 0;
+ }
+
+ inline int32_t SocketRead(socket_t socket, int *iError, uint8_t* data, uint32_t iLength, uint64_t iTimeoutMs)
+ {
+ int x, tot = 0, nErr;
+ fd_set fd_read;
+ struct timeval tv;
+
+ if (iTimeoutMs <= 0)
+ return EINVAL;
+
+ while(tot != (int)iLength)
+ {
+ tv.tv_sec = (long)(iTimeoutMs / 1000);
+ tv.tv_usec = (long)(1000 * (iTimeoutMs % 1000));
+
+ FD_ZERO(&fd_read);
+ FD_SET(socket, &fd_read);
+
+ x = select(socket + 1, &fd_read, NULL, NULL, &tv);
+
+ if (x == 0)
+ return ETIMEDOUT;
+
+ SocketSetBlocking(socket, false);
+
+ x = SocketReadFixed(socket, (char *)data + tot, iLength - tot, 0);
+ nErr = GetSocketError();
+
+ SocketSetBlocking(socket, true);
+
+ if (x == -1)
+ {
+ if (nErr == EAGAIN)
+ continue;
+ return nErr;
+ }
+
+ if (x == 0)
+ return ECONNRESET;
+
+ tot += x;
+ }
+ return 0;