Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "P_EventSystem.h"
00029
00030
00031
00032
00033 inkcoreapi Allocator ioBufAllocator[DEFAULT_BUFFER_SIZES];
00034 inkcoreapi ClassAllocator<MIOBuffer> ioAllocator("ioAllocator", DEFAULT_BUFFER_NUMBER);
00035 inkcoreapi ClassAllocator<IOBufferData> ioDataAllocator("ioDataAllocator", DEFAULT_BUFFER_NUMBER);
00036 inkcoreapi ClassAllocator<IOBufferBlock> ioBlockAllocator("ioBlockAllocator", DEFAULT_BUFFER_NUMBER);
00037 int64_t default_large_iobuffer_size = DEFAULT_LARGE_BUFFER_SIZE;
00038 int64_t default_small_iobuffer_size = DEFAULT_SMALL_BUFFER_SIZE;
00039 int64_t max_iobuffer_size = DEFAULT_BUFFER_SIZES - 1;
00040
00041
00042
00043
00044 void
00045 init_buffer_allocators()
00046 {
00047 char *name;
00048
00049 for (int i = 0; i < DEFAULT_BUFFER_SIZES; i++) {
00050 int64_t s = DEFAULT_BUFFER_BASE_SIZE * (((int64_t)1) << i);
00051 int64_t a = DEFAULT_BUFFER_ALIGNMENT;
00052 int n = i <= default_large_iobuffer_size ? DEFAULT_BUFFER_NUMBER : DEFAULT_HUGE_BUFFER_NUMBER;
00053 if (s < a)
00054 a = s;
00055
00056 name = new char[64];
00057 snprintf(name, 64, "ioBufAllocator[%d]", i);
00058 ioBufAllocator[i].re_init(name, s, n, a);
00059 }
00060 }
00061
00062 int64_t
00063 MIOBuffer::remove_append(IOBufferReader * r)
00064 {
00065 int64_t l = 0;
00066 while (r->block) {
00067 Ptr<IOBufferBlock> b = r->block;
00068 r->block = r->block->next;
00069 b->_start += r->start_offset;
00070 if (b->start() >= b->end()) {
00071 r->start_offset = -r->start_offset;
00072 continue;
00073 }
00074 r->start_offset = 0;
00075 l += b->read_avail();
00076 append_block(b);
00077 }
00078 r->mbuf->_writer = NULL;
00079 return l;
00080 }
00081
00082 int64_t
00083 MIOBuffer::write(const void *abuf, int64_t alen)
00084 {
00085 const char *buf = (const char*)abuf;
00086 int64_t len = alen;
00087 while (len) {
00088 if (!_writer)
00089 add_block();
00090 int64_t f = _writer->write_avail();
00091 f = f < len ? f : len;
00092 if (f > 0) {
00093 ::memcpy(_writer->end(), buf, f);
00094 _writer->fill(f);
00095 buf += f;
00096 len -= f;
00097 }
00098 if (len) {
00099 if (!_writer->next)
00100 add_block();
00101 else
00102 _writer = _writer->next;
00103 }
00104 }
00105 return alen;
00106 }
00107
00108
00109 #ifdef WRITE_AND_TRANSFER
00110
00111
00112
00113
00114
00115
00116 int64_t
00117 MIOBuffer::write_and_transfer_left_over_space(IOBufferReader * r, int64_t alen, int64_t offset)
00118 {
00119 int64_t rval = write(r, alen, offset);
00120
00121
00122 if (r->mbuf->_writer)
00123 r->mbuf->_writer->_buf_end = r->mbuf->_writer->_end;
00124
00125
00126 if (_writer) {
00127 _writer->_buf_end = _writer->data->data() + _writer->block_size();
00128 }
00129 return rval;
00130 }
00131
00132 #endif
00133
00134
00135 int64_t
00136 MIOBuffer::write(IOBufferReader * r, int64_t alen, int64_t offset)
00137 {
00138 int64_t len = alen;
00139 IOBufferBlock *b = r->block;
00140 offset += r->start_offset;
00141
00142 while (b && len > 0) {
00143 int64_t max_bytes = b->read_avail();
00144 max_bytes -= offset;
00145 if (max_bytes <= 0) {
00146 offset = -max_bytes;
00147 b = b->next;
00148 continue;
00149 }
00150 int64_t bytes;
00151 if (len<0 || len>= max_bytes)
00152 bytes = max_bytes;
00153 else
00154 bytes = len;
00155 IOBufferBlock *bb = b->clone();
00156 bb->_start += offset;
00157 bb->_buf_end = bb->_end = bb->_start + bytes;
00158 append_block(bb);
00159 offset = 0;
00160 len -= bytes;
00161 b = b->next;
00162 }
00163 return alen - len;
00164 }
00165
00166 int64_t
00167 MIOBuffer::puts(char *s, int64_t len)
00168 {
00169 char *pc = end();
00170 char *pb = s;
00171 while (pc < buf_end()) {
00172 if (len-- <= 0)
00173 return -1;
00174 if (!*pb || *pb == '\n') {
00175 int64_t n = (int64_t) (pb - s);
00176 memcpy(end(), s, n + 1);
00177 end()[n + 1] = 0;
00178 fill(n + 1);
00179 return n + 1;
00180 }
00181 pc++;
00182 pb++;
00183 }
00184 return 0;
00185 }
00186
00187 int64_t
00188 IOBufferReader::read(void *ab, int64_t len)
00189 {
00190 char *b = (char*)ab;
00191 int64_t max_bytes = read_avail();
00192 int64_t bytes = len <= max_bytes ? len : max_bytes;
00193 int64_t n = bytes;
00194
00195 while (n) {
00196 int64_t l = block_read_avail();
00197 if (n < l)
00198 l = n;
00199 ::memcpy(b, start(), l);
00200 consume(l);
00201 b += l;
00202 n -= l;
00203 }
00204 return bytes;
00205 }
00206
00207
00208 int64_t
00209 IOBufferReader::memchr(char c, int64_t len, int64_t offset)
00210 {
00211 IOBufferBlock *b = block;
00212 offset += start_offset;
00213 int64_t o = offset;
00214
00215 while (b && len) {
00216 int64_t max_bytes = b->read_avail();
00217 max_bytes -= offset;
00218 if (max_bytes <= 0) {
00219 offset = -max_bytes;
00220 b = b->next;
00221 continue;
00222 }
00223 int64_t bytes;
00224 if (len<0 || len>= max_bytes)
00225 bytes = max_bytes;
00226 else
00227 bytes = len;
00228 char *s = b->start() + offset;
00229 char *p = (char *) ::memchr(s, c, bytes);
00230 if (p)
00231 return (int64_t) (o - start_offset + p - s);
00232 o += bytes;
00233 len -= bytes;
00234 b = b->next;
00235 offset = 0;
00236 }
00237
00238 return -1;
00239 }
00240
00241 char *
00242 IOBufferReader::memcpy(const void *ap, int64_t len, int64_t offset)
00243 {
00244 char *p = (char*)ap;
00245 IOBufferBlock *b = block;
00246 offset += start_offset;
00247
00248 while (b && len) {
00249 int64_t max_bytes = b->read_avail();
00250 max_bytes -= offset;
00251 if (max_bytes <= 0) {
00252 offset = -max_bytes;
00253 b = b->next;
00254 continue;
00255 }
00256 int64_t bytes;
00257 if (len<0 || len>= max_bytes)
00258 bytes = max_bytes;
00259 else
00260 bytes = len;
00261 ::memcpy(p, b->start() + offset, bytes);
00262 p += bytes;
00263 len -= bytes;
00264 b = b->next;
00265 offset = 0;
00266 }
00267
00268 return p;
00269 }