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 90356345ScyINLINE void 91356345Scysldns_write_uint48(void *dst, uint64_t data) 92356345Scy{ 93356345Scy uint8_t *p = (uint8_t *) dst; 94356345Scy p[0] = (uint8_t) ((data >> 40) & 0xff); 95356345Scy p[1] = (uint8_t) ((data >> 32) & 0xff); 96356345Scy p[2] = (uint8_t) ((data >> 24) & 0xff); 97356345Scy p[3] = (uint8_t) ((data >> 16) & 0xff); 98356345Scy p[4] = (uint8_t) ((data >> 8) & 0xff); 99356345Scy p[5] = (uint8_t) (data & 0xff); 100356345Scy} 101356345Scy 102356345Scy 103266077Sdes/** 104266077Sdes * \file sbuffer.h 105266077Sdes * 106266077Sdes * This file contains the definition of sldns_buffer, and functions to manipulate those. 107266077Sdes */ 108266077Sdes 109266077Sdes/** 110266077Sdes * implementation of buffers to ease operations 111266077Sdes * 112266077Sdes * sldns_buffers can contain arbitrary information, per octet. You can write 113266077Sdes * to the current end of a buffer, read from the current position, and 114266077Sdes * access any data within it. 115266077Sdes */ 116266077Sdesstruct sldns_buffer 117266077Sdes{ 118266077Sdes /** The current position used for reading/writing */ 119266077Sdes size_t _position; 120266077Sdes 121266077Sdes /** The read/write limit */ 122266077Sdes size_t _limit; 123266077Sdes 124266077Sdes /** The amount of data the buffer can contain */ 125266077Sdes size_t _capacity; 126266077Sdes 127266077Sdes /** The data contained in the buffer */ 128266077Sdes uint8_t *_data; 129266077Sdes 130266077Sdes /** If the buffer is fixed it cannot be resized */ 131266077Sdes unsigned _fixed : 1; 132266077Sdes 133266077Sdes /** The current state of the buffer. If writing to the buffer fails 134266077Sdes * for any reason, this value is changed. This way, you can perform 135266077Sdes * multiple writes in sequence and check for success afterwards. */ 136266077Sdes unsigned _status_err : 1; 137266077Sdes}; 138266077Sdestypedef struct sldns_buffer sldns_buffer; 139266077Sdes 140266077Sdes#ifdef NDEBUG 141266077SdesINLINE void 142266077Sdessldns_buffer_invariant(sldns_buffer *ATTR_UNUSED(buffer)) 143266077Sdes{ 144266077Sdes} 145266077Sdes#else 146266077SdesINLINE void 147266077Sdessldns_buffer_invariant(sldns_buffer *buffer) 148266077Sdes{ 149266077Sdes assert(buffer != NULL); 150266077Sdes assert(buffer->_position <= buffer->_limit); 151266077Sdes assert(buffer->_limit <= buffer->_capacity); 152266077Sdes assert(buffer->_data != NULL); 153266077Sdes} 154266077Sdes#endif 155266077Sdes 156266077Sdes/** 157266077Sdes * creates a new buffer with the specified capacity. 158266077Sdes * 159266077Sdes * \param[in] capacity the size (in bytes) to allocate for the buffer 160266077Sdes * \return the created buffer 161266077Sdes */ 162266077Sdessldns_buffer *sldns_buffer_new(size_t capacity); 163266077Sdes 164266077Sdes/** 165266077Sdes * creates a buffer with the specified data. The data IS copied 166266077Sdes * and MEMORY allocations are done. The buffer is not fixed and can 167266077Sdes * be resized using buffer_reserve(). 168266077Sdes * 169266077Sdes * \param[in] buffer pointer to the buffer to put the data in 170266077Sdes * \param[in] data the data to encapsulate in the buffer 171266077Sdes * \param[in] size the size of the data 172266077Sdes */ 173266077Sdesvoid sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size); 174266077Sdes 175266077Sdes/** 176266077Sdes * Setup a buffer with the data pointed to. No data copied, no memory allocs. 177266077Sdes * The buffer is fixed. 178266077Sdes * \param[in] buffer pointer to the buffer to put the data in 179266077Sdes * \param[in] data the data to encapsulate in the buffer 180266077Sdes * \param[in] size the size of the data 181266077Sdes */ 182266077Sdesvoid sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size); 183266077Sdes 184266077Sdes/** 185266077Sdes * clears the buffer and make it ready for writing. The buffer's limit 186266077Sdes * is set to the capacity and the position is set to 0. 187266077Sdes * \param[in] buffer the buffer to clear 188266077Sdes */ 189266077SdesINLINE void sldns_buffer_clear(sldns_buffer *buffer) 190266077Sdes{ 191266077Sdes sldns_buffer_invariant(buffer); 192266077Sdes 193266077Sdes /* reset status here? */ 194266077Sdes 195266077Sdes buffer->_position = 0; 196266077Sdes buffer->_limit = buffer->_capacity; 197266077Sdes} 198266077Sdes 199266077Sdes/** 200266077Sdes * makes the buffer ready for reading the data that has been written to 201266077Sdes * the buffer. The buffer's limit is set to the current position and 202266077Sdes * the position is set to 0. 203266077Sdes * 204266077Sdes * \param[in] buffer the buffer to flip 205266077Sdes * \return void 206266077Sdes */ 207266077SdesINLINE void sldns_buffer_flip(sldns_buffer *buffer) 208266077Sdes{ 209266077Sdes sldns_buffer_invariant(buffer); 210266077Sdes 211266077Sdes buffer->_limit = buffer->_position; 212266077Sdes buffer->_position = 0; 213266077Sdes} 214266077Sdes 215266077Sdes/** 216266077Sdes * make the buffer ready for re-reading the data. The buffer's 217266077Sdes * position is reset to 0. 218266077Sdes * \param[in] buffer the buffer to rewind 219266077Sdes */ 220266077SdesINLINE void sldns_buffer_rewind(sldns_buffer *buffer) 221266077Sdes{ 222266077Sdes sldns_buffer_invariant(buffer); 223266077Sdes 224266077Sdes buffer->_position = 0; 225266077Sdes} 226266077Sdes 227266077Sdes/** 228266077Sdes * returns the current position in the buffer (as a number of bytes) 229266077Sdes * \param[in] buffer the buffer 230266077Sdes * \return the current position 231266077Sdes */ 232266077SdesINLINE size_t 233266077Sdessldns_buffer_position(sldns_buffer *buffer) 234266077Sdes{ 235266077Sdes return buffer->_position; 236266077Sdes} 237266077Sdes 238266077Sdes/** 239266077Sdes * sets the buffer's position to MARK. The position must be less than 240266077Sdes * or equal to the buffer's limit. 241266077Sdes * \param[in] buffer the buffer 242266077Sdes * \param[in] mark the mark to use 243266077Sdes */ 244266077SdesINLINE void 245266077Sdessldns_buffer_set_position(sldns_buffer *buffer, size_t mark) 246266077Sdes{ 247266077Sdes assert(mark <= buffer->_limit); 248266077Sdes buffer->_position = mark; 249266077Sdes} 250266077Sdes 251266077Sdes/** 252266077Sdes * changes the buffer's position by COUNT bytes. The position must not 253266077Sdes * be moved behind the buffer's limit or before the beginning of the 254266077Sdes * buffer. 255266077Sdes * \param[in] buffer the buffer 256266077Sdes * \param[in] count the count to use 257266077Sdes */ 258266077SdesINLINE void 259266077Sdessldns_buffer_skip(sldns_buffer *buffer, ssize_t count) 260266077Sdes{ 261266077Sdes assert(buffer->_position + count <= buffer->_limit); 262266077Sdes buffer->_position += count; 263266077Sdes} 264266077Sdes 265266077Sdes/** 266266077Sdes * returns the maximum size of the buffer 267266077Sdes * \param[in] buffer 268266077Sdes * \return the size 269266077Sdes */ 270266077SdesINLINE size_t 271266077Sdessldns_buffer_limit(sldns_buffer *buffer) 272266077Sdes{ 273266077Sdes return buffer->_limit; 274266077Sdes} 275266077Sdes 276266077Sdes/** 277266077Sdes * changes the buffer's limit. If the buffer's position is greater 278266077Sdes * than the new limit the position is set to the limit. 279266077Sdes * \param[in] buffer the buffer 280266077Sdes * \param[in] limit the new limit 281266077Sdes */ 282266077SdesINLINE void 283266077Sdessldns_buffer_set_limit(sldns_buffer *buffer, size_t limit) 284266077Sdes{ 285266077Sdes assert(limit <= buffer->_capacity); 286266077Sdes buffer->_limit = limit; 287266077Sdes if (buffer->_position > buffer->_limit) 288266077Sdes buffer->_position = buffer->_limit; 289266077Sdes} 290266077Sdes 291266077Sdes/** 292266077Sdes * returns the number of bytes the buffer can hold. 293266077Sdes * \param[in] buffer the buffer 294266077Sdes * \return the number of bytes 295266077Sdes */ 296266077SdesINLINE size_t 297266077Sdessldns_buffer_capacity(sldns_buffer *buffer) 298266077Sdes{ 299266077Sdes return buffer->_capacity; 300266077Sdes} 301266077Sdes 302266077Sdes/** 303266077Sdes * changes the buffer's capacity. The data is reallocated so any 304266077Sdes * pointers to the data may become invalid. The buffer's limit is set 305266077Sdes * to the buffer's new capacity. 306266077Sdes * \param[in] buffer the buffer 307266077Sdes * \param[in] capacity the capacity to use 308266077Sdes * \return whether this failed or succeeded 309266077Sdes */ 310266077Sdesint sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity); 311266077Sdes 312266077Sdes/** 313266077Sdes * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's 314266077Sdes * capacity is increased if necessary using buffer_set_capacity(). 315266077Sdes * 316266077Sdes * The buffer's limit is always set to the (possibly increased) 317266077Sdes * capacity. 318266077Sdes * \param[in] buffer the buffer 319266077Sdes * \param[in] amount amount to use 320266077Sdes * \return whether this failed or succeeded 321266077Sdes */ 322266077Sdesint sldns_buffer_reserve(sldns_buffer *buffer, size_t amount); 323266077Sdes 324266077Sdes/** 325266077Sdes * returns a pointer to the data at the indicated position. 326266077Sdes * \param[in] buffer the buffer 327266077Sdes * \param[in] at position 328266077Sdes * \return the pointer to the data 329266077Sdes */ 330266077SdesINLINE uint8_t * 331266077Sdessldns_buffer_at(const sldns_buffer *buffer, size_t at) 332266077Sdes{ 333266077Sdes assert(at <= buffer->_limit); 334266077Sdes return buffer->_data + at; 335266077Sdes} 336266077Sdes 337266077Sdes/** 338266077Sdes * returns a pointer to the beginning of the buffer (the data at 339266077Sdes * position 0). 340266077Sdes * \param[in] buffer the buffer 341266077Sdes * \return the pointer 342266077Sdes */ 343266077SdesINLINE uint8_t * 344266077Sdessldns_buffer_begin(const sldns_buffer *buffer) 345266077Sdes{ 346266077Sdes return sldns_buffer_at(buffer, 0); 347266077Sdes} 348266077Sdes 349266077Sdes/** 350266077Sdes * returns a pointer to the end of the buffer (the data at the buffer's 351266077Sdes * limit). 352266077Sdes * \param[in] buffer the buffer 353266077Sdes * \return the pointer 354266077Sdes */ 355266077SdesINLINE uint8_t * 356266077Sdessldns_buffer_end(sldns_buffer *buffer) 357266077Sdes{ 358266077Sdes return sldns_buffer_at(buffer, buffer->_limit); 359266077Sdes} 360266077Sdes 361266077Sdes/** 362266077Sdes * returns a pointer to the data at the buffer's current position. 363266077Sdes * \param[in] buffer the buffer 364266077Sdes * \return the pointer 365266077Sdes */ 366266077SdesINLINE uint8_t * 367266077Sdessldns_buffer_current(sldns_buffer *buffer) 368266077Sdes{ 369266077Sdes return sldns_buffer_at(buffer, buffer->_position); 370266077Sdes} 371266077Sdes 372266077Sdes/** 373266077Sdes * returns the number of bytes remaining between the indicated position and 374266077Sdes * the limit. 375266077Sdes * \param[in] buffer the buffer 376266077Sdes * \param[in] at indicated position 377266077Sdes * \return number of bytes 378266077Sdes */ 379266077SdesINLINE size_t 380266077Sdessldns_buffer_remaining_at(sldns_buffer *buffer, size_t at) 381266077Sdes{ 382266077Sdes sldns_buffer_invariant(buffer); 383266077Sdes assert(at <= buffer->_limit); 384356345Scy return at < buffer->_limit ? buffer->_limit - at : 0; 385266077Sdes} 386266077Sdes 387266077Sdes/** 388266077Sdes * returns the number of bytes remaining between the buffer's position and 389266077Sdes * limit. 390266077Sdes * \param[in] buffer the buffer 391266077Sdes * \return the number of bytes 392266077Sdes */ 393266077SdesINLINE size_t 394266077Sdessldns_buffer_remaining(sldns_buffer *buffer) 395266077Sdes{ 396266077Sdes return sldns_buffer_remaining_at(buffer, buffer->_position); 397266077Sdes} 398266077Sdes 399266077Sdes/** 400266077Sdes * checks if the buffer has at least COUNT more bytes available. 401266077Sdes * Before reading or writing the caller needs to ensure enough space 402266077Sdes * is available! 403266077Sdes * \param[in] buffer the buffer 404266077Sdes * \param[in] at indicated position 405266077Sdes * \param[in] count how much is available 406266077Sdes * \return true or false (as int?) 407266077Sdes */ 408266077SdesINLINE int 409266077Sdessldns_buffer_available_at(sldns_buffer *buffer, size_t at, size_t count) 410266077Sdes{ 411266077Sdes return count <= sldns_buffer_remaining_at(buffer, at); 412266077Sdes} 413266077Sdes 414266077Sdes/** 415266077Sdes * checks if the buffer has count bytes available at the current position 416266077Sdes * \param[in] buffer the buffer 417266077Sdes * \param[in] count how much is available 418266077Sdes * \return true or false (as int?) 419266077Sdes */ 420266077SdesINLINE int 421266077Sdessldns_buffer_available(sldns_buffer *buffer, size_t count) 422266077Sdes{ 423266077Sdes return sldns_buffer_available_at(buffer, buffer->_position, count); 424266077Sdes} 425266077Sdes 426266077Sdes/** 427266077Sdes * writes the given data to the buffer at the specified position 428266077Sdes * \param[in] buffer the buffer 429266077Sdes * \param[in] at the position (in number of bytes) to write the data at 430266077Sdes * \param[in] data pointer to the data to write to the buffer 431266077Sdes * \param[in] count the number of bytes of data to write 432266077Sdes */ 433266077SdesINLINE void 434266077Sdessldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count) 435266077Sdes{ 436266077Sdes assert(sldns_buffer_available_at(buffer, at, count)); 437266077Sdes memcpy(buffer->_data + at, data, count); 438266077Sdes} 439266077Sdes 440266077Sdes/** 441356345Scy * set the given byte to the buffer at the specified position 442356345Scy * \param[in] buffer the buffer 443356345Scy * \param[in] at the position (in number of bytes) to write the data at 444356345Scy * \param[in] c the byte to set to the buffer 445356345Scy * \param[in] count the number of bytes of bytes to write 446356345Scy */ 447356345Scy 448356345ScyINLINE void 449356345Scysldns_buffer_set_at(sldns_buffer *buffer, size_t at, int c, size_t count) 450356345Scy{ 451356345Scy assert(sldns_buffer_available_at(buffer, at, count)); 452356345Scy memset(buffer->_data + at, c, count); 453356345Scy} 454356345Scy 455356345Scy 456356345Scy/** 457266077Sdes * writes count bytes of data to the current position of the buffer 458266077Sdes * \param[in] buffer the buffer 459266077Sdes * \param[in] data the data to write 460356345Scy * \param[in] count the length of the data to write 461266077Sdes */ 462266077SdesINLINE void 463266077Sdessldns_buffer_write(sldns_buffer *buffer, const void *data, size_t count) 464266077Sdes{ 465266077Sdes sldns_buffer_write_at(buffer, buffer->_position, data, count); 466266077Sdes buffer->_position += count; 467266077Sdes} 468266077Sdes 469266077Sdes/** 470266077Sdes * copies the given (null-delimited) string to the specified position at the buffer 471266077Sdes * \param[in] buffer the buffer 472266077Sdes * \param[in] at the position in the buffer 473266077Sdes * \param[in] str the string to write 474266077Sdes */ 475266077SdesINLINE void 476266077Sdessldns_buffer_write_string_at(sldns_buffer *buffer, size_t at, const char *str) 477266077Sdes{ 478266077Sdes sldns_buffer_write_at(buffer, at, str, strlen(str)); 479266077Sdes} 480266077Sdes 481266077Sdes/** 482266077Sdes * copies the given (null-delimited) string to the current position at the buffer 483266077Sdes * \param[in] buffer the buffer 484266077Sdes * \param[in] str the string to write 485266077Sdes */ 486266077SdesINLINE void 487266077Sdessldns_buffer_write_string(sldns_buffer *buffer, const char *str) 488266077Sdes{ 489266077Sdes sldns_buffer_write(buffer, str, strlen(str)); 490266077Sdes} 491266077Sdes 492266077Sdes/** 493266077Sdes * writes the given byte of data at the given position in the buffer 494266077Sdes * \param[in] buffer the buffer 495266077Sdes * \param[in] at the position in the buffer 496266077Sdes * \param[in] data the 8 bits to write 497266077Sdes */ 498266077SdesINLINE void 499266077Sdessldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data) 500266077Sdes{ 501266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 502266077Sdes buffer->_data[at] = data; 503266077Sdes} 504266077Sdes 505266077Sdes/** 506266077Sdes * writes the given byte of data at the current position in the buffer 507266077Sdes * \param[in] buffer the buffer 508266077Sdes * \param[in] data the 8 bits to write 509266077Sdes */ 510266077SdesINLINE void 511266077Sdessldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data) 512266077Sdes{ 513266077Sdes sldns_buffer_write_u8_at(buffer, buffer->_position, data); 514266077Sdes buffer->_position += sizeof(data); 515266077Sdes} 516266077Sdes 517266077Sdes/** 518266077Sdes * writes the given 2 byte integer at the given position in the buffer 519266077Sdes * \param[in] buffer the buffer 520266077Sdes * \param[in] at the position in the buffer 521266077Sdes * \param[in] data the 16 bits to write 522266077Sdes */ 523266077SdesINLINE void 524266077Sdessldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data) 525266077Sdes{ 526266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 527266077Sdes sldns_write_uint16(buffer->_data + at, data); 528266077Sdes} 529266077Sdes 530266077Sdes/** 531266077Sdes * writes the given 2 byte integer at the current position in the buffer 532266077Sdes * \param[in] buffer the buffer 533266077Sdes * \param[in] data the 16 bits to write 534266077Sdes */ 535266077SdesINLINE void 536266077Sdessldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data) 537266077Sdes{ 538266077Sdes sldns_buffer_write_u16_at(buffer, buffer->_position, data); 539266077Sdes buffer->_position += sizeof(data); 540266077Sdes} 541266077Sdes 542266077Sdes/** 543266077Sdes * writes the given 4 byte integer at the given position in the buffer 544266077Sdes * \param[in] buffer the buffer 545266077Sdes * \param[in] at the position in the buffer 546266077Sdes * \param[in] data the 32 bits to write 547266077Sdes */ 548266077SdesINLINE void 549266077Sdessldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data) 550266077Sdes{ 551266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(data))); 552266077Sdes sldns_write_uint32(buffer->_data + at, data); 553266077Sdes} 554266077Sdes 555266077Sdes/** 556356345Scy * writes the given 6 byte integer at the given position in the buffer 557356345Scy * \param[in] buffer the buffer 558356345Scy * \param[in] at the position in the buffer 559356345Scy * \param[in] data the (lower) 48 bits to write 560356345Scy */ 561356345ScyINLINE void 562356345Scysldns_buffer_write_u48_at(sldns_buffer *buffer, size_t at, uint64_t data) 563356345Scy{ 564356345Scy assert(sldns_buffer_available_at(buffer, at, 6)); 565356345Scy sldns_write_uint48(buffer->_data + at, data); 566356345Scy} 567356345Scy 568356345Scy/** 569266077Sdes * writes the given 4 byte integer at the current position in the buffer 570266077Sdes * \param[in] buffer the buffer 571266077Sdes * \param[in] data the 32 bits to write 572266077Sdes */ 573266077SdesINLINE void 574266077Sdessldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data) 575266077Sdes{ 576266077Sdes sldns_buffer_write_u32_at(buffer, buffer->_position, data); 577266077Sdes buffer->_position += sizeof(data); 578266077Sdes} 579266077Sdes 580266077Sdes/** 581356345Scy * writes the given 6 byte integer at the current position in the buffer 582356345Scy * \param[in] buffer the buffer 583356345Scy * \param[in] data the 48 bits to write 584356345Scy */ 585356345ScyINLINE void 586356345Scysldns_buffer_write_u48(sldns_buffer *buffer, uint64_t data) 587356345Scy{ 588356345Scy sldns_buffer_write_u48_at(buffer, buffer->_position, data); 589356345Scy buffer->_position += 6; 590356345Scy} 591356345Scy 592356345Scy/** 593266077Sdes * copies count bytes of data at the given position to the given data-array 594266077Sdes * \param[in] buffer the buffer 595266077Sdes * \param[in] at the position in the buffer to start 596266077Sdes * \param[out] data buffer to copy to 597266077Sdes * \param[in] count the length of the data to copy 598266077Sdes */ 599266077SdesINLINE void 600266077Sdessldns_buffer_read_at(sldns_buffer *buffer, size_t at, void *data, size_t count) 601266077Sdes{ 602266077Sdes assert(sldns_buffer_available_at(buffer, at, count)); 603266077Sdes memcpy(data, buffer->_data + at, count); 604266077Sdes} 605266077Sdes 606266077Sdes/** 607266077Sdes * copies count bytes of data at the current position to the given data-array 608266077Sdes * \param[in] buffer the buffer 609266077Sdes * \param[out] data buffer to copy to 610266077Sdes * \param[in] count the length of the data to copy 611266077Sdes */ 612266077SdesINLINE void 613266077Sdessldns_buffer_read(sldns_buffer *buffer, void *data, size_t count) 614266077Sdes{ 615266077Sdes sldns_buffer_read_at(buffer, buffer->_position, data, count); 616266077Sdes buffer->_position += count; 617266077Sdes} 618266077Sdes 619266077Sdes/** 620266077Sdes * returns the byte value at the given position in the buffer 621266077Sdes * \param[in] buffer the buffer 622266077Sdes * \param[in] at the position in the buffer 623266077Sdes * \return 1 byte integer 624266077Sdes */ 625266077SdesINLINE uint8_t 626266077Sdessldns_buffer_read_u8_at(sldns_buffer *buffer, size_t at) 627266077Sdes{ 628266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint8_t))); 629266077Sdes return buffer->_data[at]; 630266077Sdes} 631266077Sdes 632266077Sdes/** 633266077Sdes * returns the byte value at the current position in the buffer 634266077Sdes * \param[in] buffer the buffer 635266077Sdes * \return 1 byte integer 636266077Sdes */ 637266077SdesINLINE uint8_t 638266077Sdessldns_buffer_read_u8(sldns_buffer *buffer) 639266077Sdes{ 640266077Sdes uint8_t result = sldns_buffer_read_u8_at(buffer, buffer->_position); 641266077Sdes buffer->_position += sizeof(uint8_t); 642266077Sdes return result; 643266077Sdes} 644266077Sdes 645266077Sdes/** 646266077Sdes * returns the 2-byte integer value at the given position in the buffer 647266077Sdes * \param[in] buffer the buffer 648266077Sdes * \param[in] at position in the buffer 649266077Sdes * \return 2 byte integer 650266077Sdes */ 651266077SdesINLINE uint16_t 652266077Sdessldns_buffer_read_u16_at(sldns_buffer *buffer, size_t at) 653266077Sdes{ 654266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint16_t))); 655266077Sdes return sldns_read_uint16(buffer->_data + at); 656266077Sdes} 657266077Sdes 658266077Sdes/** 659266077Sdes * returns the 2-byte integer value at the current position in the buffer 660266077Sdes * \param[in] buffer the buffer 661266077Sdes * \return 2 byte integer 662266077Sdes */ 663266077SdesINLINE uint16_t 664266077Sdessldns_buffer_read_u16(sldns_buffer *buffer) 665266077Sdes{ 666266077Sdes uint16_t result = sldns_buffer_read_u16_at(buffer, buffer->_position); 667266077Sdes buffer->_position += sizeof(uint16_t); 668266077Sdes return result; 669266077Sdes} 670266077Sdes 671266077Sdes/** 672266077Sdes * returns the 4-byte integer value at the given position in the buffer 673266077Sdes * \param[in] buffer the buffer 674266077Sdes * \param[in] at position in the buffer 675266077Sdes * \return 4 byte integer 676266077Sdes */ 677266077SdesINLINE uint32_t 678266077Sdessldns_buffer_read_u32_at(sldns_buffer *buffer, size_t at) 679266077Sdes{ 680266077Sdes assert(sldns_buffer_available_at(buffer, at, sizeof(uint32_t))); 681266077Sdes return sldns_read_uint32(buffer->_data + at); 682266077Sdes} 683266077Sdes 684266077Sdes/** 685266077Sdes * returns the 4-byte integer value at the current position in the buffer 686266077Sdes * \param[in] buffer the buffer 687266077Sdes * \return 4 byte integer 688266077Sdes */ 689266077SdesINLINE uint32_t 690266077Sdessldns_buffer_read_u32(sldns_buffer *buffer) 691266077Sdes{ 692266077Sdes uint32_t result = sldns_buffer_read_u32_at(buffer, buffer->_position); 693266077Sdes buffer->_position += sizeof(uint32_t); 694266077Sdes return result; 695266077Sdes} 696266077Sdes 697266077Sdes/** 698266077Sdes * returns the status of the buffer 699266077Sdes * \param[in] buffer 700266077Sdes * \return the status 701266077Sdes */ 702266077SdesINLINE int 703266077Sdessldns_buffer_status(sldns_buffer *buffer) 704266077Sdes{ 705266077Sdes return (int)buffer->_status_err; 706266077Sdes} 707266077Sdes 708266077Sdes/** 709266077Sdes * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise 710266077Sdes * \param[in] buffer the buffer 711266077Sdes * \return true or false 712266077Sdes */ 713266077SdesINLINE int 714266077Sdessldns_buffer_status_ok(sldns_buffer *buffer) 715266077Sdes{ 716266077Sdes if (buffer) { 717266077Sdes return sldns_buffer_status(buffer) == 0; 718266077Sdes } else { 719266077Sdes return 0; 720266077Sdes } 721266077Sdes} 722266077Sdes 723266077Sdes/** 724266077Sdes * prints to the buffer, increasing the capacity if required using 725266077Sdes * buffer_reserve(). The buffer's position is set to the terminating '\\0' 726266077Sdes * Returns the number of characters written (not including the 727266077Sdes * terminating '\\0') or -1 on failure. 728266077Sdes */ 729266077Sdesint sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) 730266077Sdes ATTR_FORMAT(printf, 2, 3); 731266077Sdes 732266077Sdes/** 733266077Sdes * frees the buffer. 734266077Sdes * \param[in] *buffer the buffer to be freed 735266077Sdes * \return void 736266077Sdes */ 737266077Sdesvoid sldns_buffer_free(sldns_buffer *buffer); 738266077Sdes 739266077Sdes/** 740266077Sdes * Copy contents of the from buffer to the result buffer and then flips 741266077Sdes * the result buffer. Data will be silently truncated if the result buffer is 742266077Sdes * too small. 743266077Sdes * \param[out] *result resulting buffer which is copied to. 744266077Sdes * \param[in] *from what to copy to result. 745266077Sdes */ 746266077Sdesvoid sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from); 747266077Sdes 748266077Sdes#ifdef __cplusplus 749266077Sdes} 750266077Sdes#endif 751266077Sdes 752266077Sdes#endif /* LDNS_SBUFFER_H */ 753