1238104Sdes/* 2238104Sdes * buffer.h -- generic memory buffer. 3238104Sdes * 4238104Sdes * Copyright (c) 2005-2008, NLnet Labs. All rights reserved. 5238104Sdes * 6238104Sdes * See LICENSE for the license. 7238104Sdes * 8238104Sdes * 9238104Sdes * The buffer module implements a generic buffer. The API is based on 10238104Sdes * the java.nio.Buffer interface. 11238104Sdes */ 12238104Sdes 13238104Sdes#ifndef LDNS_BUFFER_H 14238104Sdes#define LDNS_BUFFER_H 15238104Sdes 16238104Sdes#include <assert.h> 17238104Sdes#include <stdarg.h> 18238104Sdes#include <string.h> 19238104Sdes 20238104Sdes#include <ldns/error.h> 21238104Sdes#include <ldns/common.h> 22238104Sdes 23238104Sdes#include "ldns/util.h" 24238104Sdes 25238104Sdes#ifdef __cplusplus 26238104Sdesextern "C" { 27238104Sdes#endif 28238104Sdes 29238104Sdes/** 30238104Sdes * number of initial bytes in buffer of 31238104Sdes * which we cannot tell the size before hand 32238104Sdes */ 33238104Sdes#define LDNS_MIN_BUFLEN 512 34238104Sdes 35238104Sdes/** 36238104Sdes * \file buffer.h 37238104Sdes * 38238104Sdes * This file contains the definition of ldns_buffer, and functions to manipulate those. 39238104Sdes */ 40238104Sdes 41238104Sdes/** 42238104Sdes * implementation of buffers to ease operations 43238104Sdes * 44238104Sdes * ldns_buffers can contain arbitrary information, per octet. You can write 45238104Sdes * to the current end of a buffer, read from the current position, and 46238104Sdes * access any data within it. 47238104Sdes * 48238104Sdes * Example use of buffers is in the source code of \ref host2str.c 49238104Sdes */ 50238104Sdesstruct ldns_struct_buffer 51238104Sdes{ 52238104Sdes /** The current position used for reading/writing */ 53238104Sdes size_t _position; 54238104Sdes 55238104Sdes /** The read/write limit */ 56238104Sdes size_t _limit; 57238104Sdes 58238104Sdes /** The amount of data the buffer can contain */ 59238104Sdes size_t _capacity; 60238104Sdes 61238104Sdes /** The data contained in the buffer */ 62238104Sdes uint8_t *_data; 63238104Sdes 64238104Sdes /** If the buffer is fixed it cannot be resized */ 65238104Sdes unsigned _fixed : 1; 66238104Sdes 67238104Sdes /** The current state of the buffer. If writing to the buffer fails 68238104Sdes * for any reason, this value is changed. This way, you can perform 69238104Sdes * multiple writes in sequence and check for success afterwards. */ 70238104Sdes ldns_status _status; 71238104Sdes}; 72238104Sdestypedef struct ldns_struct_buffer ldns_buffer; 73238104Sdes 74238104Sdes 75238104Sdes#ifdef NDEBUG 76238104SdesINLINE void 77238104Sdesldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer)) 78238104Sdes{ 79238104Sdes} 80238104Sdes#else 81238104SdesINLINE void 82238104Sdesldns_buffer_invariant(ldns_buffer *buffer) 83238104Sdes{ 84238104Sdes assert(buffer != NULL); 85238104Sdes assert(buffer->_position <= buffer->_limit); 86238104Sdes assert(buffer->_limit <= buffer->_capacity); 87238104Sdes assert(buffer->_data != NULL); 88238104Sdes} 89238104Sdes#endif 90238104Sdes 91238104Sdes/** 92238104Sdes * creates a new buffer with the specified capacity. 93238104Sdes * 94238104Sdes * \param[in] capacity the size (in bytes) to allocate for the buffer 95238104Sdes * \return the created buffer 96238104Sdes */ 97238104Sdesldns_buffer *ldns_buffer_new(size_t capacity); 98238104Sdes 99238104Sdes/** 100238104Sdes * creates a buffer with the specified data. The data IS copied 101238104Sdes * and MEMORY allocations are done. The buffer is not fixed and can 102238104Sdes * be resized using buffer_reserve(). 103238104Sdes * 104238104Sdes * \param[in] buffer pointer to the buffer to put the data in 105238104Sdes * \param[in] data the data to encapsulate in the buffer 106238104Sdes * \param[in] size the size of the data 107238104Sdes */ 108238104Sdesvoid ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size); 109238104Sdes 110238104Sdes/** 111238104Sdes * clears the buffer and make it ready for writing. The buffer's limit 112238104Sdes * is set to the capacity and the position is set to 0. 113238104Sdes * \param[in] buffer the buffer to clear 114238104Sdes */ 115238104SdesINLINE void ldns_buffer_clear(ldns_buffer *buffer) 116238104Sdes{ 117238104Sdes ldns_buffer_invariant(buffer); 118238104Sdes 119238104Sdes /* reset status here? */ 120238104Sdes 121238104Sdes buffer->_position = 0; 122238104Sdes buffer->_limit = buffer->_capacity; 123238104Sdes} 124238104Sdes 125238104Sdes/** 126238104Sdes * makes the buffer ready for reading the data that has been written to 127238104Sdes * the buffer. The buffer's limit is set to the current position and 128238104Sdes * the position is set to 0. 129238104Sdes * 130238104Sdes * \param[in] buffer the buffer to flip 131238104Sdes * \return void 132238104Sdes */ 133238104SdesINLINE void ldns_buffer_flip(ldns_buffer *buffer) 134238104Sdes{ 135238104Sdes ldns_buffer_invariant(buffer); 136238104Sdes 137238104Sdes buffer->_limit = buffer->_position; 138238104Sdes buffer->_position = 0; 139238104Sdes} 140238104Sdes 141238104Sdes/** 142238104Sdes * make the buffer ready for re-reading the data. The buffer's 143238104Sdes * position is reset to 0. 144238104Sdes * \param[in] buffer the buffer to rewind 145238104Sdes */ 146238104SdesINLINE void ldns_buffer_rewind(ldns_buffer *buffer) 147238104Sdes{ 148238104Sdes ldns_buffer_invariant(buffer); 149238104Sdes 150238104Sdes buffer->_position = 0; 151238104Sdes} 152238104Sdes 153238104Sdes/** 154238104Sdes * returns the current position in the buffer (as a number of bytes) 155238104Sdes * \param[in] buffer the buffer 156238104Sdes * \return the current position 157238104Sdes */ 158238104SdesINLINE size_t 159238104Sdesldns_buffer_position(ldns_buffer *buffer) 160238104Sdes{ 161238104Sdes return buffer->_position; 162238104Sdes} 163238104Sdes 164238104Sdes/** 165238104Sdes * sets the buffer's position to MARK. The position must be less than 166238104Sdes * or equal to the buffer's limit. 167238104Sdes * \param[in] buffer the buffer 168238104Sdes * \param[in] mark the mark to use 169238104Sdes */ 170238104SdesINLINE void 171238104Sdesldns_buffer_set_position(ldns_buffer *buffer, size_t mark) 172238104Sdes{ 173238104Sdes assert(mark <= buffer->_limit); 174238104Sdes buffer->_position = mark; 175238104Sdes} 176238104Sdes 177238104Sdes/** 178238104Sdes * changes the buffer's position by COUNT bytes. The position must not 179238104Sdes * be moved behind the buffer's limit or before the beginning of the 180238104Sdes * buffer. 181238104Sdes * \param[in] buffer the buffer 182238104Sdes * \param[in] count the count to use 183238104Sdes */ 184238104SdesINLINE void 185238104Sdesldns_buffer_skip(ldns_buffer *buffer, ssize_t count) 186238104Sdes{ 187238104Sdes assert(buffer->_position + count <= buffer->_limit); 188238104Sdes buffer->_position += count; 189238104Sdes} 190238104Sdes 191238104Sdes/** 192238104Sdes * returns the maximum size of the buffer 193238104Sdes * \param[in] buffer 194238104Sdes * \return the size 195238104Sdes */ 196238104SdesINLINE size_t 197238104Sdesldns_buffer_limit(ldns_buffer *buffer) 198238104Sdes{ 199238104Sdes return buffer->_limit; 200238104Sdes} 201238104Sdes 202238104Sdes/** 203238104Sdes * changes the buffer's limit. If the buffer's position is greater 204238104Sdes * than the new limit the position is set to the limit. 205238104Sdes * \param[in] buffer the buffer 206238104Sdes * \param[in] limit the new limit 207238104Sdes */ 208238104SdesINLINE void 209238104Sdesldns_buffer_set_limit(ldns_buffer *buffer, size_t limit) 210238104Sdes{ 211238104Sdes assert(limit <= buffer->_capacity); 212238104Sdes buffer->_limit = limit; 213238104Sdes if (buffer->_position > buffer->_limit) 214238104Sdes buffer->_position = buffer->_limit; 215238104Sdes} 216238104Sdes 217238104Sdes/** 218238104Sdes * returns the number of bytes the buffer can hold. 219238104Sdes * \param[in] buffer the buffer 220238104Sdes * \return the number of bytes 221238104Sdes */ 222238104SdesINLINE size_t 223238104Sdesldns_buffer_capacity(ldns_buffer *buffer) 224238104Sdes{ 225238104Sdes return buffer->_capacity; 226238104Sdes} 227238104Sdes 228238104Sdes/** 229238104Sdes * changes the buffer's capacity. The data is reallocated so any 230238104Sdes * pointers to the data may become invalid. The buffer's limit is set 231238104Sdes * to the buffer's new capacity. 232238104Sdes * \param[in] buffer the buffer 233238104Sdes * \param[in] capacity the capacity to use 234238104Sdes * \return whether this failed or succeeded 235238104Sdes */ 236238104Sdesbool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity); 237238104Sdes 238238104Sdes/** 239238104Sdes * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's 240238104Sdes * capacity is increased if necessary using buffer_set_capacity(). 241238104Sdes * 242238104Sdes * The buffer's limit is always set to the (possibly increased) 243238104Sdes * capacity. 244238104Sdes * \param[in] buffer the buffer 245238104Sdes * \param[in] amount amount to use 246238104Sdes * \return whether this failed or succeeded 247238104Sdes */ 248238104Sdesbool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount); 249238104Sdes 250238104Sdes/** 251238104Sdes * returns a pointer to the data at the indicated position. 252238104Sdes * \param[in] buffer the buffer 253238104Sdes * \param[in] at position 254238104Sdes * \return the pointer to the data 255238104Sdes */ 256238104SdesINLINE uint8_t * 257238104Sdesldns_buffer_at(const ldns_buffer *buffer, size_t at) 258238104Sdes{ 259238104Sdes assert(at <= buffer->_limit); 260238104Sdes return buffer->_data + at; 261238104Sdes} 262238104Sdes 263238104Sdes/** 264238104Sdes * returns a pointer to the beginning of the buffer (the data at 265238104Sdes * position 0). 266238104Sdes * \param[in] buffer the buffer 267238104Sdes * \return the pointer 268238104Sdes */ 269238104SdesINLINE uint8_t * 270238104Sdesldns_buffer_begin(const ldns_buffer *buffer) 271238104Sdes{ 272238104Sdes return ldns_buffer_at(buffer, 0); 273238104Sdes} 274238104Sdes 275238104Sdes/** 276238104Sdes * returns a pointer to the end of the buffer (the data at the buffer's 277238104Sdes * limit). 278238104Sdes * \param[in] buffer the buffer 279238104Sdes * \return the pointer 280238104Sdes */ 281238104SdesINLINE uint8_t * 282238104Sdesldns_buffer_end(ldns_buffer *buffer) 283238104Sdes{ 284238104Sdes return ldns_buffer_at(buffer, buffer->_limit); 285238104Sdes} 286238104Sdes 287238104Sdes/** 288238104Sdes * returns a pointer to the data at the buffer's current position. 289238104Sdes * \param[in] buffer the buffer 290238104Sdes * \return the pointer 291238104Sdes */ 292238104SdesINLINE uint8_t * 293238104Sdesldns_buffer_current(ldns_buffer *buffer) 294238104Sdes{ 295238104Sdes return ldns_buffer_at(buffer, buffer->_position); 296238104Sdes} 297238104Sdes 298238104Sdes/** 299238104Sdes * returns the number of bytes remaining between the indicated position and 300238104Sdes * the limit. 301238104Sdes * \param[in] buffer the buffer 302238104Sdes * \param[in] at indicated position 303238104Sdes * \return number of bytes 304238104Sdes */ 305238104SdesINLINE size_t 306238104Sdesldns_buffer_remaining_at(ldns_buffer *buffer, size_t at) 307238104Sdes{ 308238104Sdes ldns_buffer_invariant(buffer); 309238104Sdes assert(at <= buffer->_limit); 310238104Sdes return buffer->_limit - at; 311238104Sdes} 312238104Sdes 313238104Sdes/** 314238104Sdes * returns the number of bytes remaining between the buffer's position and 315238104Sdes * limit. 316238104Sdes * \param[in] buffer the buffer 317238104Sdes * \return the number of bytes 318238104Sdes */ 319238104SdesINLINE size_t 320238104Sdesldns_buffer_remaining(ldns_buffer *buffer) 321238104Sdes{ 322238104Sdes return ldns_buffer_remaining_at(buffer, buffer->_position); 323238104Sdes} 324238104Sdes 325238104Sdes/** 326238104Sdes * checks if the buffer has at least COUNT more bytes available. 327238104Sdes * Before reading or writing the caller needs to ensure enough space 328238104Sdes * is available! 329238104Sdes * \param[in] buffer the buffer 330238104Sdes * \param[in] at indicated position 331238104Sdes * \param[in] count how much is available 332238104Sdes * \return true or false (as int?) 333238104Sdes */ 334238104SdesINLINE int 335238104Sdesldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count) 336238104Sdes{ 337238104Sdes return count <= ldns_buffer_remaining_at(buffer, at); 338238104Sdes} 339238104Sdes 340238104Sdes/** 341238104Sdes * checks if the buffer has count bytes available at the current position 342238104Sdes * \param[in] buffer the buffer 343238104Sdes * \param[in] count how much is available 344238104Sdes * \return true or false (as int?) 345238104Sdes */ 346238104SdesINLINE int 347238104Sdesldns_buffer_available(ldns_buffer *buffer, size_t count) 348238104Sdes{ 349238104Sdes return ldns_buffer_available_at(buffer, buffer->_position, count); 350238104Sdes} 351238104Sdes 352238104Sdes/** 353238104Sdes * writes the given data to the buffer at the specified position 354238104Sdes * \param[in] buffer the buffer 355238104Sdes * \param[in] at the position (in number of bytes) to write the data at 356238104Sdes * \param[in] data pointer to the data to write to the buffer 357238104Sdes * \param[in] count the number of bytes of data to write 358238104Sdes */ 359238104SdesINLINE void 360238104Sdesldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count) 361238104Sdes{ 362238104Sdes assert(ldns_buffer_available_at(buffer, at, count)); 363238104Sdes memcpy(buffer->_data + at, data, count); 364238104Sdes} 365238104Sdes 366238104Sdes/** 367238104Sdes * writes count bytes of data to the current position of the buffer 368238104Sdes * \param[in] buffer the buffer 369238104Sdes * \param[in] data the data to write 370238104Sdes * \param[in] count the lenght of the data to write 371238104Sdes */ 372238104SdesINLINE void 373238104Sdesldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count) 374238104Sdes{ 375238104Sdes ldns_buffer_write_at(buffer, buffer->_position, data, count); 376238104Sdes buffer->_position += count; 377238104Sdes} 378238104Sdes 379238104Sdes/** 380238104Sdes * copies the given (null-delimited) string to the specified position at the buffer 381238104Sdes * \param[in] buffer the buffer 382238104Sdes * \param[in] at the position in the buffer 383238104Sdes * \param[in] str the string to write 384238104Sdes */ 385238104SdesINLINE void 386238104Sdesldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str) 387238104Sdes{ 388238104Sdes ldns_buffer_write_at(buffer, at, str, strlen(str)); 389238104Sdes} 390238104Sdes 391238104Sdes/** 392238104Sdes * copies the given (null-delimited) string to the current position at the buffer 393238104Sdes * \param[in] buffer the buffer 394238104Sdes * \param[in] str the string to write 395238104Sdes */ 396238104SdesINLINE void 397238104Sdesldns_buffer_write_string(ldns_buffer *buffer, const char *str) 398238104Sdes{ 399238104Sdes ldns_buffer_write(buffer, str, strlen(str)); 400238104Sdes} 401238104Sdes 402238104Sdes/** 403238104Sdes * writes the given byte of data at the given position in the buffer 404238104Sdes * \param[in] buffer the buffer 405238104Sdes * \param[in] at the position in the buffer 406238104Sdes * \param[in] data the 8 bits to write 407238104Sdes */ 408238104SdesINLINE void 409238104Sdesldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data) 410238104Sdes{ 411238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(data))); 412238104Sdes buffer->_data[at] = data; 413238104Sdes} 414238104Sdes 415238104Sdes/** 416238104Sdes * writes the given byte of data at the current position in the buffer 417238104Sdes * \param[in] buffer the buffer 418238104Sdes * \param[in] data the 8 bits to write 419238104Sdes */ 420238104SdesINLINE void 421238104Sdesldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data) 422238104Sdes{ 423238104Sdes ldns_buffer_write_u8_at(buffer, buffer->_position, data); 424238104Sdes buffer->_position += sizeof(data); 425238104Sdes} 426238104Sdes 427238104Sdes/** 428238104Sdes * writes the given 2 byte integer at the given position in the buffer 429238104Sdes * \param[in] buffer the buffer 430238104Sdes * \param[in] at the position in the buffer 431238104Sdes * \param[in] data the 16 bits to write 432238104Sdes */ 433238104SdesINLINE void 434238104Sdesldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data) 435238104Sdes{ 436238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(data))); 437238104Sdes ldns_write_uint16(buffer->_data + at, data); 438238104Sdes} 439238104Sdes 440238104Sdes/** 441238104Sdes * writes the given 2 byte integer at the current position in the buffer 442238104Sdes * \param[in] buffer the buffer 443238104Sdes * \param[in] data the 16 bits to write 444238104Sdes */ 445238104SdesINLINE void 446238104Sdesldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data) 447238104Sdes{ 448238104Sdes ldns_buffer_write_u16_at(buffer, buffer->_position, data); 449238104Sdes buffer->_position += sizeof(data); 450238104Sdes} 451238104Sdes 452238104Sdes/** 453238104Sdes * writes the given 4 byte integer at the given position in the buffer 454238104Sdes * \param[in] buffer the buffer 455238104Sdes * \param[in] at the position in the buffer 456238104Sdes * \param[in] data the 32 bits to write 457238104Sdes */ 458238104SdesINLINE void 459238104Sdesldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data) 460238104Sdes{ 461238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(data))); 462238104Sdes ldns_write_uint32(buffer->_data + at, data); 463238104Sdes} 464238104Sdes 465238104Sdes/** 466238104Sdes * writes the given 4 byte integer at the current position in the buffer 467238104Sdes * \param[in] buffer the buffer 468238104Sdes * \param[in] data the 32 bits to write 469238104Sdes */ 470238104SdesINLINE void 471238104Sdesldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data) 472238104Sdes{ 473238104Sdes ldns_buffer_write_u32_at(buffer, buffer->_position, data); 474238104Sdes buffer->_position += sizeof(data); 475238104Sdes} 476238104Sdes 477238104Sdes/** 478238104Sdes * copies count bytes of data at the given position to the given data-array 479238104Sdes * \param[in] buffer the buffer 480238104Sdes * \param[in] at the position in the buffer to start 481238104Sdes * \param[out] data buffer to copy to 482238104Sdes * \param[in] count the length of the data to copy 483238104Sdes */ 484238104SdesINLINE void 485238104Sdesldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count) 486238104Sdes{ 487238104Sdes assert(ldns_buffer_available_at(buffer, at, count)); 488238104Sdes memcpy(data, buffer->_data + at, count); 489238104Sdes} 490238104Sdes 491238104Sdes/** 492238104Sdes * copies count bytes of data at the current position to the given data-array 493238104Sdes * \param[in] buffer the buffer 494238104Sdes * \param[out] data buffer to copy to 495238104Sdes * \param[in] count the length of the data to copy 496238104Sdes */ 497238104SdesINLINE void 498238104Sdesldns_buffer_read(ldns_buffer *buffer, void *data, size_t count) 499238104Sdes{ 500238104Sdes ldns_buffer_read_at(buffer, buffer->_position, data, count); 501238104Sdes buffer->_position += count; 502238104Sdes} 503238104Sdes 504238104Sdes/** 505238104Sdes * returns the byte value at the given position in the buffer 506238104Sdes * \param[in] buffer the buffer 507238104Sdes * \param[in] at the position in the buffer 508238104Sdes * \return 1 byte integer 509238104Sdes */ 510238104SdesINLINE uint8_t 511238104Sdesldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at) 512238104Sdes{ 513238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t))); 514238104Sdes return buffer->_data[at]; 515238104Sdes} 516238104Sdes 517238104Sdes/** 518238104Sdes * returns the byte value at the current position in the buffer 519238104Sdes * \param[in] buffer the buffer 520238104Sdes * \return 1 byte integer 521238104Sdes */ 522238104SdesINLINE uint8_t 523238104Sdesldns_buffer_read_u8(ldns_buffer *buffer) 524238104Sdes{ 525238104Sdes uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position); 526238104Sdes buffer->_position += sizeof(uint8_t); 527238104Sdes return result; 528238104Sdes} 529238104Sdes 530238104Sdes/** 531238104Sdes * returns the 2-byte integer value at the given position in the buffer 532238104Sdes * \param[in] buffer the buffer 533238104Sdes * \param[in] at position in the buffer 534238104Sdes * \return 2 byte integer 535238104Sdes */ 536238104SdesINLINE uint16_t 537238104Sdesldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at) 538238104Sdes{ 539238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t))); 540238104Sdes return ldns_read_uint16(buffer->_data + at); 541238104Sdes} 542238104Sdes 543238104Sdes/** 544238104Sdes * returns the 2-byte integer value at the current position in the buffer 545238104Sdes * \param[in] buffer the buffer 546238104Sdes * \return 2 byte integer 547238104Sdes */ 548238104SdesINLINE uint16_t 549238104Sdesldns_buffer_read_u16(ldns_buffer *buffer) 550238104Sdes{ 551238104Sdes uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position); 552238104Sdes buffer->_position += sizeof(uint16_t); 553238104Sdes return result; 554238104Sdes} 555238104Sdes 556238104Sdes/** 557238104Sdes * returns the 4-byte integer value at the given position in the buffer 558238104Sdes * \param[in] buffer the buffer 559238104Sdes * \param[in] at position in the buffer 560238104Sdes * \return 4 byte integer 561238104Sdes */ 562238104SdesINLINE uint32_t 563238104Sdesldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at) 564238104Sdes{ 565238104Sdes assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t))); 566238104Sdes return ldns_read_uint32(buffer->_data + at); 567238104Sdes} 568238104Sdes 569238104Sdes/** 570238104Sdes * returns the 4-byte integer value at the current position in the buffer 571238104Sdes * \param[in] buffer the buffer 572238104Sdes * \return 4 byte integer 573238104Sdes */ 574238104SdesINLINE uint32_t 575238104Sdesldns_buffer_read_u32(ldns_buffer *buffer) 576238104Sdes{ 577238104Sdes uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position); 578238104Sdes buffer->_position += sizeof(uint32_t); 579238104Sdes return result; 580238104Sdes} 581238104Sdes 582238104Sdes/** 583238104Sdes * returns the status of the buffer 584238104Sdes * \param[in] buffer 585238104Sdes * \return the status 586238104Sdes */ 587238104SdesINLINE ldns_status 588238104Sdesldns_buffer_status(ldns_buffer *buffer) 589238104Sdes{ 590238104Sdes return buffer->_status; 591238104Sdes} 592238104Sdes 593238104Sdes/** 594238104Sdes * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise 595238104Sdes * \param[in] buffer the buffer 596238104Sdes * \return true or false 597238104Sdes */ 598238104SdesINLINE bool 599238104Sdesldns_buffer_status_ok(ldns_buffer *buffer) 600238104Sdes{ 601238104Sdes if (buffer) { 602238104Sdes return ldns_buffer_status(buffer) == LDNS_STATUS_OK; 603238104Sdes } else { 604238104Sdes return false; 605238104Sdes } 606238104Sdes} 607238104Sdes 608238104Sdes/** 609238104Sdes * prints to the buffer, increasing the capacity if required using 610238104Sdes * buffer_reserve(). The buffer's position is set to the terminating '\\0' 611238104Sdes * Returns the number of characters written (not including the 612238104Sdes * terminating '\\0') or -1 on failure. 613238104Sdes */ 614238104Sdesint ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...); 615238104Sdes/* ATTR_FORMAT(printf, 2, 3);*/ 616238104Sdes 617238104Sdes/** 618238104Sdes * frees the buffer. 619238104Sdes * \param[in] *buffer the buffer to be freed 620238104Sdes * \return void 621238104Sdes */ 622238104Sdesvoid ldns_buffer_free(ldns_buffer *buffer); 623238104Sdes 624238104Sdes/** 625238104Sdes * Makes the buffer fixed and returns a pointer to the data. The 626238104Sdes * caller is responsible for free'ing the result. 627238104Sdes * \param[in] *buffer the buffer to be exported 628238104Sdes * \return void 629238104Sdes */ 630238104Sdesvoid *ldns_buffer_export(ldns_buffer *buffer); 631238104Sdes 632238104Sdes/** 633246854Sdes * Copy contents of the from buffer to the result buffer and then flips 634246854Sdes * the result buffer. Data will be silently truncated if the result buffer is 635246854Sdes * too small. 636238104Sdes * \param[out] *result resulting buffer which is copied to. 637238104Sdes * \param[in] *from what to copy to result. 638238104Sdes */ 639238104Sdesvoid ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from); 640238104Sdes 641238104Sdes#ifdef __cplusplus 642238104Sdes} 643238104Sdes#endif 644238104Sdes 645238104Sdes#endif /* LDNS_BUFFER_H */ 646