Change many files to new log_fn format
[tor.git] / src / or / buffers.c
blobb179405284a85571a4ff6cc47c0bb9d38e545823
1 /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
3 /* $Id$ */
5 /* buffers.c */
7 #include "or.h"
9 extern or_options_t options; /* command-line and config-file options */
11 /* Create a new buf of size MAX_BUF_SIZE. Write a pointer to it
12 * into *buf, write MAX_BUF_SIZE into *buflen, and initialize
13 * *buf_datalen to 0. Return 0.
15 int buf_new(char **buf, int *buflen, int *buf_datalen) {
17 assert(buf && buflen && buf_datalen);
19 *buf = (char *)tor_malloc(MAX_BUF_SIZE);
20 // memset(*buf,0,MAX_BUF_SIZE);
21 *buflen = MAX_BUF_SIZE;
22 *buf_datalen = 0;
24 return 0;
27 void buf_free(char *buf) {
28 free(buf);
31 /* read from socket s, writing onto buf+buf_datalen. If at_most is >= 0 then
32 * read at most 'at_most' bytes, and in any case don't read more than will fit based on buflen.
33 * If read() returns 0, set *reached_eof to 1 and return 0. If you want to tear
34 * down the connection return -1, else return the number of bytes read.
36 int read_to_buf(int s, int at_most, char **buf, int *buflen, int *buf_datalen, int *reached_eof) {
38 int read_result;
40 assert(buf && *buf && buflen && buf_datalen && reached_eof && (s>=0));
42 /* this is the point where you would grow the buffer, if you want to */
44 if(at_most < 0 || *buflen - *buf_datalen < at_most)
45 at_most = *buflen - *buf_datalen; /* take the min of the two */
46 /* (note that this only modifies at_most inside this function) */
48 if(at_most == 0)
49 return 0; /* we shouldn't read anything */
51 if(!options.LinkPadding && at_most > 10*sizeof(cell_t)) {
52 /* if no linkpadding: do a rudimentary round-robin so one
53 * connection can't hog a thickpipe
55 at_most = 10*(CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE);
56 /* XXX this still isn't perfect. now we read 10 relay data payloads per read --
57 * but if we're reading from a connection that speaks cells, we always
58 * read a partial cell from the network and can't process it yet. Good
59 * enough for now though. (And maybe best, to stress our code more.)
63 // log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most);
64 read_result = read(s, *buf+*buf_datalen, at_most);
65 if (read_result < 0) {
66 if(errno!=EAGAIN) { /* it's a real error */
67 return -1;
69 return 0;
70 } else if (read_result == 0) {
71 log_fn(LOG_DEBUG,"Encountered eof");
72 *reached_eof = 1;
73 return 0;
74 } else { /* we read some bytes */
75 *buf_datalen += read_result;
76 // log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result, *buf_datalen);
77 return read_result;
81 int flush_buf(int s, char **buf, int *buflen, int *buf_flushlen, int *buf_datalen) {
83 /* push from buf onto s
84 * then memmove to front of buf
85 * return -1 or how many bytes remain to be flushed */
87 int write_result;
89 assert(buf && *buf && buflen && buf_flushlen && buf_datalen && (s>=0) && (*buf_flushlen <= *buf_datalen));
91 if(*buf_flushlen == 0) /* nothing to flush */
92 return 0;
94 /* this is the point where you would grow the buffer, if you want to */
96 write_result = write(s, *buf, *buf_flushlen);
97 if (write_result < 0) {
98 if(errno!=EAGAIN) { /* it's a real error */
99 return -1;
101 log_fn(LOG_DEBUG,"write() would block, returning.");
102 return 0;
103 } else {
104 *buf_datalen -= write_result;
105 *buf_flushlen -= write_result;
106 memmove(*buf, *buf+write_result, *buf_datalen);
107 // log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
108 // write_result,*buf_flushlen,*buf_datalen);
109 return *buf_flushlen;
113 int write_to_buf(char *string, int string_len,
114 char **buf, int *buflen, int *buf_datalen) {
116 /* append string to buf (growing as needed, return -1 if "too big")
117 * return total number of bytes on the buf
120 assert(string && buf && *buf && buflen && buf_datalen);
122 /* this is the point where you would grow the buffer, if you want to */
124 if (string_len + *buf_datalen > *buflen) { /* we're out of luck */
125 log_fn(LOG_DEBUG, "buflen too small. Time to implement growing dynamic bufs.");
126 return -1;
129 memcpy(*buf+*buf_datalen, string, string_len);
130 *buf_datalen += string_len;
131 // log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",string_len, *buf_datalen);
132 return *buf_datalen;
135 int fetch_from_buf(char *string, int string_len,
136 char **buf, int *buflen, int *buf_datalen) {
138 /* if there are string_len bytes in buf, write them onto string,
139 * then memmove buf back (that is, remove them from buf).
141 * If there are not enough bytes on the buffer to fill string, return -1.
143 * Return the number of bytes still on the buffer. */
145 assert(string && buf && *buf && buflen && buf_datalen);
147 /* this is the point where you would grow the buffer, if you want to */
149 if(string_len > *buf_datalen) /* we want too much. sorry. */
150 return -1;
152 memcpy(string,*buf,string_len);
153 *buf_datalen -= string_len;
154 memmove(*buf, *buf+string_len, *buf_datalen);
155 return *buf_datalen;
158 int find_on_inbuf(char *string, int string_len,
159 char *buf, int buf_datalen) {
160 /* find first instance of needle 'string' on haystack 'buf'. return how
161 * many bytes from the beginning of buf to the end of string.
162 * If it's not there, return -1.
165 char *location;
166 char *last_possible = buf + buf_datalen - string_len;
168 assert(string && string_len > 0 && buf);
170 if(buf_datalen < string_len)
171 return -1;
173 for(location = buf; location <= last_possible; location++)
174 if((*location == *string) && !memcmp(location+1, string+1, string_len-1))
175 return location-buf+string_len;
177 return -1;
181 Local Variables:
182 mode:c
183 indent-tabs-mode:nil
184 c-basic-offset:2
185 End: