00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <isc/buffer.h>
00023 #include <isc/mem.h>
00024 #include <isc/region.h>
00025 #include <isc/string.h>
00026 #include <isc/util.h>
00027
00028 void
00029 isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
00030
00031
00032
00033
00034
00035 REQUIRE(b != NULL);
00036
00037 ISC__BUFFER_INIT(b, base, length);
00038 }
00039
00040 void
00041 isc__buffer_initnull(isc_buffer_t *b) {
00042
00043
00044
00045
00046
00047 ISC__BUFFER_INIT(b, NULL, 0);
00048 }
00049
00050 void
00051 isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 REQUIRE(b->length <= length);
00062 REQUIRE(base != NULL);
00063
00064 (void)memmove(base, b->base, b->length);
00065 b->base = base;
00066 b->length = length;
00067 }
00068
00069 void
00070 isc__buffer_invalidate(isc_buffer_t *b) {
00071
00072
00073
00074
00075 REQUIRE(ISC_BUFFER_VALID(b));
00076 REQUIRE(!ISC_LINK_LINKED(b, link));
00077 REQUIRE(b->mctx == NULL);
00078
00079 ISC__BUFFER_INVALIDATE(b);
00080 }
00081
00082 void
00083 isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
00084
00085
00086
00087
00088 REQUIRE(ISC_BUFFER_VALID(b));
00089 REQUIRE(r != NULL);
00090
00091 ISC__BUFFER_REGION(b, r);
00092 }
00093
00094 void
00095 isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
00096
00097
00098
00099
00100 REQUIRE(ISC_BUFFER_VALID(b));
00101 REQUIRE(r != NULL);
00102
00103 ISC__BUFFER_USEDREGION(b, r);
00104 }
00105
00106 void
00107 isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
00108
00109
00110
00111
00112 REQUIRE(ISC_BUFFER_VALID(b));
00113 REQUIRE(r != NULL);
00114
00115 ISC__BUFFER_AVAILABLEREGION(b, r);
00116 }
00117
00118 void
00119 isc__buffer_add(isc_buffer_t *b, unsigned int n) {
00120
00121
00122
00123
00124 REQUIRE(ISC_BUFFER_VALID(b));
00125 REQUIRE(b->used + n <= b->length);
00126
00127 ISC__BUFFER_ADD(b, n);
00128 }
00129
00130 void
00131 isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
00132
00133
00134
00135
00136 REQUIRE(ISC_BUFFER_VALID(b));
00137 REQUIRE(b->used >= n);
00138
00139 ISC__BUFFER_SUBTRACT(b, n);
00140 }
00141
00142 void
00143 isc__buffer_clear(isc_buffer_t *b) {
00144
00145
00146
00147
00148 REQUIRE(ISC_BUFFER_VALID(b));
00149
00150 ISC__BUFFER_CLEAR(b);
00151 }
00152
00153 void
00154 isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) {
00155
00156
00157
00158
00159 REQUIRE(ISC_BUFFER_VALID(b));
00160 REQUIRE(r != NULL);
00161
00162 ISC__BUFFER_CONSUMEDREGION(b, r);
00163 }
00164
00165 void
00166 isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
00167
00168
00169
00170
00171 REQUIRE(ISC_BUFFER_VALID(b));
00172 REQUIRE(r != NULL);
00173
00174 ISC__BUFFER_REMAININGREGION(b, r);
00175 }
00176
00177 void
00178 isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
00179
00180
00181
00182
00183 REQUIRE(ISC_BUFFER_VALID(b));
00184 REQUIRE(r != NULL);
00185
00186 ISC__BUFFER_ACTIVEREGION(b, r);
00187 }
00188
00189 void
00190 isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
00191
00192
00193
00194
00195 REQUIRE(ISC_BUFFER_VALID(b));
00196 REQUIRE(b->current + n <= b->used);
00197
00198 ISC__BUFFER_SETACTIVE(b, n);
00199 }
00200
00201 void
00202 isc__buffer_first(isc_buffer_t *b) {
00203
00204
00205
00206
00207 REQUIRE(ISC_BUFFER_VALID(b));
00208
00209 ISC__BUFFER_FIRST(b);
00210 }
00211
00212 void
00213 isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
00214
00215
00216
00217
00218 REQUIRE(ISC_BUFFER_VALID(b));
00219 REQUIRE(b->current + n <= b->used);
00220
00221 ISC__BUFFER_FORWARD(b, n);
00222 }
00223
00224 void
00225 isc__buffer_back(isc_buffer_t *b, unsigned int n) {
00226
00227
00228
00229
00230 REQUIRE(ISC_BUFFER_VALID(b));
00231 REQUIRE(n <= b->current);
00232
00233 ISC__BUFFER_BACK(b, n);
00234 }
00235
00236 void
00237 isc_buffer_compact(isc_buffer_t *b) {
00238 unsigned int length;
00239 void *src;
00240
00241
00242
00243
00244
00245
00246
00247 REQUIRE(ISC_BUFFER_VALID(b));
00248
00249 src = isc_buffer_current(b);
00250 length = isc_buffer_remaininglength(b);
00251 (void)memmove(b->base, src, (size_t)length);
00252
00253 if (b->active > b->current)
00254 b->active -= b->current;
00255 else
00256 b->active = 0;
00257 b->current = 0;
00258 b->used = length;
00259 }
00260
00261 isc_uint8_t
00262 isc_buffer_getuint8(isc_buffer_t *b) {
00263 unsigned char *cp;
00264 isc_uint8_t result;
00265
00266
00267
00268
00269
00270 REQUIRE(ISC_BUFFER_VALID(b));
00271 REQUIRE(b->used - b->current >= 1);
00272
00273 cp = isc_buffer_current(b);
00274 b->current += 1;
00275 result = ((isc_uint8_t)(cp[0]));
00276
00277 return (result);
00278 }
00279
00280 void
00281 isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
00282 REQUIRE(ISC_BUFFER_VALID(b));
00283 REQUIRE(b->used + 1 <= b->length);
00284
00285 ISC__BUFFER_PUTUINT8(b, val);
00286 }
00287
00288 isc_uint16_t
00289 isc_buffer_getuint16(isc_buffer_t *b) {
00290 unsigned char *cp;
00291 isc_uint16_t result;
00292
00293
00294
00295
00296
00297
00298 REQUIRE(ISC_BUFFER_VALID(b));
00299 REQUIRE(b->used - b->current >= 2);
00300
00301 cp = isc_buffer_current(b);
00302 b->current += 2;
00303 result = ((unsigned int)(cp[0])) << 8;
00304 result |= ((unsigned int)(cp[1]));
00305
00306 return (result);
00307 }
00308
00309 void
00310 isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
00311 REQUIRE(ISC_BUFFER_VALID(b));
00312 REQUIRE(b->used + 2 <= b->length);
00313
00314 ISC__BUFFER_PUTUINT16(b, val);
00315 }
00316
00317 void
00318 isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
00319 REQUIRE(ISC_BUFFER_VALID(b));
00320 REQUIRE(b->used + 3 <= b->length);
00321
00322 ISC__BUFFER_PUTUINT24(b, val);
00323 }
00324
00325 isc_uint32_t
00326 isc_buffer_getuint32(isc_buffer_t *b) {
00327 unsigned char *cp;
00328 isc_uint32_t result;
00329
00330
00331
00332
00333
00334
00335 REQUIRE(ISC_BUFFER_VALID(b));
00336 REQUIRE(b->used - b->current >= 4);
00337
00338 cp = isc_buffer_current(b);
00339 b->current += 4;
00340 result = ((unsigned int)(cp[0])) << 24;
00341 result |= ((unsigned int)(cp[1])) << 16;
00342 result |= ((unsigned int)(cp[2])) << 8;
00343 result |= ((unsigned int)(cp[3]));
00344
00345 return (result);
00346 }
00347
00348 void
00349 isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
00350 REQUIRE(ISC_BUFFER_VALID(b));
00351 REQUIRE(b->used + 4 <= b->length);
00352
00353 ISC__BUFFER_PUTUINT32(b, val);
00354 }
00355
00356 isc_uint64_t
00357 isc_buffer_getuint48(isc_buffer_t *b) {
00358 unsigned char *cp;
00359 isc_uint64_t result;
00360
00361
00362
00363
00364
00365
00366 REQUIRE(ISC_BUFFER_VALID(b));
00367 REQUIRE(b->used - b->current >= 6);
00368
00369 cp = isc_buffer_current(b);
00370 b->current += 6;
00371 result = ((isc_int64_t)(cp[0])) << 40;
00372 result |= ((isc_int64_t)(cp[1])) << 32;
00373 result |= ((isc_int64_t)(cp[2])) << 24;
00374 result |= ((isc_int64_t)(cp[3])) << 16;
00375 result |= ((isc_int64_t)(cp[4])) << 8;
00376 result |= ((isc_int64_t)(cp[5]));
00377
00378 return (result);
00379 }
00380
00381 void
00382 isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
00383 isc_uint16_t valhi;
00384 isc_uint32_t vallo;
00385
00386 REQUIRE(ISC_BUFFER_VALID(b));
00387 REQUIRE(b->used + 6 <= b->length);
00388
00389 valhi = (isc_uint16_t)(val >> 32);
00390 vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
00391 ISC__BUFFER_PUTUINT16(b, valhi);
00392 ISC__BUFFER_PUTUINT32(b, vallo);
00393 }
00394
00395 void
00396 isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
00397 unsigned int length)
00398 {
00399 REQUIRE(ISC_BUFFER_VALID(b));
00400 REQUIRE(b->used + length <= b->length);
00401
00402 ISC__BUFFER_PUTMEM(b, base, length);
00403 }
00404
00405 void
00406 isc__buffer_putstr(isc_buffer_t *b, const char *source) {
00407 unsigned int l;
00408 unsigned char *cp;
00409
00410 REQUIRE(ISC_BUFFER_VALID(b));
00411 REQUIRE(source != NULL);
00412
00413
00414
00415
00416 l = strlen(source);
00417
00418 REQUIRE(l <= isc_buffer_availablelength(b));
00419
00420 cp = isc_buffer_used(b);
00421 memmove(cp, source, l);
00422 b->used += l;
00423 }
00424
00425 isc_result_t
00426 isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
00427 unsigned char *base;
00428 unsigned int available;
00429
00430 REQUIRE(ISC_BUFFER_VALID(b));
00431 REQUIRE(r != NULL);
00432
00433
00434
00435
00436 base = isc_buffer_used(b);
00437 available = isc_buffer_availablelength(b);
00438 if (r->length > available)
00439 return (ISC_R_NOSPACE);
00440 memmove(base, r->base, r->length);
00441 b->used += r->length;
00442
00443 return (ISC_R_SUCCESS);
00444 }
00445
00446 isc_result_t
00447 isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
00448 unsigned int length)
00449 {
00450 isc_buffer_t *dbuf;
00451
00452 REQUIRE(dynbuffer != NULL);
00453 REQUIRE(*dynbuffer == NULL);
00454
00455 dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t));
00456 if (dbuf == NULL)
00457 return (ISC_R_NOMEMORY);
00458
00459 isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
00460 length);
00461 dbuf->mctx = mctx;
00462
00463 *dynbuffer = dbuf;
00464
00465 return (ISC_R_SUCCESS);
00466 }
00467
00468 isc_result_t
00469 isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
00470 isc_buffer_t *dbuf;
00471
00472 REQUIRE(dynbuffer != NULL);
00473 REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
00474 REQUIRE((*dynbuffer)->mctx != NULL);
00475
00476 if ((*dynbuffer)->length > length)
00477 return (ISC_R_NOSPACE);
00478
00479
00480
00481
00482
00483
00484 dbuf = isc_mem_get((*dynbuffer)->mctx, length + sizeof(isc_buffer_t));
00485 if (dbuf == NULL)
00486 return (ISC_R_NOMEMORY);
00487
00488 memmove(dbuf, *dynbuffer, (*dynbuffer)->length + sizeof(isc_buffer_t));
00489 isc_mem_put(dbuf->mctx, *dynbuffer,
00490 (*dynbuffer)->length + sizeof(isc_buffer_t));
00491
00492 dbuf->base = ((unsigned char *)dbuf) + sizeof(isc_buffer_t);
00493 dbuf->length = length;
00494
00495 INSIST(ISC_BUFFER_VALID(dbuf));
00496
00497 *dynbuffer = dbuf;
00498
00499 return (ISC_R_SUCCESS);
00500 }
00501
00502 isc_result_t
00503 isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) {
00504 isc_uint64_t len;
00505
00506 REQUIRE(dynbuffer != NULL);
00507 REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
00508
00509 len = (*dynbuffer)->length;
00510 if ((len - (*dynbuffer)->used) >= size)
00511 return (ISC_R_SUCCESS);
00512
00513 if ((*dynbuffer)->mctx == NULL)
00514 return (ISC_R_NOSPACE);
00515
00516
00517 len = size + (*dynbuffer)->used;
00518 len = (len + ISC_BUFFER_INCR - 1 - ((len - 1) % ISC_BUFFER_INCR));
00519
00520
00521 if (len > UINT_MAX) {
00522 len = UINT_MAX;
00523 }
00524
00525 if ((len - (*dynbuffer)->used) < size)
00526 return (ISC_R_NOMEMORY);
00527
00528 return (isc_buffer_reallocate(dynbuffer, (unsigned int) len));
00529 }
00530
00531 void
00532 isc_buffer_free(isc_buffer_t **dynbuffer) {
00533 unsigned int real_length;
00534 isc_buffer_t *dbuf;
00535 isc_mem_t *mctx;
00536
00537 REQUIRE(dynbuffer != NULL);
00538 REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
00539 REQUIRE((*dynbuffer)->mctx != NULL);
00540
00541 dbuf = *dynbuffer;
00542 *dynbuffer = NULL;
00543
00544 real_length = dbuf->length + sizeof(isc_buffer_t);
00545 mctx = dbuf->mctx;
00546 dbuf->mctx = NULL;
00547 isc_buffer_invalidate(dbuf);
00548
00549 isc_mem_put(mctx, dbuf, real_length);
00550 }