| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // Written in NSPR style to also be suitable for adding to the NSS demo suite | 4 // Written in NSPR style to also be suitable for adding to the NSS demo suite |
| 5 | 5 |
| 6 /* memio is a simple NSPR I/O layer that lets you decouple NSS from | 6 /* memio is a simple NSPR I/O layer that lets you decouple NSS from |
| 7 * the real network. It's rather like openssl's memory bio, | 7 * the real network. It's rather like openssl's memory bio, |
| 8 * and is useful when your app absolutely, positively doesn't | 8 * and is useful when your app absolutely, positively doesn't |
| 9 * want to let NSS do its own networking. | 9 * want to let NSS do its own networking. |
| 10 */ | 10 */ |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); | 221 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); |
| 222 return -1; | 222 return -1; |
| 223 } | 223 } |
| 224 | 224 |
| 225 secret = fd->secret; | 225 secret = fd->secret; |
| 226 mb = &secret->readbuf; | 226 mb = &secret->readbuf; |
| 227 PR_ASSERT(mb->bufsize); | 227 PR_ASSERT(mb->bufsize); |
| 228 rv = memio_buffer_get(mb, buf, len); | 228 rv = memio_buffer_get(mb, buf, len); |
| 229 if (rv == 0 && !secret->eof) { | 229 if (rv == 0 && !secret->eof) { |
| 230 secret->read_requested = len; | 230 secret->read_requested = len; |
| 231 /* If there is no more data in the buffer, report any pending errors |
| 232 * that were previously observed. Note that both the readbuf and the |
| 233 * writebuf are checked for errors, since the application may have |
| 234 * encountered a socket error while writing that would otherwise not |
| 235 * be reported until the application attempted to write again - which |
| 236 * it may never do. |
| 237 */ |
| 231 if (mb->last_err) | 238 if (mb->last_err) |
| 232 PR_SetError(mb->last_err, 0); | 239 PR_SetError(mb->last_err, 0); |
| 240 else if (secret->writebuf.last_err) |
| 241 PR_SetError(secret->writebuf.last_err, 0); |
| 233 else | 242 else |
| 234 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); | 243 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); |
| 235 return -1; | 244 return -1; |
| 236 } | 245 } |
| 237 | 246 |
| 238 secret->read_requested = 0; | 247 secret->read_requested = 0; |
| 239 return rv; | 248 return rv; |
| 240 } | 249 } |
| 241 | 250 |
| 242 static int PR_CALLBACK memio_Read(PRFileDesc *fd, void *buf, PRInt32 len) | 251 static int PR_CALLBACK memio_Read(PRFileDesc *fd, void *buf, PRInt32 len) |
| 243 { | 252 { |
| 244 /* pull bytes from buffer */ | 253 /* pull bytes from buffer */ |
| 245 return memio_Recv(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT); | 254 return memio_Recv(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT); |
| 246 } | 255 } |
| 247 | 256 |
| 248 static int PR_CALLBACK memio_Send(PRFileDesc *fd, const void *buf, PRInt32 len, | 257 static int PR_CALLBACK memio_Send(PRFileDesc *fd, const void *buf, PRInt32 len, |
| 249 PRIntn flags, PRIntervalTime timeout) | 258 PRIntn flags, PRIntervalTime timeout) |
| 250 { | 259 { |
| 251 struct PRFilePrivate *secret; | 260 struct PRFilePrivate *secret; |
| 252 struct memio_buffer *mb; | 261 struct memio_buffer *mb; |
| 253 int rv; | 262 int rv; |
| 254 | 263 |
| 255 secret = fd->secret; | 264 secret = fd->secret; |
| 256 mb = &secret->writebuf; | 265 mb = &secret->writebuf; |
| 257 PR_ASSERT(mb->bufsize); | 266 PR_ASSERT(mb->bufsize); |
| 258 | 267 |
| 268 /* Note that the read error state is not reported, because it cannot be |
| 269 * reported until all buffered data has been read. If there is an error |
| 270 * with the next layer, attempting to call Send again will report the |
| 271 * error appropriately. |
| 272 */ |
| 259 if (mb->last_err) { | 273 if (mb->last_err) { |
| 260 PR_SetError(mb->last_err, 0); | 274 PR_SetError(mb->last_err, 0); |
| 261 return -1; | 275 return -1; |
| 262 } | 276 } |
| 263 rv = memio_buffer_put(mb, buf, len); | 277 rv = memio_buffer_put(mb, buf, len); |
| 264 if (rv == 0) { | 278 if (rv == 0) { |
| 265 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); | 279 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); |
| 266 return -1; | 280 return -1; |
| 267 } | 281 } |
| 268 return rv; | 282 return rv; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); | 524 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); |
| 511 CHECKEQ(memio_buffer_used_contiguous(&mb), 1); | 525 CHECKEQ(memio_buffer_used_contiguous(&mb), 1); |
| 512 | 526 |
| 513 /* TODO: add more cases */ | 527 /* TODO: add more cases */ |
| 514 | 528 |
| 515 printf("Test passed\n"); | 529 printf("Test passed\n"); |
| 516 exit(0); | 530 exit(0); |
| 517 } | 531 } |
| 518 | 532 |
| 519 #endif | 533 #endif |
| OLD | NEW |