1 /* 2 * buffer.h -- generic memory buffer. 3 * 4 * Copyright (c) 2005-2008, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 * 9 * The buffer module implements a generic buffer. The API is based on 10 * the java.nio.Buffer interface. 11 */ 12 13 #ifndef LDNS_SBUFFER_H 14 #define LDNS_SBUFFER_H 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #ifdef S_SPLINT_S 21 # define INLINE 22 #else 23 # ifdef SWIG 24 # define INLINE static 25 # else 26 # define INLINE static inline 27 # endif 28 #endif 29 30 /* 31 * Copy data allowing for unaligned accesses in network byte order 32 * (big endian). 33 */ 34 INLINE uint16_t 35 sldns_read_uint16(const void *src) 36 { 37 #ifdef ALLOW_UNALIGNED_ACCESSES 38 return ntohs(*(const uint16_t *) src); 39 #else 40 const uint8_t *p = (const uint8_t *) src; 41 return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; 42 #endif 43 } 44 45 INLINE uint32_t 46 sldns_read_uint32(const void *src) 47 { 48 #ifdef ALLOW_UNALIGNED_ACCESSES 49 return ntohl(*(const uint32_t *) src); 50 #else 51 const uint8_t *p = (const uint8_t *) src; 52 return ( ((uint32_t) p[0] << 24) 53 | ((uint32_t) p[1] << 16) 54 | ((uint32_t) p[2] << 8) 55 | (uint32_t) p[3]); 56 #endif 57 } 58 59 /* 60 * Copy data allowing for unaligned accesses in network byte order 61 * (big endian). 62 */ 63 INLINE void 64 sldns_write_uint16(void *dst, uint16_t data) 65 { 66 #ifdef ALLOW_UNALIGNED_ACCESSES 67 * (uint16_t *) dst = htons(data); 68 #else 69 uint8_t *p = (uint8_t *) dst; 70 p[0] = (uint8_t) ((data >> 8) & 0xff); 71 p[1] = (uint8_t) (data & 0xff); 72 #endif 73 } 74 75 INLINE void 76 sldns_write_uint32(void *dst, uint32_t data) 77 { 78 #ifdef ALLOW_UNALIGNED_ACCESSES 79 * (uint32_t *) dst = htonl(data); 80 #else 81 uint8_t *p = (uint8_t *) dst; 82 p[0] = (uint8_t) ((data >> 24) & 0xff); 83 p[1] = (uint8_t) ((data >> 16) & 0xff); 84 p[2] = (uint8_t) ((data >> 8) & 0xff); 85 p[3] = (uint8_t) (data & 0xff); 86 #endif 87 } 88 89 90 INLINE void 91 sldns_write_uint48(void *dst, uint64_t data) 92 { 93 uint8_t *p = (uint8_t *) dst; 94 p[0] = (uint8_t) ((data >> 40) & 0xff); 95 p[1] = (uint8_t) ((data >> 32) & 0xff); 96 p[2] = (uint8_t) ((data >> 24) & 0xff); 97 p[3] = (uint8_t) ((data >> 16) & 0xff); 98 p[4] = (uint8_t) ((data >> 8) & 0xff); 99 p[5] = (uint8_t) (data & 0xff); 100 } 101 102 103 /** 104 * \file sbuffer.h 105 * 106 * This file contains the definition of sldns_buffer, and functions to manipulate those. 107 */ 108 109 /** 110 * implementation of buffers to ease operations 111 * 112 * sldns_buffers can contain arbitrary information, per octet. You can write 113 * to the current end of a buffer, read from the current position, and 114 * access any data within it. 115 */ 116 struct sldns_buffer 117 { 118 /** The current position used for reading/writing */ 119 size_t _position; 120 121 /** The read/write limit */ 122 size_t _limit; 123 124 /** The amount of data the buffer can contain */ 125 size_t _capacity; 126 127 /** The data contained in the buffer */ 128 uint8_t *_data; 129 130 /** If the buffer is fixed it cannot be resized */ 131 unsigned _fixed : 1; 132 133 /** If the buffer is vfixed, no more than capacity bytes willl be 134 * written to _data, however the _position counter will be updated 135 * with the amount that would have been written in consecutive 136 * writes. This allows for a modus operandi in which a sequence is 137 * written on a fixed capacity buffer (perhaps with _data on stack). 138 * When everything could be written, then the _data is immediately 139 * usable, if not, then a buffer could be allocated sized precisely 140 * to fit the data for a second attempt. 141 */ 142 unsigned _vfixed : 1; 143 144 /** The current state of the buffer. If writing to the buffer fails 145 * for any reason, this value is changed. This way, you can perform 146 * multiple writes in sequence and check for success afterwards. */ 147 unsigned _status_err : 1; 148 }; 149 typedef struct sldns_buffer sldns_buffer; 150 151 #ifdef NDEBUG 152 INLINE void 153 sldns_buffer_invariant(sldns_buffer *ATTR_UNUSED(buffer)) 154 { 155 } 156 #else 157 INLINE void 158 sldns_buffer_invariant(sldns_buffer *buffer) 159 { 160 assert(buffer != NULL); 161 assert(buffer->_position <= buffer->_limit || buffer->_vfixed); 162 assert(buffer->_limit <= buffer->_capacity); 163 assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0)); 164 } 165 #endif 166 167 /** 168 * creates a new buffer with the specified capacity. 169 * 170 * \param[in] capacity the size (in bytes) to allocate for the buffer 171 * \return the created buffer 172 */ 173 sldns_buffer *sldns_buffer_new(size_t capacity); 174 175 /** 176 * creates a buffer with the specified data. The data IS copied 177 * and MEMORY allocations are done. The buffer is not fixed and can 178 * be resized using buffer_reserve(). 179 * 180 * \param[in] buffer pointer to the buffer to put the data in 181 * \param[in] data the data to encapsulate in the buffer 182 * \param[in] size the size of the data 183 */ 184 void sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size); 185 186 /** 187 * Setup a buffer with the data pointed to. No data copied, no memory allocs. 188 * The buffer is fixed. 189 * \param[in] buffer pointer to the buffer to put the data in 190 * \param[in] data the data to encapsulate in the buffer 191 * \param[in] size the size of the data 192 */ 193 void sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size); 194 195 /** 196 * Setup a buffer with the data pointed to. No data copied, no memory allocs. 197 * The buffer is "virtually" fixed. Writes beyond size (the capacity) will 198 * only update position, but no data will be written beyond capacity. This 199 * allows to determine how big the buffer should have been to contain all the 200 * written data, by looking at the position with sldns_buffer_position(), 201 * similarly to the return value of POSIX's snprintf. 202 * \param[in] buffer pointer to the buffer to put the data in 203 * \param[in] data the data to encapsulate in the buffer 204 * \param[in] size the size of the data 205 */ 206 void sldns_buffer_init_vfixed_frm_data(sldns_buffer *buffer, void *data, size_t size); 207 208 /** 209 * clears the buffer and make it ready for writing. The buffer's limit 210 * is set to the capacity and the position is set to 0. 211 * \param[in] buffer the buffer to clear 212 */ 213 INLINE void sldns_buffer_clear(sldns_buffer *buffer) 214 { 215 sldns_buffer_invariant(buffer); 216 217 /* reset status here? */ 218 219 buffer->_position = 0; 220 buffer->_limit = buffer->_capacity; 221 } 222 223 /** 224 * makes the buffer ready for reading the data that has been written to 225 * the buffer. The buffer's limit is set to the current position and 226 * the position is set to 0. 227 * 228 * \param[in] buffer the buffer to flip 229 * \return void 230 */ 231 INLINE void sldns_buffer_flip(sldns_buffer *buffer) 232 { 233 sldns_buffer_invariant(buffer); 234 235 buffer->_limit = buffer->_position; 236 buffer->_position = 0; 237 } 238 239 /** 240 * make the buffer ready for re-reading the data. The buffer's 241 * position is reset to 0. 242 * \param[in] buffer the buffer to rewind 243 */ 244 INLINE void sldns_buffer_rewind(sldns_buffer *buffer) 245 { 246 sldns_buffer_invariant(buffer); 247 248 buffer->_position = 0; 249 } 250 251 /** 252 * returns the current position in the buffer (as a number of bytes) 253 * \param[in] buffer the buffer 254 * \return the current position 255 */ 256 INLINE size_t 257 sldns_buffer_position(sldns_buffer *buffer) 258 { 259 return buffer->_position; 260 } 261 262 /** 263 * sets the buffer's position to MARK. The position must be less than 264 * or equal to the buffer's limit. 265 * \param[in] buffer the buffer 266 * \param[in] mark the mark to use 267 */ 268 INLINE void 269 sldns_buffer_set_position(sldns_buffer *buffer, size_t mark) 270 { 271 assert(mark <= buffer->_limit || buffer->_vfixed); 272 buffer->_position = mark; 273 } 274 275 /** 276 * changes the buffer's position by COUNT bytes. The position must not 277 * be moved behind the buffer's limit or before the beginning of the 278 * buffer. 279 * \param[in] buffer the buffer 280 * \param[in] count the count to use 281 */ 282 INLINE void 283 sldns_buffer_skip(sldns_buffer *buffer, ssize_t count) 284 { 285 assert(buffer->_position + count <= buffer->_limit || buffer->_vfixed); 286 buffer->_position += count; 287 } 288 289 /** 290 * returns the maximum size of the buffer 291 * \param[in] buffer 292 * \return the size 293 */ 294 INLINE size_t 295 sldns_buffer_limit(sldns_buffer *buffer) 296 { 297 return buffer->_limit; 298 } 299 300 /** 301 * changes the buffer's limit. If the buffer's position is greater 302 * than the new limit the position is set to the limit. 303 * \param[in] buffer the buffer 304 * \param[in] limit the new limit 305 */ 306 INLINE void 307 sldns_buffer_set_limit(sldns_buffer *buffer, size_t limit) 308 { 309 assert(limit <= buffer->_capacity); 310 buffer->_limit = limit; 311 if (buffer->_position > buffer->_limit) 312 buffer->_position = buffer->_limit; 313 } 314 315 /** 316 * returns the number of bytes the buffer can hold. 317 * \param[in] buffer the buffer 318 * \return the number of bytes 319 */ 320 INLINE size_t 321 sldns_buffer_capacity(sldns_buffer *buffer) 322 { 323 return buffer->_capacity; 324 } 325 326 /** 327 * changes the buffer's capacity. The data is reallocated so any 328 * pointers to the data may become invalid. The buffer's limit is set 329 * to the buffer's new capacity. 330 * \param[in] buffer the buffer 331 * \param[in] capacity the capacity to use 332 * \return whether this failed or succeeded 333 */ 334 int sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity); 335 336 /** 337 * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's 338 * capacity is increased if necessary using buffer_set_capacity(). 339 * 340 * The buffer's limit is always set to the (possibly increased) 341 * capacity. 342 * \param[in] buffer the buffer 343 * \param[in] amount amount to use 344 * \return whether this failed or succeeded 345 */ 346 int sldns_buffer_reserve(sldns_buffer *buffer, size_t amount); 347 348 /** 349 * returns a pointer to the data at the indicated position. 350 * \param[in] buffer the buffer 351 * \param[in] at position 352 * \return the pointer to the data 353 */ 354 INLINE uint8_t * 355 sldns_buffer_at(const sldns_buffer *buffer, size_t at) 356 { 357 assert(at <= buffer->_limit || buffer->_vfixed); 358 return buffer->_data + at; 359 } 360 361 /** 362 * returns a pointer to the beginning of the buffer (the data at 363 * position 0). 364 * \param[in] buffer the buffer 365 * \return the pointer 366 */ 367 INLINE uint8_t * 368 sldns_buffer_begin(const sldns_buffer *buffer) 369 { 370 return sldns_buffer_at(buffer, 0); 371 } 372 373 /** 374 * returns a pointer to the end of the buffer (the data at the buffer's 375 * limit). 376 * \param[in] buffer the buffer 377 * \return the pointer 378 */ 379 INLINE uint8_t * 380 sldns_buffer_end(sldns_buffer *buffer) 381 { 382 return sldns_buffer_at(buffer, buffer->_limit); 383 } 384 385 /** 386 * returns a pointer to the data at the buffer's current position. 387 * \param[in] buffer the buffer 388 * \return the pointer 389 */ 390 INLINE uint8_t * 391 sldns_buffer_current(sldns_buffer *buffer) 392 { 393 return sldns_buffer_at(buffer, buffer->_position); 394 } 395 396 /** 397 * returns the number of bytes remaining between the indicated position and 398 * the limit. 399 * \param[in] buffer the buffer 400 * \param[in] at indicated position 401 * \return number of bytes 402 */ 403 INLINE size_t 404 sldns_buffer_remaining_at(sldns_buffer *buffer, size_t at) 405 { 406 sldns_buffer_invariant(buffer); 407 assert(at <= buffer->_limit || buffer->_vfixed); 408 return at < buffer->_limit ? buffer->_limit - at : 0; 409 } 410 411 /** 412 * returns the number of bytes remaining between the buffer's position and 413 * limit. 414 * \param[in] buffer the buffer 415 * \return the number of bytes 416 */ 417 INLINE size_t 418 sldns_buffer_remaining(sldns_buffer *buffer) 419 { 420 return sldns_buffer_remaining_at(buffer, buffer->_position); 421 } 422 423 /** 424 * checks if the buffer has at least COUNT more bytes available. 425 * Before reading or writing the caller needs to ensure enough space 426 * is available! 427 * \param[in] buffer the buffer 428 * \param[in] at indicated position 429 * \param[in] count how much is available 430 * \return true or false (as int?) 431 */ 432 INLINE int 433 sldns_buffer_available_at(sldns_buffer *buffer, size_t at, size_t count) 434 { 435 return count <= sldns_buffer_remaining_at(buffer, at); 436 } 437 438 /** 439 * checks if the buffer has count bytes available at the current position 440 * \param[in] buffer the buffer 441 * \param[in] count how much is available 442 * \return true or false (as int?) 443 */ 444 INLINE int 445 sldns_buffer_available(sldns_buffer *buffer, size_t count) 446 { 447 return sldns_buffer_available_at(buffer, buffer->_position, count); 448 } 449 450 /** 451 * writes the given data to the buffer at the specified position 452 * \param[in] buffer the buffer 453 * \param[in] at the position (in number of bytes) to write the data at 454 * \param[in] data pointer to the data to write to the buffer 455 * \param[in] count the number of bytes of data to write 456 */ 457 INLINE void 458 sldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count) 459 { 460 if (!buffer->_vfixed) 461 assert(sldns_buffer_available_at(buffer, at, count)); 462 else if (sldns_buffer_remaining_at(buffer, at) == 0) 463 return; 464 else if (count > sldns_buffer_remaining_at(buffer, at)) { 465 memcpy(buffer->_data + at, data, 466 sldns_buffer_remaining_at(buffer, at)); 467 return; 468 } 469 memcpy(buffer->_data + at, data, count); 470 } 471 472 /** 473 * set the given byte to the buffer at the specified position 474 * \param[in] buffer the buffer 475 * \param[in] at the position (in number of bytes) to write the data at 476 * \param[in] c the byte to set to the buffer 477 * \param[in] count the number of bytes of bytes to write 478 */ 479 480 INLINE void 481 sldns_buffer_set_at(sldns_buffer *buffer, size_t at, int c, size_t count) 482 { 483 if (!buffer->_vfixed) 484 assert(sldns_buffer_available_at(buffer, at, count)); 485 else if (sldns_buffer_remaining_at(buffer, at) == 0) 486 return; 487 else if (count > sldns_buffer_remaining_at(buffer, at)) { 488 memset(buffer->_data + at, c, 489 sldns_buffer_remaining_at(buffer, at)); 490 return; 491 } 492 memset(buffer->_data + at, c, count); 493 } 494 495 496 /** 497 * writes count bytes of data to the current position of the buffer 498 * \param[in] buffer the buffer 499 * \param[in] data the data to write 500 * \param[in] count the length of the data to write 501 */ 502 INLINE void 503 sldns_buffer_write(sldns_buffer *buffer, const void *data, size_t count) 504 { 505 sldns_buffer_write_at(buffer, buffer->_position, data, count); 506 buffer->_position += count; 507 } 508 509 /** 510 * copies the given (null-delimited) string to the specified position at the buffer 511 * \param[in] buffer the buffer 512 * \param[in] at the position in the buffer 513 * \param[in] str the string to write 514 */ 515 INLINE void 516 sldns_buffer_write_string_at(sldns_buffer *buffer, size_t at, const char *str) 517 { 518 sldns_buffer_write_at(buffer, at, str, strlen(str)); 519 } 520 521 /** 522 * copies the given (null-delimited) string to the current position at the buffer 523 * \param[in] buffer the buffer 524 * \param[in] str the string to write 525 */ 526 INLINE void 527 sldns_buffer_write_string(sldns_buffer *buffer, const char *str) 528 { 529 sldns_buffer_write(buffer, str, strlen(str)); 530 } 531 532 /** 533 * writes the given byte of data at the given position in the buffer 534 * \param[in] buffer the buffer 535 * \param[in] at the position in the buffer 536 * \param[in] data the 8 bits to write 537 */ 538 INLINE void 539 sldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data) 540 { 541 if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return; 542 assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 543 buffer->_data[at] = data; 544 } 545 546 /** 547 * writes the given byte of data at the current position in the buffer 548 * \param[in] buffer the buffer 549 * \param[in] data the 8 bits to write 550 */ 551 INLINE void 552 sldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data) 553 { 554 sldns_buffer_write_u8_at(buffer, buffer->_position, data); 555 buffer->_position += sizeof(data); 556 } 557 558 /** 559 * writes the given 2 byte integer at the given position in the buffer 560 * \param[in] buffer the buffer 561 * \param[in] at the position in the buffer 562 * \param[in] data the 16 bits to write 563 */ 564 INLINE void 565 sldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data) 566 { 567 if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return; 568 assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 569 sldns_write_uint16(buffer->_data + at, data); 570 } 571 572 /** 573 * writes the given 2 byte integer at the current position in the buffer 574 * \param[in] buffer the buffer 575 * \param[in] data the 16 bits to write 576 */ 577 INLINE void 578 sldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data) 579 { 580 sldns_buffer_write_u16_at(buffer, buffer->_position, data); 581 buffer->_position += sizeof(data); 582 } 583 584 /** 585 * writes the given 4 byte integer at the given position in the buffer 586 * \param[in] buffer the buffer 587 * \param[in] at the position in the buffer 588 * \param[in] data the 32 bits to write 589 */ 590 INLINE void 591 sldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data) 592 { 593 if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return; 594 assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 595 sldns_write_uint32(buffer->_data + at, data); 596 } 597 598 /** 599 * writes the given 6 byte integer at the given position in the buffer 600 * \param[in] buffer the buffer 601 * \param[in] at the position in the buffer 602 * \param[in] data the (lower) 48 bits to write 603 */ 604 INLINE void 605 sldns_buffer_write_u48_at(sldns_buffer *buffer, size_t at, uint64_t data) 606 { 607 if (buffer->_vfixed && at + 6 > buffer->_limit) return; 608 assert(sldns_buffer_available_at(buffer, at, 6)); 609 sldns_write_uint48(buffer->_data + at, data); 610 } 611 612 /** 613 * writes the given 4 byte integer at the current position in the buffer 614 * \param[in] buffer the buffer 615 * \param[in] data the 32 bits to write 616 */ 617 INLINE void 618 sldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data) 619 { 620 sldns_buffer_write_u32_at(buffer, buffer->_position, data); 621 buffer->_position += sizeof(data); 622 } 623 624 /** 625 * writes the given 6 byte integer at the current position in the buffer 626 * \param[in] buffer the buffer 627 * \param[in] data the 48 bits to write 628 */ 629 INLINE void 630 sldns_buffer_write_u48(sldns_buffer *buffer, uint64_t data) 631 { 632 sldns_buffer_write_u48_at(buffer, buffer->_position, data); 633 buffer->_position += 6; 634 } 635 636 /** 637 * copies count bytes of data at the given position to the given data-array 638 * \param[in] buffer the buffer 639 * \param[in] at the position in the buffer to start 640 * \param[out] data buffer to copy to 641 * \param[in] count the length of the data to copy 642 */ 643 INLINE void 644 sldns_buffer_read_at(sldns_buffer *buffer, size_t at, void *data, size_t count) 645 { 646 assert(sldns_buffer_available_at(buffer, at, count)); 647 memcpy(data, buffer->_data + at, count); 648 } 649 650 /** 651 * copies count bytes of data at the current position to the given data-array 652 * \param[in] buffer the buffer 653 * \param[out] data buffer to copy to 654 * \param[in] count the length of the data to copy 655 */ 656 INLINE void 657 sldns_buffer_read(sldns_buffer *buffer, void *data, size_t count) 658 { 659 sldns_buffer_read_at(buffer, buffer->_position, data, count); 660 buffer->_position += count; 661 } 662 663 /** 664 * returns the byte value at the given position in the buffer 665 * \param[in] buffer the buffer 666 * \param[in] at the position in the buffer 667 * \return 1 byte integer 668 */ 669 INLINE uint8_t 670 sldns_buffer_read_u8_at(sldns_buffer *buffer, size_t at) 671 { 672 assert(sldns_buffer_available_at(buffer, at, sizeof(uint8_t))); 673 return buffer->_data[at]; 674 } 675 676 /** 677 * returns the byte value at the current position in the buffer 678 * \param[in] buffer the buffer 679 * \return 1 byte integer 680 */ 681 INLINE uint8_t 682 sldns_buffer_read_u8(sldns_buffer *buffer) 683 { 684 uint8_t result = sldns_buffer_read_u8_at(buffer, buffer->_position); 685 buffer->_position += sizeof(uint8_t); 686 return result; 687 } 688 689 /** 690 * returns the 2-byte integer value at the given position in the buffer 691 * \param[in] buffer the buffer 692 * \param[in] at position in the buffer 693 * \return 2 byte integer 694 */ 695 INLINE uint16_t 696 sldns_buffer_read_u16_at(sldns_buffer *buffer, size_t at) 697 { 698 assert(sldns_buffer_available_at(buffer, at, sizeof(uint16_t))); 699 return sldns_read_uint16(buffer->_data + at); 700 } 701 702 /** 703 * returns the 2-byte integer value at the current position in the buffer 704 * \param[in] buffer the buffer 705 * \return 2 byte integer 706 */ 707 INLINE uint16_t 708 sldns_buffer_read_u16(sldns_buffer *buffer) 709 { 710 uint16_t result = sldns_buffer_read_u16_at(buffer, buffer->_position); 711 buffer->_position += sizeof(uint16_t); 712 return result; 713 } 714 715 /** 716 * returns the 4-byte integer value at the given position in the buffer 717 * \param[in] buffer the buffer 718 * \param[in] at position in the buffer 719 * \return 4 byte integer 720 */ 721 INLINE uint32_t 722 sldns_buffer_read_u32_at(sldns_buffer *buffer, size_t at) 723 { 724 assert(sldns_buffer_available_at(buffer, at, sizeof(uint32_t))); 725 return sldns_read_uint32(buffer->_data + at); 726 } 727 728 /** 729 * returns the 4-byte integer value at the current position in the buffer 730 * \param[in] buffer the buffer 731 * \return 4 byte integer 732 */ 733 INLINE uint32_t 734 sldns_buffer_read_u32(sldns_buffer *buffer) 735 { 736 uint32_t result = sldns_buffer_read_u32_at(buffer, buffer->_position); 737 buffer->_position += sizeof(uint32_t); 738 return result; 739 } 740 741 /** 742 * returns the status of the buffer 743 * \param[in] buffer 744 * \return the status 745 */ 746 INLINE int 747 sldns_buffer_status(sldns_buffer *buffer) 748 { 749 return (int)buffer->_status_err; 750 } 751 752 /** 753 * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise 754 * \param[in] buffer the buffer 755 * \return true or false 756 */ 757 INLINE int 758 sldns_buffer_status_ok(sldns_buffer *buffer) 759 { 760 if (buffer) { 761 return sldns_buffer_status(buffer) == 0; 762 } else { 763 return 0; 764 } 765 } 766 767 /** 768 * prints to the buffer, increasing the capacity if required using 769 * buffer_reserve(). The buffer's position is set to the terminating '\\0' 770 * Returns the number of characters written (not including the 771 * terminating '\\0') or -1 on failure. 772 */ 773 int sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) 774 ATTR_FORMAT(printf, 2, 3); 775 776 /** 777 * frees the buffer. 778 * \param[in] *buffer the buffer to be freed 779 * \return void 780 */ 781 void sldns_buffer_free(sldns_buffer *buffer); 782 783 /** 784 * Makes the buffer fixed and returns a pointer to the data. The 785 * caller is responsible for free'ing the result. 786 * \param[in] *buffer the buffer to be exported 787 * \return void 788 */ 789 void *sldns_buffer_export(sldns_buffer *buffer); 790 791 /** 792 * Copy contents of the from buffer to the result buffer and then flips 793 * the result buffer. Data will be silently truncated if the result buffer is 794 * too small. 795 * \param[out] *result resulting buffer which is copied to. 796 * \param[in] *from what to copy to result. 797 */ 798 void sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from); 799 800 #ifdef __cplusplus 801 } 802 #endif 803 804 #endif /* LDNS_SBUFFER_H */ 805