1266077Sdes/* 2266077Sdes * buffer.h -- generic memory buffer. 3266077Sdes * 4266077Sdes * Copyright (c) 2005-2008, NLnet Labs. All rights reserved. 5266077Sdes * 6266077Sdes * See LICENSE for the license. 7266077Sdes * 8266077Sdes * 9266077Sdes * The buffer module implements a generic buffer. The API is based on 10266077Sdes * the java.nio.Buffer interface. 11266077Sdes */ 12266077Sdes 13266077Sdes#ifndef LDNS_SBUFFER_H 14266077Sdes#define LDNS_SBUFFER_H 15266077Sdes 16266077Sdes#ifdef __cplusplus 17266077Sdesextern "C" { 18266077Sdes#endif 19266077Sdes 20266077Sdes#ifdef S_SPLINT_S 21266077Sdes# define INLINE 22266077Sdes#else 23266077Sdes# ifdef SWIG 24266077Sdes# define INLINE static 25266077Sdes# else 26266077Sdes# define INLINE static inline 27266077Sdes# endif 28266077Sdes#endif 29266077Sdes 30266077Sdes/* 31266077Sdes * Copy data allowing for unaligned accesses in network byte order 32266077Sdes * (big endian). 33266077Sdes */ 34266077SdesINLINE uint16_t 35266077Sdessldns_read_uint16(const void *src) 36266077Sdes{ 37266077Sdes#ifdef ALLOW_UNALIGNED_ACCESSES 38276541Sdes return ntohs(*(const uint16_t *) src); 39266077Sdes#else 40276541Sdes const uint8_t *p = (const uint8_t *) src; 41266077Sdes return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; 42266077Sdes#endif 43266077Sdes} 44266077Sdes 45266077SdesINLINE uint32_t 46266077Sdessldns_read_uint32(const void *src) 47266077Sdes{ 48266077Sdes#ifdef ALLOW_UNALIGNED_ACCESSES 49276541Sdes return ntohl(*(const uint32_t *) src); 50266077Sdes#else 51276541Sdes const uint8_t *p = (const uint8_t *) src; 52266077Sdes return ( ((uint32_t) p[0] << 24) 53266077Sdes | ((uint32_t) p[1] << 16) 54266077Sdes | ((uint32_t) p[2] << 8) 55266077Sdes | (uint32_t) p[3]); 56266077Sdes#endif 57266077Sdes} 58266077Sdes 59266077Sdes/* 60266077Sdes * Copy data allowing for unaligned accesses in network byte order 61266077Sdes * (big endian). 62266077Sdes */ 63266077SdesINLINE void 64266077Sdessldns_write_uint16(void *dst, uint16_t data) 65266077Sdes{ 66266077Sdes#ifdef ALLOW_UNALIGNED_ACCESSES 67266077Sdes * (uint16_t *) dst = htons(data); 68266077Sdes#else 69266077Sdes uint8_t *p = (uint8_t *) dst; 70266077Sdes p[0] = (uint8_t) ((data >> 8) & 0xff); 71266077Sdes p[1] = (uint8_t) (data & 0xff); 72266077Sdes#endif 73266077Sdes} 74266077Sdes 75266077SdesINLINE void 76266077Sdessldns_write_uint32(void *dst, uint32_t data) 77266077Sdes{ 78266077Sdes#ifdef ALLOW_UNALIGNED_ACCESSES 79266077Sdes * (uint32_t *) dst = htonl(data); 80266077Sdes#else 81266077Sdes uint8_t *p = (uint8_t *) dst; 82266077Sdes p[0] = (uint8_t) ((data >> 24) & 0xff); 83266077Sdes p[1] = (uint8_t) ((data >> 16) & 0xff); 84266077Sdes p[2] = (uint8_t) ((data >> 8) & 0xff); 85266077Sdes p[3] = (uint8_t) (data & 0xff); 86266077Sdes#endif 87266077Sdes} 88266077Sdes 89266077Sdes 90266077Sdes/** 91266077Sdes * \file sbuffer.h 92266077Sdes * 93266077Sdes * This file contains the definition of sldns_buffer, and functions to manipulate those. 94266077Sdes */ 95266077Sdes 96266077Sdes/** 97266077Sdes * implementation of buffers to ease operations 98266077Sdes * 99266077Sdes * sldns_buffers can contain arbitrary information, per octet. You can write 100266077Sdes * to the current end of a buffer, read from the current position, and 101266077Sdes * access any data within it. 102266077Sdes */ 103266077Sdesstruct sldns_buffer 104266077Sdes{ 105266077Sdes /** The current position used for reading/writing */ 106266077Sdes size_t _position; 107266077Sdes 108266077Sdes /** The read/write limit */ 109266077Sdes size_t _limit; 110266077Sdes 111266077Sdes /** The amount of data the buffer can contain */ 112266077Sdes size_t _capacity; 113266077Sdes 114266077Sdes /** The data contained in the buffer */ 115266077Sdes uint8_t *_data; 116266077Sdes 117266077Sdes /** If the buffer is fixed it cannot be resized */ 118266077Sdes unsigned _fixed : 1; 119266077Sdes 120266077Sdes /** The current state of the buffer. If writing to the buffer fails 121266077Sdes * for any reason, this value is changed. This way, you can perform 122266077Sdes * multiple writes in sequence and check for success afterwards. */ 123266077Sdes unsigned _status_err : 1; 124266077Sdes}; 125266077Sdestypedef struct sldns_buffer sldns_buffer; 126266077Sdes 127266077Sdes#ifdef NDEBUG 128266077SdesINLINE void 129266077Sdessldns_buffer_invariant(sldns_buffer *ATTR_UNUSED(buffer)) 130266077Sdes{ 131266077Sdes} 132266077Sdes#else 133266077SdesINLINE void 134266077Sdessldns_buffer_invariant(sldns_buffer *buffer) 135266077Sdes{ 136266077Sdes assert(buffer != NULL); 137266077Sdes assert(buffer->_position <= buffer->_limit); 138266077Sdes assert(buffer->_limit <= buffer->_capacity); 139266077Sdes assert(buffer->_data != NULL); 140266077Sdes} 141266077Sdes#endif 142266077Sdes 143266077Sdes/** 144266077Sdes * creates a new buffer with the specified capacity. 145266077Sdes * 146266077Sdes * \param[in] capacity the size (in bytes) to allocate for the buffer 147266077Sdes * \return the created buffer 148266077Sdes */ 149266077Sdessldns_buffer *sldns_buffer_new(size_t capacity); 150266077Sdes 151266077Sdes/** 152266077Sdes * creates a buffer with the specified data. The data IS copied 153266077Sdes * and MEMORY allocations are done. The buffer is not fixed and can 154266077Sdes * be resized using buffer_reserve(). 155266077Sdes * 156266077Sdes * \param[in] buffer pointer to the buffer to put the data in 157266077Sdes * \param[in] data the data to encapsulate in the buffer 158266077Sdes * \param[in] size the size of the data 159266077Sdes */ 160266077Sdesvoid sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size); 161266077Sdes 162266077Sdes/** 163266077Sdes * Setup a buffer with the data pointed to. No data copied, no memory allocs. 164266077Sdes * The buffer is fixed. 165266077Sdes * \param[in] buffer pointer to the buffer to put the data in 166266077Sdes * \param[in] data the data to encapsulate in the buffer 167266077Sdes * \param[in] size the size of the data 168266077Sdes */ 169266077Sdesvoid sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size); 170266077Sdes 171266077Sdes/** 172266077Sdes * clears the buffer and make it ready for writing. The buffer's limit 173266077Sdes * is set to the capacity and the position is set to 0. 174266077Sdes * \param[in] buffer the buffer to clear 175266077Sdes */ 176266077SdesINLINE void sldns_buffer_clear(sldns_buffer *buffer) 177266077Sdes{ 178266077Sdes sldns_buffer_invariant(buffer); 179266077Sdes 180266077Sdes /* reset status here? */ 181266077Sdes 182266077Sdes buffer->_position = 0; 183266077Sdes buffer->_limit = buffer->_capacity; 184266077Sdes} 185266077Sdes 186266077Sdes/** 187266077Sdes * makes the buffer ready for reading the data that has been written to 188266077Sdes * the buffer. The buffer's limit is set to the current position and 189266077Sdes * the position is set to 0. 190266077Sdes * 191266077Sdes * \param[in] buffer the buffer to flip 192266077Sdes * \return void 193266077Sdes */ 194266077SdesINLINE void sldns_buffer_flip(sldns_buffer *buffer) 195266077Sdes{ 196266077Sdes sldns_buffer_invariant(buffer); 197266077Sdes 198266077Sdes buffer->_limit = buffer->_position; 199266077Sdes buffer->_position = 0; 200266077Sdes} 201266077Sdes 202266077Sdes/** 203266077Sdes * make the buffer ready for re-reading the data. The buffer's 204266077Sdes * position is reset to 0. 205266077Sdes * \param[in] buffer the buffer to rewind 206266077Sdes */ 207266077SdesINLINE void sldns_buffer_rewind(sldns_buffer *buffer) 208266077Sdes{ 209266077Sdes sldns_buffer_invariant(buffer); 210266077Sdes 211266077Sdes buffer->_position = 0; 212266077Sdes} 213266077Sdes 214266077Sdes/** 215266077Sdes * returns the current position in the buffer (as a number of bytes) 216266077Sdes * \param[in] buffer the buffer 217266077Sdes * \return the current position 218266077Sdes */ 219266077SdesINLINE size_t 220266077Sdessldns_buffer_position(sldns_buffer *buffer) 221266077Sdes{ 222266077Sdes return buffer->_position; 223266077Sdes} 224266077Sdes 225266077Sdes/** 226266077Sdes * sets the buffer's position to MARK. The position must be less than 227266077Sdes * or equal to the buffer's limit. 228266077Sdes * \param[in] buffer the buffer 229266077Sdes * \param[in] mark the mark to use 230266077Sdes */ 231266077SdesINLINE void 232266077Sdessldns_buffer_set_position(sldns_buffer *buffer, size_t mark) 233266077Sdes{ 234266077Sdes assert(mark <= buffer->_limit); 235266077Sdes buffer->_position = mark; 236266077Sdes} 237266077Sdes 238266077Sdes/** 239266077Sdes * changes the buffer's position by COUNT bytes. The position must not 240266077Sdes * be moved behind the buffer's limit or before the beginning of the 241266077Sdes * buffer. 242266077Sdes * \param[in] buffer the buffer 243266077Sdes * \param[in] count the count to use 244266077Sdes */ 245266077SdesINLINE void 246266077Sdessldns_buffer_skip(sldns_buffer *buffer, ssize_t count) 247266077Sdes{ 248266077Sdes assert(buffer->_position + count <= buffer->_limit); 249266077Sdes buffer->_position += count; 250266077Sdes} 251266077Sdes 252266077Sdes/** 253266077Sdes * returns the maximum size of the buffer 254266077Sdes * \param[in] buffer 255266077Sdes * \return the size 256266077Sdes */ 257266077SdesINLINE size_t 258266077Sdessldns_buffer_limit(sldns_buffer *buffer) 259266077Sdes{ 260266077Sdes return buffer->_limit; 261266077Sdes} 262266077Sdes 263266077Sdes/** 264266077Sdes * changes the buffer's limit. If the buffer's position is greater 265266077Sdes * than the new limit the position is set to the limit. 266266077Sdes * \param[in] buffer the buffer 267266077Sdes * \param[in] limit the new limit 268266077Sdes */ 269266077SdesINLINE void 270266077Sdessldns_buffer_set_limit(sldns_buffer *buffer, size_t limit) 271266077Sdes{ 272266077Sdes assert(limit <= buffer->_capacity); 273266077Sdes buffer->_limit = limit; 274266077Sdes if (buffer->_position > buffer->_limit) 275266077Sdes buffer->_position = buffer->_limit; 276266077Sdes} 277266077Sdes 278266077Sdes/** 279266077Sdes * returns the number of bytes the buffer can hold. 280266077Sdes * \param[in] buffer the buffer 281266077Sdes * \return the number of bytes 282266077Sdes */ 283266077SdesINLINE size_t 284266077Sdessldns_buffer_capacity(sldns_buffer *buffer) 285266077Sdes{ 286266077Sdes return buffer->_capacity; 287266077Sdes} 288266077Sdes 289266077Sdes/** 290266077Sdes * changes the buffer's capacity. The data is reallocated so any 291266077Sdes * pointers to the data may become invalid. The buffer's limit is set 292266077Sdes * to the buffer's new capacity. 293266077Sdes * \param[in] buffer the buffer 294266077Sdes * \param[in] capacity the capacity to use 295266077Sdes * \return whether this failed or succeeded 296266077Sdes */ 297266077Sdesint sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity); 298266077Sdes 299266077Sdes/** 300266077Sdes * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's 301266077Sdes * capacity is increased if necessary using buffer_set_capacity(). 302266077Sdes * 303266077Sdes * The buffer's limit is always set to the (possibly increased) 304266077Sdes * capacity. 305266077Sdes * \param[in] buffer the buffer 306266077Sdes * \param[in] amount amount to use 307266077Sdes * \return whether this failed or succeeded 308266077Sdes */ 309266077Sdesint sldns_buffer_reserve(sldns_buffer *buffer, size_t amount); 310266077Sdes 311266077Sdes/** 312266077Sdes * returns a pointer to the data at the indicated position. 313266077Sdes * \param[in] buffer the buffer 314266077Sdes * \param[in] at position 315266077Sdes * \return the pointer to the data 316266077Sdes */ 317266077SdesINLINE uint8_t * 318266077Sdessldns_buffer_at(const sldns_buffer *buffer, size_t at) 319266077Sdes{ 320266077Sdes assert(at <= buffer->_limit); 321266077Sdes return buffer->_data + at; 322266077Sdes} 323266077Sdes 324266077Sdes/** 325266077Sdes * returns a pointer to the beginning of the buffer (the data at 326266077Sdes * position 0). 327266077Sdes * \param[in] buffer the buffer 328266077Sdes * \return the pointer 329266077Sdes */ 330266077SdesINLINE uint8_t * 331266077Sdessldns_buffer_begin(const sldns_buffer *buffer) 332266077Sdes{ 333266077Sdes return sldns_buffer_at(buffer, 0); 334266077Sdes} 335266077Sdes 336266077Sdes/** 337266077Sdes * returns a pointer to the end of the buffer (the data at the buffer's 338266077Sdes * limit). 339266077Sdes * \param[in] buffer the buffer 340266077Sdes * \return the pointer 341266077Sdes */ 342266077SdesINLINE uint8_t * 343266077Sdessldns_buffer_end(sldns_buffer *buffer) 344266077Sdes{ 345266077Sdes return sldns_buffer_at(buffer, buffer->_limit); 346266077Sdes} 347266077Sdes 348266077Sdes/** 349266077Sdes * returns a pointer to the data at the buffer's current position. 350266077Sdes * \param[in] buffer the buffer 351266077Sdes * \return the pointer 352266077Sdes */ 353266077SdesINLINE uint8_t * 354266077Sdessldns_buffer_current(sldns_buffer *buffer) 355266077Sdes{ 356266077Sdes return sldns_buffer_at(buffer, buffer->_position); 357266077Sdes} 358266077Sdes 359266077Sdes/** 360266077Sdes * returns the number of bytes remaining between the indicated position and 361266077Sdes * the limit. 362266077Sdes * \param[in] buffer the buffer 363266077Sdes * \param[in] at indicated position 364266077Sdes * \return number of bytes 365266077Sdes */ 366266077SdesINLINE size_t 367266077Sdessldns_buffer_remaining_at(sldns_buffer *buffer, size_t at) 368266077Sdes{ 369266077Sdes sldns_buffer_invariant(buffer); 370266077Sdes assert(at <= buffer->_limit); 371266077Sdes return buffer->_limit - at; 372266077Sdes} 373266077Sdes 374266077Sdes/** 375266077Sdes * returns the number of bytes remaining between the buffer's position and 376266077Sdes * limit. 377266077Sdes * \param[in] buffer the buffer 378266077Sdes * \return the number of bytes 379266077Sdes */ 380266077SdesINLINE size_t 381266077Sdessldns_buffer_remaining(sldns_buffer *buffer) 382266077Sdes{ 383266077Sdes return sldns_buffer_remaining_at(buffer, buffer->_position); 384266077Sdes} 385266077Sdes 386266077Sdes/** 387266077Sdes * checks if the buffer has at least COUNT more bytes available. 388266077Sdes * Before reading or writing the caller needs to ensure enough space 389266077Sdes * is available! 390266077Sdes * \param[in] buffer the buffer 391266077Sdes * \param[in] at indicated position 392266077Sdes * \param[in] count how much is available 393266077Sdes * \return true or false (as int?) 394266077Sdes */ 395266077SdesINLINE int 396266077Sdessldns_buffer_available_at(sldns_buffer *buffer, size_t at, size_t count) 397266077Sdes{ 398266077Sdes return count <= sldns_buffer_remaining_at(buffer, at); 399266077Sdes} 400266077Sdes 401266077Sdes/** 402266077Sdes * checks if the buffer has count bytes available at the current position 403266077Sdes * \param[in] buffer the buffer 404266077Sdes * \param[in] count how much is available 405266077Sdes * \return true or false (as int?) 406266077Sdes */ 407266077SdesINLINE int 408266077Sdessldns_buffer_available(sldns_buffer *buffer, size_t count) 409266077Sdes{ 410266077Sdes return sldns_buffer_available_at(buffer, buffer->_position, count); 411266077Sdes} 412266077Sdes 413266077Sdes/** 414266077Sdes * writes the given data to the buffer at the specified position 415266077Sdes * \param[in] buffer the buffer 416266077Sdes * \param[in] at the position (in number of bytes) to write the data at 417266077Sdes * \param[in] data pointer to the data to write to the buffer 418266077Sdes * \param[in] count the number of bytes of data to write 419266077Sdes */ 420266077SdesINLINE void 421266077Sdessldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count) 422266077Sdes{ 423266077Sdes assert(sldns_buffer_available_at(buffer, at, count)); 424266077Sdes memcpy(buffer->_data + at, data, count); 425266077Sdes} 426266077Sdes 427266077Sdes/** 428266077Sdes * writes count bytes of data to the current position of the buffer 429266077Sdes * \param[in] buffer the buffer 430266077Sdes * \param[in] data the data to write 431266077Sdes * \param[in] count the lenght of the data to write 432266077Sdes */ 433266077SdesINLINE void 434266077Sdessldns_buffer_write(sldns_buffer *buffer, const void *data, size_t count) 435266077Sdes{ 436266077Sdes sldns_buffer_write_at(buffer, buffer->_position, data, count); 437266077Sdes buffer->_position += count; 438266077Sdes} 439266077Sdes 440266077Sdes/** 441266077Sdes * copies the given (null-delimited) string to the specified position at the buffer 442266077Sdes * \param[in] buffer the buffer 443266077Sdes * \param[in] at the position in the buffer 444266077Sdes * \param[in] str the string to write 445266077Sdes */ 446266077SdesINLINE void 447266077Sdessldns_buffer_write_string_at(sldns_buffer *buffer, size_t at, const char *str) 448266077Sdes{ 449266077Sdes sldns_buffer_write_at(buffer, at, str, strlen(str)); 450266077Sdes} 451266077Sdes 452266077Sdes/** 453266077Sdes * copies the given (null-delimited) string to the current position at the buffer 454266077Sdes * \param[in] buffer the buffer 455266077Sdes * \param[in] str the string to write 456266077Sdes */ 457266077SdesINLINE void 458266077Sdessldns_buffer_write_string(sldns_buffer *buffer, const char *str) 459266077Sdes{ 460266077Sdes sldns_buffer_write(buffer, str, strlen(str)); 461266077Sdes} 462266077Sdes 463266077Sdes/** 464266077Sdes * writes the given byte of data at the given position in the buffer 465266077Sdes * \param[in] buffer the buffer 466266077Sdes * \param[in] at the position in the buffer 467266077Sdes * \param[in] data the 8 bits to write 468266077Sdes */ 469266077SdesINLINE void 470266077Sdessldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data) 471266077Sdes{ 472266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 473266077Sdes buffer->_data[at] = data; 474266077Sdes} 475266077Sdes 476266077Sdes/** 477266077Sdes * writes the given byte of data at the current position in the buffer 478266077Sdes * \param[in] buffer the buffer 479266077Sdes * \param[in] data the 8 bits to write 480266077Sdes */ 481266077SdesINLINE void 482266077Sdessldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data) 483266077Sdes{ 484266077Sdes sldns_buffer_write_u8_at(buffer, buffer->_position, data); 485266077Sdes buffer->_position += sizeof(data); 486266077Sdes} 487266077Sdes 488266077Sdes/** 489266077Sdes * writes the given 2 byte integer at the given position in the buffer 490266077Sdes * \param[in] buffer the buffer 491266077Sdes * \param[in] at the position in the buffer 492266077Sdes * \param[in] data the 16 bits to write 493266077Sdes */ 494266077SdesINLINE void 495266077Sdessldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data) 496266077Sdes{ 497266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 498266077Sdes sldns_write_uint16(buffer->_data + at, data); 499266077Sdes} 500266077Sdes 501266077Sdes/** 502266077Sdes * writes the given 2 byte integer at the current position in the buffer 503266077Sdes * \param[in] buffer the buffer 504266077Sdes * \param[in] data the 16 bits to write 505266077Sdes */ 506266077SdesINLINE void 507266077Sdessldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data) 508266077Sdes{ 509266077Sdes sldns_buffer_write_u16_at(buffer, buffer->_position, data); 510266077Sdes buffer->_position += sizeof(data); 511266077Sdes} 512266077Sdes 513266077Sdes/** 514266077Sdes * writes the given 4 byte integer at the given position in the buffer 515266077Sdes * \param[in] buffer the buffer 516266077Sdes * \param[in] at the position in the buffer 517266077Sdes * \param[in] data the 32 bits to write 518266077Sdes */ 519266077SdesINLINE void 520266077Sdessldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data) 521266077Sdes{ 522266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 523266077Sdes sldns_write_uint32(buffer->_data + at, data); 524266077Sdes} 525266077Sdes 526266077Sdes/** 527266077Sdes * writes the given 4 byte integer at the current position in the buffer 528266077Sdes * \param[in] buffer the buffer 529266077Sdes * \param[in] data the 32 bits to write 530266077Sdes */ 531266077SdesINLINE void 532266077Sdessldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data) 533266077Sdes{ 534266077Sdes sldns_buffer_write_u32_at(buffer, buffer->_position, data); 535266077Sdes buffer->_position += sizeof(data); 536266077Sdes} 537266077Sdes 538266077Sdes/** 539266077Sdes * copies count bytes of data at the given position to the given data-array 540266077Sdes * \param[in] buffer the buffer 541266077Sdes * \param[in] at the position in the buffer to start 542266077Sdes * \param[out] data buffer to copy to 543266077Sdes * \param[in] count the length of the data to copy 544266077Sdes */ 545266077SdesINLINE void 546266077Sdessldns_buffer_read_at(sldns_buffer *buffer, size_t at, void *data, size_t count) 547266077Sdes{ 548266077Sdes assert(sldns_buffer_available_at(buffer, at, count)); 549266077Sdes memcpy(data, buffer->_data + at, count); 550266077Sdes} 551266077Sdes 552266077Sdes/** 553266077Sdes * copies count bytes of data at the current position to the given data-array 554266077Sdes * \param[in] buffer the buffer 555266077Sdes * \param[out] data buffer to copy to 556266077Sdes * \param[in] count the length of the data to copy 557266077Sdes */ 558266077SdesINLINE void 559266077Sdessldns_buffer_read(sldns_buffer *buffer, void *data, size_t count) 560266077Sdes{ 561266077Sdes sldns_buffer_read_at(buffer, buffer->_position, data, count); 562266077Sdes buffer->_position += count; 563266077Sdes} 564266077Sdes 565266077Sdes/** 566266077Sdes * returns the byte value at the given position in the buffer 567266077Sdes * \param[in] buffer the buffer 568266077Sdes * \param[in] at the position in the buffer 569266077Sdes * \return 1 byte integer 570266077Sdes */ 571266077SdesINLINE uint8_t 572266077Sdessldns_buffer_read_u8_at(sldns_buffer *buffer, size_t at) 573266077Sdes{ 574266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint8_t))); 575266077Sdes return buffer->_data[at]; 576266077Sdes} 577266077Sdes 578266077Sdes/** 579266077Sdes * returns the byte value at the current position in the buffer 580266077Sdes * \param[in] buffer the buffer 581266077Sdes * \return 1 byte integer 582266077Sdes */ 583266077SdesINLINE uint8_t 584266077Sdessldns_buffer_read_u8(sldns_buffer *buffer) 585266077Sdes{ 586266077Sdes uint8_t result = sldns_buffer_read_u8_at(buffer, buffer->_position); 587266077Sdes buffer->_position += sizeof(uint8_t); 588266077Sdes return result; 589266077Sdes} 590266077Sdes 591266077Sdes/** 592266077Sdes * returns the 2-byte integer value at the given position in the buffer 593266077Sdes * \param[in] buffer the buffer 594266077Sdes * \param[in] at position in the buffer 595266077Sdes * \return 2 byte integer 596266077Sdes */ 597266077SdesINLINE uint16_t 598266077Sdessldns_buffer_read_u16_at(sldns_buffer *buffer, size_t at) 599266077Sdes{ 600266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint16_t))); 601266077Sdes return sldns_read_uint16(buffer->_data + at); 602266077Sdes} 603266077Sdes 604266077Sdes/** 605266077Sdes * returns the 2-byte integer value at the current position in the buffer 606266077Sdes * \param[in] buffer the buffer 607266077Sdes * \return 2 byte integer 608266077Sdes */ 609266077SdesINLINE uint16_t 610266077Sdessldns_buffer_read_u16(sldns_buffer *buffer) 611266077Sdes{ 612266077Sdes uint16_t result = sldns_buffer_read_u16_at(buffer, buffer->_position); 613266077Sdes buffer->_position += sizeof(uint16_t); 614266077Sdes return result; 615266077Sdes} 616266077Sdes 617266077Sdes/** 618266077Sdes * returns the 4-byte integer value at the given position in the buffer 619266077Sdes * \param[in] buffer the buffer 620266077Sdes * \param[in] at position in the buffer 621266077Sdes * \return 4 byte integer 622266077Sdes */ 623266077SdesINLINE uint32_t 624266077Sdessldns_buffer_read_u32_at(sldns_buffer *buffer, size_t at) 625266077Sdes{ 626266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint32_t))); 627266077Sdes return sldns_read_uint32(buffer->_data + at); 628266077Sdes} 629266077Sdes 630266077Sdes/** 631266077Sdes * returns the 4-byte integer value at the current position in the buffer 632266077Sdes * \param[in] buffer the buffer 633266077Sdes * \return 4 byte integer 634266077Sdes */ 635266077SdesINLINE uint32_t 636266077Sdessldns_buffer_read_u32(sldns_buffer *buffer) 637266077Sdes{ 638266077Sdes uint32_t result = sldns_buffer_read_u32_at(buffer, buffer->_position); 639266077Sdes buffer->_position += sizeof(uint32_t); 640266077Sdes return result; 641266077Sdes} 642266077Sdes 643266077Sdes/** 644266077Sdes * returns the status of the buffer 645266077Sdes * \param[in] buffer 646266077Sdes * \return the status 647266077Sdes */ 648266077SdesINLINE int 649266077Sdessldns_buffer_status(sldns_buffer *buffer) 650266077Sdes{ 651266077Sdes return (int)buffer->_status_err; 652266077Sdes} 653266077Sdes 654266077Sdes/** 655266077Sdes * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise 656266077Sdes * \param[in] buffer the buffer 657266077Sdes * \return true or false 658266077Sdes */ 659266077SdesINLINE int 660266077Sdessldns_buffer_status_ok(sldns_buffer *buffer) 661266077Sdes{ 662266077Sdes if (buffer) { 663266077Sdes return sldns_buffer_status(buffer) == 0; 664266077Sdes } else { 665266077Sdes return 0; 666266077Sdes } 667266077Sdes} 668266077Sdes 669266077Sdes/** 670266077Sdes * prints to the buffer, increasing the capacity if required using 671266077Sdes * buffer_reserve(). The buffer's position is set to the terminating '\\0' 672266077Sdes * Returns the number of characters written (not including the 673266077Sdes * terminating '\\0') or -1 on failure. 674266077Sdes */ 675266077Sdesint sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) 676266077Sdes ATTR_FORMAT(printf, 2, 3); 677266077Sdes 678266077Sdes/** 679266077Sdes * frees the buffer. 680266077Sdes * \param[in] *buffer the buffer to be freed 681266077Sdes * \return void 682266077Sdes */ 683266077Sdesvoid sldns_buffer_free(sldns_buffer *buffer); 684266077Sdes 685266077Sdes/** 686266077Sdes * Makes the buffer fixed and returns a pointer to the data. The 687266077Sdes * caller is responsible for free'ing the result. 688266077Sdes * \param[in] *buffer the buffer to be exported 689266077Sdes * \return void 690266077Sdes */ 691266077Sdesvoid *sldns_buffer_export(sldns_buffer *buffer); 692266077Sdes 693266077Sdes/** 694266077Sdes * Copy contents of the from buffer to the result buffer and then flips 695266077Sdes * the result buffer. Data will be silently truncated if the result buffer is 696266077Sdes * too small. 697266077Sdes * \param[out] *result resulting buffer which is copied to. 698266077Sdes * \param[in] *from what to copy to result. 699266077Sdes */ 700266077Sdesvoid sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from); 701266077Sdes 702266077Sdes#ifdef __cplusplus 703266077Sdes} 704266077Sdes#endif 705266077Sdes 706266077Sdes#endif /* LDNS_SBUFFER_H */ 707