Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: net/base/nss_memio.c

Issue 647883002: git cl format the final third of the net/base directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 */
11 11
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <string.h> 13 #include <string.h>
14 14
15 #include <prerror.h> 15 #include <prerror.h>
16 #include <prinit.h> 16 #include <prinit.h>
17 #include <prlog.h> 17 #include <prlog.h>
18 18
19 #include "nss_memio.h" 19 #include "nss_memio.h"
20 20
21 /*--------------- private memio types -----------------------*/ 21 /*--------------- private memio types -----------------------*/
22 22
23 /*---------------------------------------------------------------------- 23 /*----------------------------------------------------------------------
24 Simple private circular buffer class. Size cannot be changed once allocated. 24 Simple private circular buffer class. Size cannot be changed once allocated.
25 ----------------------------------------------------------------------*/ 25 ----------------------------------------------------------------------*/
26 26
27 struct memio_buffer { 27 struct memio_buffer {
28 int head; /* where to take next byte out of buf */ 28 int head; /* where to take next byte out of buf */
29 int tail; /* where to put next byte into buf */ 29 int tail; /* where to put next byte into buf */
30 int bufsize; /* number of bytes allocated to buf */ 30 int bufsize; /* number of bytes allocated to buf */
31 /* TODO(port): error handling is pessimistic right now. 31 /* TODO(port): error handling is pessimistic right now.
mef 2014/10/10 20:38:17 not sure that this comment should align with those
32 * Once an error is set, the socket is considered broken 32 * Once an error is set, the socket is considered broken
33 * (PR_WOULD_BLOCK_ERROR not included). 33 * (PR_WOULD_BLOCK_ERROR not included).
34 */ 34 */
35 PRErrorCode last_err; 35 PRErrorCode last_err;
36 char *buf; 36 char* buf;
37 }; 37 };
38 38
39
40 /* The 'secret' field of a PRFileDesc created by memio_CreateIOLayer points 39 /* The 'secret' field of a PRFileDesc created by memio_CreateIOLayer points
41 * to one of these. 40 * to one of these.
42 * In the public header, we use struct memio_Private as a typesafe alias 41 * In the public header, we use struct memio_Private as a typesafe alias
43 * for this. This causes a few ugly typecasts in the private file, but 42 * for this. This causes a few ugly typecasts in the private file, but
44 * seems safer. 43 * seems safer.
45 */ 44 */
46 struct PRFilePrivate { 45 struct PRFilePrivate {
47 /* read requests are satisfied from this buffer */ 46 /* read requests are satisfied from this buffer */
48 struct memio_buffer readbuf; 47 struct memio_buffer readbuf;
49 48
50 /* write requests are satisfied from this buffer */ 49 /* write requests are satisfied from this buffer */
51 struct memio_buffer writebuf; 50 struct memio_buffer writebuf;
52 51
53 /* SSL needs to know socket peer's name */ 52 /* SSL needs to know socket peer's name */
54 PRNetAddr peername; 53 PRNetAddr peername;
55 54
56 /* if set, empty I/O returns EOF instead of EWOULDBLOCK */ 55 /* if set, empty I/O returns EOF instead of EWOULDBLOCK */
57 int eof; 56 int eof;
58 57
59 /* if set, the number of bytes requested from readbuf that were not 58 /* if set, the number of bytes requested from readbuf that were not
60 * fulfilled (due to readbuf being empty) */ 59 * fulfilled (due to readbuf being empty) */
61 int read_requested; 60 int read_requested;
62 }; 61 };
63 62
64 /*--------------- private memio_buffer functions ---------------------*/ 63 /*--------------- private memio_buffer functions ---------------------*/
65 64
66 /* Forward declarations. */ 65 /* Forward declarations. */
67 66
68 /* Allocate a memio_buffer of given size. */ 67 /* Allocate a memio_buffer of given size. */
69 static void memio_buffer_new(struct memio_buffer *mb, int size); 68 static void memio_buffer_new(struct memio_buffer* mb, int size);
70 69
71 /* Deallocate a memio_buffer allocated by memio_buffer_new. */ 70 /* Deallocate a memio_buffer allocated by memio_buffer_new. */
72 static void memio_buffer_destroy(struct memio_buffer *mb); 71 static void memio_buffer_destroy(struct memio_buffer* mb);
73 72
74 /* How many bytes can be read out of the buffer without wrapping */ 73 /* How many bytes can be read out of the buffer without wrapping */
75 static int memio_buffer_used_contiguous(const struct memio_buffer *mb); 74 static int memio_buffer_used_contiguous(const struct memio_buffer* mb);
76 75
77 /* How many bytes exist after the wrap? */ 76 /* How many bytes exist after the wrap? */
78 static int memio_buffer_wrapped_bytes(const struct memio_buffer *mb); 77 static int memio_buffer_wrapped_bytes(const struct memio_buffer* mb);
79 78
80 /* How many bytes can be written into the buffer without wrapping */ 79 /* How many bytes can be written into the buffer without wrapping */
81 static int memio_buffer_unused_contiguous(const struct memio_buffer *mb); 80 static int memio_buffer_unused_contiguous(const struct memio_buffer* mb);
82 81
83 /* Write n bytes into the buffer. Returns number of bytes written. */ 82 /* Write n bytes into the buffer. Returns number of bytes written. */
84 static int memio_buffer_put(struct memio_buffer *mb, const char *buf, int n); 83 static int memio_buffer_put(struct memio_buffer* mb, const char* buf, int n);
85 84
86 /* Read n bytes from the buffer. Returns number of bytes read. */ 85 /* Read n bytes from the buffer. Returns number of bytes read. */
87 static int memio_buffer_get(struct memio_buffer *mb, char *buf, int n); 86 static int memio_buffer_get(struct memio_buffer* mb, char* buf, int n);
88 87
89 /* Allocate a memio_buffer of given size. */ 88 /* Allocate a memio_buffer of given size. */
90 static void memio_buffer_new(struct memio_buffer *mb, int size) 89 static void memio_buffer_new(struct memio_buffer* mb, int size) {
91 { 90 mb->head = 0;
92 mb->head = 0; 91 mb->tail = 0;
93 mb->tail = 0; 92 mb->bufsize = size;
94 mb->bufsize = size; 93 mb->buf = malloc(size);
95 mb->buf = malloc(size);
96 } 94 }
97 95
98 /* Deallocate a memio_buffer allocated by memio_buffer_new. */ 96 /* Deallocate a memio_buffer allocated by memio_buffer_new. */
99 static void memio_buffer_destroy(struct memio_buffer *mb) 97 static void memio_buffer_destroy(struct memio_buffer* mb) {
100 { 98 free(mb->buf);
101 free(mb->buf); 99 mb->buf = NULL;
102 mb->buf = NULL; 100 mb->bufsize = 0;
103 mb->bufsize = 0; 101 mb->head = 0;
104 mb->head = 0; 102 mb->tail = 0;
105 mb->tail = 0;
106 } 103 }
107 104
108 /* How many bytes can be read out of the buffer without wrapping */ 105 /* How many bytes can be read out of the buffer without wrapping */
109 static int memio_buffer_used_contiguous(const struct memio_buffer *mb) 106 static int memio_buffer_used_contiguous(const struct memio_buffer* mb) {
110 { 107 return (((mb->tail >= mb->head) ? mb->tail : mb->bufsize) - mb->head);
111 return (((mb->tail >= mb->head) ? mb->tail : mb->bufsize) - mb->head);
112 } 108 }
113 109
114 /* How many bytes exist after the wrap? */ 110 /* How many bytes exist after the wrap? */
115 static int memio_buffer_wrapped_bytes(const struct memio_buffer *mb) 111 static int memio_buffer_wrapped_bytes(const struct memio_buffer* mb) {
116 { 112 return (mb->tail >= mb->head) ? 0 : mb->tail;
117 return (mb->tail >= mb->head) ? 0 : mb->tail;
118 } 113 }
119 114
120 /* How many bytes can be written into the buffer without wrapping */ 115 /* How many bytes can be written into the buffer without wrapping */
121 static int memio_buffer_unused_contiguous(const struct memio_buffer *mb) 116 static int memio_buffer_unused_contiguous(const struct memio_buffer* mb) {
122 { 117 if (mb->head > mb->tail)
123 if (mb->head > mb->tail) return mb->head - mb->tail - 1; 118 return mb->head - mb->tail - 1;
124 return mb->bufsize - mb->tail - (mb->head == 0); 119 return mb->bufsize - mb->tail - (mb->head == 0);
125 } 120 }
126 121
127 /* Write n bytes into the buffer. Returns number of bytes written. */ 122 /* Write n bytes into the buffer. Returns number of bytes written. */
128 static int memio_buffer_put(struct memio_buffer *mb, const char *buf, int n) 123 static int memio_buffer_put(struct memio_buffer* mb, const char* buf, int n) {
129 { 124 int len;
130 int len; 125 int transferred = 0;
131 int transferred = 0; 126
132 127 /* Handle part before wrap */
mef 2014/10/10 20:38:17 I think NSS has/had formatting different from Chro
133 /* Handle part before wrap */ 128 len = PR_MIN(n, memio_buffer_unused_contiguous(mb));
129 if (len > 0) {
130 /* Buffer not full */
131 memcpy(&mb->buf[mb->tail], buf, len);
132 mb->tail += len;
133 if (mb->tail == mb->bufsize)
134 mb->tail = 0;
135 n -= len;
136 buf += len;
137 transferred += len;
138
139 /* Handle part after wrap */
134 len = PR_MIN(n, memio_buffer_unused_contiguous(mb)); 140 len = PR_MIN(n, memio_buffer_unused_contiguous(mb));
135 if (len > 0) { 141 if (len > 0) {
136 /* Buffer not full */ 142 /* Output buffer still not full, input buffer still not empty */
137 memcpy(&mb->buf[mb->tail], buf, len); 143 memcpy(&mb->buf[mb->tail], buf, len);
138 mb->tail += len; 144 mb->tail += len;
139 if (mb->tail == mb->bufsize) 145 if (mb->tail == mb->bufsize)
140 mb->tail = 0; 146 mb->tail = 0;
141 n -= len; 147 transferred += len;
142 buf += len;
143 transferred += len;
144
145 /* Handle part after wrap */
146 len = PR_MIN(n, memio_buffer_unused_contiguous(mb));
147 if (len > 0) {
148 /* Output buffer still not full, input buffer still not empty */
149 memcpy(&mb->buf[mb->tail], buf, len);
150 mb->tail += len;
151 if (mb->tail == mb->bufsize)
152 mb->tail = 0;
153 transferred += len;
154 }
155 } 148 }
156 149 }
157 return transferred; 150
158 } 151 return transferred;
159 152 }
160 153
161 /* Read n bytes from the buffer. Returns number of bytes read. */ 154 /* Read n bytes from the buffer. Returns number of bytes read. */
162 static int memio_buffer_get(struct memio_buffer *mb, char *buf, int n) 155 static int memio_buffer_get(struct memio_buffer* mb, char* buf, int n) {
163 { 156 int len;
164 int len; 157 int transferred = 0;
165 int transferred = 0; 158
166 159 /* Handle part before wrap */
167 /* Handle part before wrap */ 160 len = PR_MIN(n, memio_buffer_used_contiguous(mb));
161 if (len) {
162 memcpy(buf, &mb->buf[mb->head], len);
163 mb->head += len;
164 if (mb->head == mb->bufsize)
165 mb->head = 0;
166 n -= len;
167 buf += len;
168 transferred += len;
169
170 /* Handle part after wrap */
168 len = PR_MIN(n, memio_buffer_used_contiguous(mb)); 171 len = PR_MIN(n, memio_buffer_used_contiguous(mb));
169 if (len) { 172 if (len) {
170 memcpy(buf, &mb->buf[mb->head], len); 173 memcpy(buf, &mb->buf[mb->head], len);
171 mb->head += len; 174 mb->head += len;
172 if (mb->head == mb->bufsize) 175 if (mb->head == mb->bufsize)
173 mb->head = 0; 176 mb->head = 0;
174 n -= len; 177 transferred += len;
175 buf += len;
176 transferred += len;
177
178 /* Handle part after wrap */
179 len = PR_MIN(n, memio_buffer_used_contiguous(mb));
180 if (len) {
181 memcpy(buf, &mb->buf[mb->head], len);
182 mb->head += len;
183 if (mb->head == mb->bufsize)
184 mb->head = 0;
185 transferred += len;
186 }
187 } 178 }
188 179 }
189 return transferred; 180
181 return transferred;
190 } 182 }
191 183
192 /*--------------- private memio functions -----------------------*/ 184 /*--------------- private memio functions -----------------------*/
193 185
194 static PRStatus PR_CALLBACK memio_Close(PRFileDesc *fd) 186 static PRStatus PR_CALLBACK memio_Close(PRFileDesc* fd) {
195 { 187 struct PRFilePrivate* secret = fd->secret;
196 struct PRFilePrivate *secret = fd->secret; 188 memio_buffer_destroy(&secret->readbuf);
197 memio_buffer_destroy(&secret->readbuf); 189 memio_buffer_destroy(&secret->writebuf);
198 memio_buffer_destroy(&secret->writebuf); 190 free(secret);
199 free(secret); 191 fd->dtor(fd);
200 fd->dtor(fd); 192 return PR_SUCCESS;
201 return PR_SUCCESS; 193 }
202 } 194
203 195 static PRStatus PR_CALLBACK memio_Shutdown(PRFileDesc* fd, PRIntn how) {
204 static PRStatus PR_CALLBACK memio_Shutdown(PRFileDesc *fd, PRIntn how) 196 /* TODO: pass shutdown status to app somehow */
205 { 197 return PR_SUCCESS;
206 /* TODO: pass shutdown status to app somehow */
207 return PR_SUCCESS;
208 } 198 }
209 199
210 /* If there was a network error in the past taking bytes 200 /* If there was a network error in the past taking bytes
211 * out of the buffer, return it to the next call that 201 * out of the buffer, return it to the next call that
212 * tries to read from an empty buffer. 202 * tries to read from an empty buffer.
213 */ 203 */
214 static int PR_CALLBACK memio_Recv(PRFileDesc *fd, void *buf, PRInt32 len, 204 static int PR_CALLBACK memio_Recv(PRFileDesc* fd,
215 PRIntn flags, PRIntervalTime timeout) 205 void* buf,
216 { 206 PRInt32 len,
217 struct PRFilePrivate *secret; 207 PRIntn flags,
218 struct memio_buffer *mb; 208 PRIntervalTime timeout) {
219 int rv; 209 struct PRFilePrivate* secret;
220 210 struct memio_buffer* mb;
221 if (flags) { 211 int rv;
222 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); 212
223 return -1; 213 if (flags) {
224 } 214 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
225 215 return -1;
226 secret = fd->secret; 216 }
227 mb = &secret->readbuf; 217
228 PR_ASSERT(mb->bufsize); 218 secret = fd->secret;
229 rv = memio_buffer_get(mb, buf, len); 219 mb = &secret->readbuf;
230 if (rv == 0 && !secret->eof) { 220 PR_ASSERT(mb->bufsize);
231 secret->read_requested = len; 221 rv = memio_buffer_get(mb, buf, len);
232 /* If there is no more data in the buffer, report any pending errors 222 if (rv == 0 && !secret->eof) {
233 * that were previously observed. Note that both the readbuf and the 223 secret->read_requested = len;
234 * writebuf are checked for errors, since the application may have 224 /* If there is no more data in the buffer, report any pending errors
235 * encountered a socket error while writing that would otherwise not 225 * that were previously observed. Note that both the readbuf and the
236 * be reported until the application attempted to write again - which 226 * writebuf are checked for errors, since the application may have
237 * it may never do. 227 * encountered a socket error while writing that would otherwise not
238 */ 228 * be reported until the application attempted to write again - which
239 if (mb->last_err) 229 * it may never do.
240 PR_SetError(mb->last_err, 0);
241 else if (secret->writebuf.last_err)
242 PR_SetError(secret->writebuf.last_err, 0);
243 else
244 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
245 return -1;
246 }
247
248 secret->read_requested = 0;
249 return rv;
250 }
251
252 static int PR_CALLBACK memio_Read(PRFileDesc *fd, void *buf, PRInt32 len)
253 {
254 /* pull bytes from buffer */
255 return memio_Recv(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT);
256 }
257
258 static int PR_CALLBACK memio_Send(PRFileDesc *fd, const void *buf, PRInt32 len,
259 PRIntn flags, PRIntervalTime timeout)
260 {
261 struct PRFilePrivate *secret;
262 struct memio_buffer *mb;
263 int rv;
264
265 secret = fd->secret;
266 mb = &secret->writebuf;
267 PR_ASSERT(mb->bufsize);
268
269 /* Note that the read error state is not reported, because it cannot be
270 * reported until all buffered data has been read. If there is an error
271 * with the next layer, attempting to call Send again will report the
272 * error appropriately.
273 */ 230 */
274 if (mb->last_err) { 231 if (mb->last_err)
275 PR_SetError(mb->last_err, 0); 232 PR_SetError(mb->last_err, 0);
276 return -1; 233 else if (secret->writebuf.last_err)
277 } 234 PR_SetError(secret->writebuf.last_err, 0);
278 rv = memio_buffer_put(mb, buf, len); 235 else
279 if (rv == 0) { 236 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
280 PR_SetError(PR_WOULD_BLOCK_ERROR, 0); 237 return -1;
281 return -1; 238 }
282 } 239
283 return rv; 240 secret->read_requested = 0;
284 } 241 return rv;
285 242 }
286 static int PR_CALLBACK memio_Write(PRFileDesc *fd, const void *buf, PRInt32 len) 243
287 { 244 static int PR_CALLBACK memio_Read(PRFileDesc* fd, void* buf, PRInt32 len) {
288 /* append bytes to buffer */ 245 /* pull bytes from buffer */
289 return memio_Send(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT); 246 return memio_Recv(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT);
290 } 247 }
291 248
292 static PRStatus PR_CALLBACK memio_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) 249 static int PR_CALLBACK memio_Send(PRFileDesc* fd,
293 { 250 const void* buf,
294 /* TODO: fail if memio_SetPeerName has not been called */ 251 PRInt32 len,
295 struct PRFilePrivate *secret = fd->secret; 252 PRIntn flags,
296 *addr = secret->peername; 253 PRIntervalTime timeout) {
254 struct PRFilePrivate* secret;
255 struct memio_buffer* mb;
256 int rv;
257
258 secret = fd->secret;
259 mb = &secret->writebuf;
260 PR_ASSERT(mb->bufsize);
261
262 /* Note that the read error state is not reported, because it cannot be
263 * reported until all buffered data has been read. If there is an error
264 * with the next layer, attempting to call Send again will report the
265 * error appropriately.
266 */
267 if (mb->last_err) {
268 PR_SetError(mb->last_err, 0);
269 return -1;
270 }
271 rv = memio_buffer_put(mb, buf, len);
272 if (rv == 0) {
273 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
274 return -1;
275 }
276 return rv;
277 }
278
279 static int PR_CALLBACK
280 memio_Write(PRFileDesc* fd, const void* buf, PRInt32 len) {
281 /* append bytes to buffer */
282 return memio_Send(fd, buf, len, 0, PR_INTERVAL_NO_TIMEOUT);
283 }
284
285 static PRStatus PR_CALLBACK memio_GetPeerName(PRFileDesc* fd, PRNetAddr* addr) {
286 /* TODO: fail if memio_SetPeerName has not been called */
287 struct PRFilePrivate* secret = fd->secret;
288 *addr = secret->peername;
289 return PR_SUCCESS;
290 }
291
292 static PRStatus memio_GetSocketOption(PRFileDesc* fd,
293 PRSocketOptionData* data) {
294 /*
295 * Even in the original version for real tcp sockets,
296 * PR_SockOpt_Nonblocking is a special case that does not
297 * translate to a getsockopt() call
298 */
299 if (PR_SockOpt_Nonblocking == data->option) {
300 data->value.non_blocking = PR_TRUE;
297 return PR_SUCCESS; 301 return PR_SUCCESS;
298 } 302 }
299 303 PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
300 static PRStatus memio_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) 304 return PR_FAILURE;
301 {
302 /*
303 * Even in the original version for real tcp sockets,
304 * PR_SockOpt_Nonblocking is a special case that does not
305 * translate to a getsockopt() call
306 */
307 if (PR_SockOpt_Nonblocking == data->option) {
308 data->value.non_blocking = PR_TRUE;
309 return PR_SUCCESS;
310 }
311 PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
312 return PR_FAILURE;
313 } 305 }
314 306
315 /*--------------- private memio data -----------------------*/ 307 /*--------------- private memio data -----------------------*/
316 308
317 /* 309 /*
318 * Implement just the bare minimum number of methods needed to make ssl happy. 310 * Implement just the bare minimum number of methods needed to make ssl happy.
319 * 311 *
320 * Oddly, PR_Recv calls ssl_Recv calls ssl_SocketIsBlocking calls 312 * Oddly, PR_Recv calls ssl_Recv calls ssl_SocketIsBlocking calls
321 * PR_GetSocketOption, so we have to provide an implementation of 313 * PR_GetSocketOption, so we have to provide an implementation of
322 * PR_GetSocketOption that just says "I'm nonblocking". 314 * PR_GetSocketOption that just says "I'm nonblocking".
323 */ 315 */
324 316
325 static struct PRIOMethods memio_layer_methods = { 317 static struct PRIOMethods memio_layer_methods = {
326 PR_DESC_LAYERED, 318 PR_DESC_LAYERED,
327 memio_Close, 319 memio_Close,
328 memio_Read, 320 memio_Read,
329 memio_Write, 321 memio_Write,
330 NULL, 322 NULL,
331 NULL, 323 NULL,
332 NULL, 324 NULL,
333 NULL, 325 NULL,
334 NULL, 326 NULL,
335 NULL, 327 NULL,
(...skipping 20 matching lines...) Expand all
356 NULL, 348 NULL,
357 NULL, 349 NULL,
358 NULL, 350 NULL,
359 NULL, 351 NULL,
360 NULL, 352 NULL,
361 NULL, 353 NULL,
362 }; 354 };
363 355
364 static PRDescIdentity memio_identity = PR_INVALID_IO_LAYER; 356 static PRDescIdentity memio_identity = PR_INVALID_IO_LAYER;
365 357
366 static PRStatus memio_InitializeLayerName(void) 358 static PRStatus memio_InitializeLayerName(void) {
367 { 359 memio_identity = PR_GetUniqueIdentity("memio");
368 memio_identity = PR_GetUniqueIdentity("memio"); 360 return PR_SUCCESS;
369 return PR_SUCCESS;
370 } 361 }
371 362
372 /*--------------- public memio functions -----------------------*/ 363 /*--------------- public memio functions -----------------------*/
373 364
374 PRFileDesc *memio_CreateIOLayer(int readbufsize, int writebufsize) 365 PRFileDesc* memio_CreateIOLayer(int readbufsize, int writebufsize) {
375 { 366 PRFileDesc* fd;
376 PRFileDesc *fd; 367 struct PRFilePrivate* secret;
377 struct PRFilePrivate *secret; 368 static PRCallOnceType once;
378 static PRCallOnceType once;
379 369
380 PR_CallOnce(&once, memio_InitializeLayerName); 370 PR_CallOnce(&once, memio_InitializeLayerName);
381 371
382 fd = PR_CreateIOLayerStub(memio_identity, &memio_layer_methods); 372 fd = PR_CreateIOLayerStub(memio_identity, &memio_layer_methods);
383 secret = malloc(sizeof(struct PRFilePrivate)); 373 secret = malloc(sizeof(struct PRFilePrivate));
384 memset(secret, 0, sizeof(*secret)); 374 memset(secret, 0, sizeof(*secret));
385 375
386 memio_buffer_new(&secret->readbuf, readbufsize); 376 memio_buffer_new(&secret->readbuf, readbufsize);
387 memio_buffer_new(&secret->writebuf, writebufsize); 377 memio_buffer_new(&secret->writebuf, writebufsize);
388 fd->secret = secret; 378 fd->secret = secret;
389 return fd; 379 return fd;
390 } 380 }
391 381
392 void memio_SetPeerName(PRFileDesc *fd, const PRNetAddr *peername) 382 void memio_SetPeerName(PRFileDesc* fd, const PRNetAddr* peername) {
393 { 383 PRFileDesc* memiofd = PR_GetIdentitiesLayer(fd, memio_identity);
394 PRFileDesc *memiofd = PR_GetIdentitiesLayer(fd, memio_identity); 384 struct PRFilePrivate* secret = memiofd->secret;
395 struct PRFilePrivate *secret = memiofd->secret; 385 secret->peername = *peername;
396 secret->peername = *peername;
397 } 386 }
398 387
399 memio_Private *memio_GetSecret(PRFileDesc *fd) 388 memio_Private* memio_GetSecret(PRFileDesc* fd) {
400 { 389 PRFileDesc* memiofd = PR_GetIdentitiesLayer(fd, memio_identity);
401 PRFileDesc *memiofd = PR_GetIdentitiesLayer(fd, memio_identity); 390 struct PRFilePrivate* secret = memiofd->secret;
402 struct PRFilePrivate *secret = memiofd->secret; 391 return (memio_Private*)secret;
403 return (memio_Private *)secret;
404 } 392 }
405 393
406 int memio_GetReadRequest(memio_Private *secret) 394 int memio_GetReadRequest(memio_Private* secret) {
407 { 395 return ((PRFilePrivate*)secret)->read_requested;
408 return ((PRFilePrivate *)secret)->read_requested;
409 } 396 }
410 397
411 int memio_GetReadParams(memio_Private *secret, char **buf) 398 int memio_GetReadParams(memio_Private* secret, char** buf) {
412 { 399 struct memio_buffer* mb = &((PRFilePrivate*)secret)->readbuf;
413 struct memio_buffer* mb = &((PRFilePrivate *)secret)->readbuf; 400 PR_ASSERT(mb->bufsize);
414 PR_ASSERT(mb->bufsize);
415 401
416 *buf = &mb->buf[mb->tail]; 402 *buf = &mb->buf[mb->tail];
417 return memio_buffer_unused_contiguous(mb); 403 return memio_buffer_unused_contiguous(mb);
418 } 404 }
419 405
420 int memio_GetReadableBufferSize(memio_Private *secret) 406 int memio_GetReadableBufferSize(memio_Private* secret) {
421 { 407 struct memio_buffer* mb = &((PRFilePrivate*)secret)->readbuf;
422 struct memio_buffer* mb = &((PRFilePrivate *)secret)->readbuf; 408 PR_ASSERT(mb->bufsize);
423 PR_ASSERT(mb->bufsize);
424 409
425 return memio_buffer_used_contiguous(mb); 410 return memio_buffer_used_contiguous(mb);
426 } 411 }
427 412
428 void memio_PutReadResult(memio_Private *secret, int bytes_read) 413 void memio_PutReadResult(memio_Private* secret, int bytes_read) {
429 { 414 struct memio_buffer* mb = &((PRFilePrivate*)secret)->readbuf;
430 struct memio_buffer* mb = &((PRFilePrivate *)secret)->readbuf; 415 PR_ASSERT(mb->bufsize);
431 PR_ASSERT(mb->bufsize);
432 416
433 if (bytes_read > 0) { 417 if (bytes_read > 0) {
434 mb->tail += bytes_read; 418 mb->tail += bytes_read;
435 if (mb->tail == mb->bufsize) 419 if (mb->tail == mb->bufsize)
436 mb->tail = 0; 420 mb->tail = 0;
437 } else if (bytes_read == 0) { 421 } else if (bytes_read == 0) {
438 /* Record EOF condition and report to caller when buffer runs dry */ 422 /* Record EOF condition and report to caller when buffer runs dry */
439 ((PRFilePrivate *)secret)->eof = PR_TRUE; 423 ((PRFilePrivate*)secret)->eof = PR_TRUE;
440 } else /* if (bytes_read < 0) */ { 424 } else /* if (bytes_read < 0) */ {
441 mb->last_err = bytes_read; 425 mb->last_err = bytes_read;
442 } 426 }
443 } 427 }
444 428
445 int memio_GetWriteParams(memio_Private *secret, 429 int memio_GetWriteParams(memio_Private* secret,
446 const char **buf1, unsigned int *len1, 430 const char** buf1,
447 const char **buf2, unsigned int *len2) 431 unsigned int* len1,
448 { 432 const char** buf2,
449 struct memio_buffer* mb = &((PRFilePrivate *)secret)->writebuf; 433 unsigned int* len2) {
450 PR_ASSERT(mb->bufsize); 434 struct memio_buffer* mb = &((PRFilePrivate*)secret)->writebuf;
435 PR_ASSERT(mb->bufsize);
451 436
452 if (mb->last_err) 437 if (mb->last_err)
453 return mb->last_err; 438 return mb->last_err;
454 439
455 *buf1 = &mb->buf[mb->head]; 440 *buf1 = &mb->buf[mb->head];
456 *len1 = memio_buffer_used_contiguous(mb); 441 *len1 = memio_buffer_used_contiguous(mb);
457 *buf2 = mb->buf; 442 *buf2 = mb->buf;
458 *len2 = memio_buffer_wrapped_bytes(mb); 443 *len2 = memio_buffer_wrapped_bytes(mb);
459 return 0; 444 return 0;
460 } 445 }
461 446
462 void memio_PutWriteResult(memio_Private *secret, int bytes_written) 447 void memio_PutWriteResult(memio_Private* secret, int bytes_written) {
463 { 448 struct memio_buffer* mb = &((PRFilePrivate*)secret)->writebuf;
464 struct memio_buffer* mb = &((PRFilePrivate *)secret)->writebuf; 449 PR_ASSERT(mb->bufsize);
465 PR_ASSERT(mb->bufsize);
466 450
467 if (bytes_written > 0) { 451 if (bytes_written > 0) {
468 mb->head += bytes_written; 452 mb->head += bytes_written;
469 if (mb->head >= mb->bufsize) 453 if (mb->head >= mb->bufsize)
470 mb->head -= mb->bufsize; 454 mb->head -= mb->bufsize;
471 } else if (bytes_written < 0) { 455 } else if (bytes_written < 0) {
472 mb->last_err = bytes_written; 456 mb->last_err = bytes_written;
473 } 457 }
474 } 458 }
475 459
476 /*--------------- private memio_buffer self-test -----------------*/ 460 /*--------------- private memio_buffer self-test -----------------*/
477 461
478 /* Even a trivial unit test is very helpful when doing circular buffers. */ 462 /* Even a trivial unit test is very helpful when doing circular buffers. */
479 /*#define TRIVIAL_SELF_TEST*/ 463 /*#define TRIVIAL_SELF_TEST*/
480 #ifdef TRIVIAL_SELF_TEST 464 #ifdef TRIVIAL_SELF_TEST
481 #include <stdio.h> 465 #include <stdio.h>
482 466
483 #define TEST_BUFLEN 7 467 #define TEST_BUFLEN 7
484 468
485 #define CHECKEQ(a, b) { \ 469 #define CHECKEQ(a, b) \
486 if ((a) != (b)) { \ 470 { \
487 printf("%d != %d, Test failed line %d\n", a, b, __LINE__); \ 471 if ((a) != (b)) { \
488 exit(1); \ 472 printf("%d != %d, Test failed line %d\n", a, b, __LINE__); \
489 } \ 473 exit(1); \
490 } 474 } \
475 }
491 476
492 int main() 477 int main() {
493 { 478 struct memio_buffer mb;
494 struct memio_buffer mb; 479 char buf[100];
495 char buf[100]; 480 int i;
496 int i;
497 481
498 memio_buffer_new(&mb, TEST_BUFLEN); 482 memio_buffer_new(&mb, TEST_BUFLEN);
499 483
500 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1); 484 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN - 1);
501 CHECKEQ(memio_buffer_used_contiguous(&mb), 0); 485 CHECKEQ(memio_buffer_used_contiguous(&mb), 0);
502 486
503 CHECKEQ(memio_buffer_put(&mb, "howdy", 5), 5); 487 CHECKEQ(memio_buffer_put(&mb, "howdy", 5), 5);
504 488
505 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5); 489 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN - 1 - 5);
506 CHECKEQ(memio_buffer_used_contiguous(&mb), 5); 490 CHECKEQ(memio_buffer_used_contiguous(&mb), 5);
507 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0); 491 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0);
508 492
509 CHECKEQ(memio_buffer_put(&mb, "!", 1), 1); 493 CHECKEQ(memio_buffer_put(&mb, "!", 1), 1);
510 494
511 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); 495 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0);
512 CHECKEQ(memio_buffer_used_contiguous(&mb), 6); 496 CHECKEQ(memio_buffer_used_contiguous(&mb), 6);
513 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0); 497 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 0);
514 498
515 CHECKEQ(memio_buffer_get(&mb, buf, 6), 6); 499 CHECKEQ(memio_buffer_get(&mb, buf, 6), 6);
516 CHECKEQ(memcmp(buf, "howdy!", 6), 0); 500 CHECKEQ(memcmp(buf, "howdy!", 6), 0);
517 501
518 CHECKEQ(memio_buffer_unused_contiguous(&mb), 1); 502 CHECKEQ(memio_buffer_unused_contiguous(&mb), 1);
519 CHECKEQ(memio_buffer_used_contiguous(&mb), 0); 503 CHECKEQ(memio_buffer_used_contiguous(&mb), 0);
520 504
521 CHECKEQ(memio_buffer_put(&mb, "01234", 5), 5); 505 CHECKEQ(memio_buffer_put(&mb, "01234", 5), 5);
522 506
523 CHECKEQ(memio_buffer_used_contiguous(&mb), 1); 507 CHECKEQ(memio_buffer_used_contiguous(&mb), 1);
524 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 4); 508 CHECKEQ(memio_buffer_wrapped_bytes(&mb), 4);
525 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN-1-5); 509 CHECKEQ(memio_buffer_unused_contiguous(&mb), TEST_BUFLEN - 1 - 5);
526 510
527 CHECKEQ(memio_buffer_put(&mb, "5", 1), 1); 511 CHECKEQ(memio_buffer_put(&mb, "5", 1), 1);
528 512
529 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0); 513 CHECKEQ(memio_buffer_unused_contiguous(&mb), 0);
530 CHECKEQ(memio_buffer_used_contiguous(&mb), 1); 514 CHECKEQ(memio_buffer_used_contiguous(&mb), 1);
531 515
532 /* TODO: add more cases */ 516 /* TODO: add more cases */
533 517
534 printf("Test passed\n"); 518 printf("Test passed\n");
535 exit(0); 519 exit(0);
536 } 520 }
537 521
538 #endif 522 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698