/* If there was a network error in the past taking bytes * out of the buffer, return it to the next call that * tries to read from an empty buffer. */ static int PR_CALLBACK memio_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, PRIntervalTime timeout) { struct PRFilePrivate *secret; struct memio_buffer *mb; int rv; if (flags) { PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1; } secret = fd->secret; mb = &secret->readbuf; PR_ASSERT(mb->bufsize); rv = memio_buffer_get(mb, buf, len); if (rv == 0 && !secret->eof) { if (mb->last_err) PR_SetError(mb->last_err, 0); else PR_SetError(PR_WOULD_BLOCK_ERROR, 0); return -1; } return rv; }
int main() { struct memio_buffer mb; char buf[100]; int i; memio_buffer_new(&mb, TEST_BUFLEN); CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1); CHECKEQ(memio_buffer_used_contiguous(&mb), 0); CHECKEQ(memio_buffer_put(&mb, "howdy", 5), 5); CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5); CHECKEQ(memio_buffer_used_contiguous(&mb), 5); CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0); CHECKEQ(memio_buffer_put(&mb, "!", 1), 1); CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); CHECKEQ(memio_buffer_used_contiguous(&mb), 6); CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0); CHECKEQ(memio_buffer_get(&mb, buf, 6), 6); CHECKEQ(memcmp(buf, "howdy!", 6), 0); CHECKEQ(memio_buffer_unused_contiguous(&mb), 1); CHECKEQ(memio_buffer_used_contiguous(&mb), 0); CHECKEQ(memio_buffer_put(&mb, "01234", 5), 5); CHECKEQ(memio_buffer_used_contiguous(&mb), 1); CHECKEQ(memio_buffer_wrapped_bytes(&mb), 4); CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5); CHECKEQ(memio_buffer_put(&mb, "5", 1), 1); CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); CHECKEQ(memio_buffer_used_contiguous(&mb), 1); /* TODO: add more cases */ printf("Test passed\n"); exit(0); }
/* If there was a network error in the past taking bytes * out of the buffer, return it to the next call that * tries to read from an empty buffer. */ static int PR_CALLBACK memio_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, PRIntervalTime timeout) { struct PRFilePrivate *secret; struct memio_buffer *mb; int rv; if (flags) { PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1; } secret = fd->secret; mb = &secret->readbuf; PR_ASSERT(mb->bufsize); rv = memio_buffer_get(mb, buf, len); if (rv == 0 && !secret->eof) { secret->read_requested = len; /* If there is no more data in the buffer, report any pending errors * that were previously observed. Note that both the readbuf and the * writebuf are checked for errors, since the application may have * encountered a socket error while writing that would otherwise not * be reported until the application attempted to write again - which * it may never do. */ if (mb->last_err) PR_SetError(mb->last_err, 0); else if (secret->writebuf.last_err) PR_SetError(secret->writebuf.last_err, 0); else PR_SetError(PR_WOULD_BLOCK_ERROR, 0); return -1; } secret->read_requested = 0; return rv; }