"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/lwres/lwbuffer.c" (7 Sep 2020, 9505 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lwbuffer.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file */
   13 
   14 /**
   15  *    These functions provide bounds checked access to a region of memory
   16  *    where data is being read or written. They are based on, and similar
   17  *    to, the isc_buffer_ functions in the ISC library.
   18  *
   19  *    A buffer is a region of memory, together with a set of related
   20  *    subregions. The used region and the available region are disjoint, and
   21  *    their union is the buffer's region. The used region extends from the
   22  *    beginning of the buffer region to the last used byte. The available
   23  *    region extends from one byte greater than the last used byte to the
   24  *    end of the buffer's region. The size of the used region can be changed
   25  *    using various buffer commands. Initially, the used region is empty.
   26  *
   27  *    The used region is further subdivided into two disjoint regions: the
   28  *    consumed region and the remaining region. The union of these two
   29  *    regions is the used region. The consumed region extends from the
   30  *    beginning of the used region to the byte before the current offset (if
   31  *    any). The remaining region the current pointer to the end of the used
   32  *    region. The size of the consumed region can be changed using various
   33  *    buffer commands. Initially, the consumed region is empty.
   34  *
   35  *    The active region is an (optional) subregion of the remaining region.
   36  *    It extends from the current offset to an offset in the remaining
   37  *    region. Initially, the active region is empty. If the current offset
   38  *    advances beyond the chosen offset, the active region will also be
   39  *    empty.
   40  *
   41  *
   42  * \verbatim
   43  *    /------------entire length---------------\\
   44  *    /----- used region -----\\/-- available --\\
   45  *    +----------------------------------------+
   46  *    | consumed  | remaining |                |
   47  *    +----------------------------------------+
   48  *    a           b     c     d                e
   49  *
   50  *   a == base of buffer.
   51  *   b == current pointer.  Can be anywhere between a and d.
   52  *   c == active pointer.  Meaningful between b and d.
   53  *   d == used pointer.
   54  *   e == length of buffer.
   55  *
   56  *   a-e == entire length of buffer.
   57  *   a-d == used region.
   58  *   a-b == consumed region.
   59  *   b-d == remaining region.
   60  *   b-c == optional active region.
   61  * \endverbatim
   62  *
   63  *    lwres_buffer_init() initializes the lwres_buffer_t *b and associates it
   64  *    with the memory region of size length bytes starting at location base.
   65  *
   66  *    lwres_buffer_invalidate() marks the buffer *b as invalid. Invalidating
   67  *    a buffer after use is not required, but makes it possible to catch its
   68  *    possible accidental use.
   69  *
   70  *    The functions lwres_buffer_add() and lwres_buffer_subtract()
   71  *    respectively increase and decrease the used space in buffer *b by n
   72  *    bytes. lwres_buffer_add() checks for buffer overflow and
   73  *    lwres_buffer_subtract() checks for underflow. These functions do not
   74  *    allocate or deallocate memory. They just change the value of used.
   75  *
   76  *    A buffer is re-initialised by lwres_buffer_clear(). The function sets
   77  *    used , current and active to zero.
   78  *
   79  *    lwres_buffer_first() makes the consumed region of buffer *p empty by
   80  *    setting current to zero (the start of the buffer).
   81  *
   82  *    lwres_buffer_forward() increases the consumed region of buffer *b by n
   83  *    bytes, checking for overflow. Similarly, lwres_buffer_back() decreases
   84  *    buffer b's consumed region by n bytes and checks for underflow.
   85  *
   86  *    lwres_buffer_getuint8() reads an unsigned 8-bit integer from *b and
   87  *    returns it. lwres_buffer_putuint8() writes the unsigned 8-bit integer
   88  *    val to buffer *b.
   89  *
   90  *    lwres_buffer_getuint16() and lwres_buffer_getuint32() are identical to
   91  *    lwres_buffer_putuint8() except that they respectively read an unsigned
   92  *    16-bit or 32-bit integer in network byte order from b. Similarly,
   93  *    lwres_buffer_putuint16() and lwres_buffer_putuint32() writes the
   94  *    unsigned 16-bit or 32-bit integer val to buffer b, in network byte
   95  *    order.
   96  *
   97  *    Arbitrary amounts of data are read or written from a lightweight
   98  *    resolver buffer with lwres_buffer_getmem() and lwres_buffer_putmem()
   99  *    respectively. lwres_buffer_putmem() copies length bytes of memory at
  100  *    base to b. Conversely, lwres_buffer_getmem() copies length bytes of
  101  *    memory from b to base.
  102  */
  103 
  104 #include <config.h>
  105 
  106 #include <inttypes.h>
  107 #include <string.h>
  108 
  109 #include <lwres/lwbuffer.h>
  110 
  111 #include "assert_p.h"
  112 
  113 void
  114 lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length)
  115 {
  116     /*
  117      * Make 'b' refer to the 'length'-byte region starting at base.
  118      */
  119 
  120     REQUIRE(b != NULL);
  121 
  122     b->magic = LWRES_BUFFER_MAGIC;
  123     b->base = base;
  124     b->length = length;
  125     b->used = 0;
  126     b->current = 0;
  127     b->active = 0;
  128 }
  129 
  130 /*  Make 'b' an invalid buffer. */
  131 void
  132 lwres_buffer_invalidate(lwres_buffer_t *b)
  133 {
  134 
  135     REQUIRE(LWRES_BUFFER_VALID(b));
  136 
  137     b->magic = 0;
  138     b->base = NULL;
  139     b->length = 0;
  140     b->used = 0;
  141     b->current = 0;
  142     b->active = 0;
  143 }
  144 
  145 /* Increase the 'used' region of 'b' by 'n' bytes. */
  146 void
  147 lwres_buffer_add(lwres_buffer_t *b, unsigned int n)
  148 {
  149 
  150     REQUIRE(LWRES_BUFFER_VALID(b));
  151     REQUIRE(b->used + n <= b->length);
  152 
  153     b->used += n;
  154 }
  155 
  156 /* Decrease the 'used' region of 'b' by 'n' bytes. */
  157 void
  158 lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n)
  159 {
  160 
  161     REQUIRE(LWRES_BUFFER_VALID(b));
  162     REQUIRE(b->used >= n);
  163 
  164     b->used -= n;
  165     if (b->current > b->used)
  166         b->current = b->used;
  167     if (b->active > b->used)
  168         b->active = b->used;
  169 }
  170 
  171 /* Make the used region empty. */
  172 void
  173 lwres_buffer_clear(lwres_buffer_t *b)
  174 {
  175 
  176     REQUIRE(LWRES_BUFFER_VALID(b));
  177 
  178     b->used = 0;
  179     b->current = 0;
  180     b->active = 0;
  181 }
  182 
  183 /* Make the consumed region empty. */
  184 void
  185 lwres_buffer_first(lwres_buffer_t *b)
  186 {
  187 
  188     REQUIRE(LWRES_BUFFER_VALID(b));
  189 
  190     b->current = 0;
  191 }
  192 
  193 /* Increase the 'consumed' region of 'b' by 'n' bytes. */
  194 void
  195 lwres_buffer_forward(lwres_buffer_t *b, unsigned int n)
  196 {
  197 
  198     REQUIRE(LWRES_BUFFER_VALID(b));
  199     REQUIRE(b->current + n <= b->used);
  200 
  201     b->current += n;
  202 }
  203 
  204 /* Decrease the 'consumed' region of 'b' by 'n' bytes. */
  205 void
  206 lwres_buffer_back(lwres_buffer_t *b, unsigned int n)
  207 {
  208 
  209     REQUIRE(LWRES_BUFFER_VALID(b));
  210     REQUIRE(n <= b->current);
  211 
  212     b->current -= n;
  213 }
  214 
  215 /* Read an unsigned 8-bit integer from 'b' and return it. */
  216 uint8_t
  217 lwres_buffer_getuint8(lwres_buffer_t *b)
  218 {
  219     unsigned char *cp;
  220     uint8_t result;
  221 
  222 
  223     REQUIRE(LWRES_BUFFER_VALID(b));
  224     REQUIRE(b->used - b->current >= 1);
  225 
  226     cp = b->base;
  227     cp += b->current;
  228     b->current += 1;
  229     result = ((unsigned int)(cp[0]));
  230 
  231     return (result);
  232 }
  233 
  234 /* Put an unsigned 8-bit integer */
  235 void
  236 lwres_buffer_putuint8(lwres_buffer_t *b, uint8_t val)
  237 {
  238     unsigned char *cp;
  239 
  240     REQUIRE(LWRES_BUFFER_VALID(b));
  241     REQUIRE(b->used + 1 <= b->length);
  242 
  243     cp = b->base;
  244     cp += b->used;
  245     b->used += 1;
  246     cp[0] = (val & 0x00ff);
  247 }
  248 
  249 /*  Read an unsigned 16-bit integer in network byte order from 'b', convert it to host byte order, and return it. */
  250 uint16_t
  251 lwres_buffer_getuint16(lwres_buffer_t *b)
  252 {
  253     unsigned char *cp;
  254     uint16_t result;
  255 
  256 
  257     REQUIRE(LWRES_BUFFER_VALID(b));
  258     REQUIRE(b->used - b->current >= 2);
  259 
  260     cp = b->base;
  261     cp += b->current;
  262     b->current += 2;
  263     result = ((unsigned int)(cp[0])) << 8;
  264     result |= ((unsigned int)(cp[1]));
  265 
  266     return (result);
  267 }
  268 
  269 /* Put an unsigned 16-bit integer. */
  270 void
  271 lwres_buffer_putuint16(lwres_buffer_t *b, uint16_t val)
  272 {
  273     unsigned char *cp;
  274 
  275     REQUIRE(LWRES_BUFFER_VALID(b));
  276     REQUIRE(b->used + 2 <= b->length);
  277 
  278     cp = b->base;
  279     cp += b->used;
  280     b->used += 2;
  281     cp[0] = (val & 0xff00) >> 8;
  282     cp[1] = (val & 0x00ff);
  283 }
  284 
  285 /*  Read an unsigned 32-bit integer in network byte order from 'b', convert it to host byte order, and return it. */
  286 uint32_t
  287 lwres_buffer_getuint32(lwres_buffer_t *b)
  288 {
  289     unsigned char *cp;
  290     uint32_t result;
  291 
  292     REQUIRE(LWRES_BUFFER_VALID(b));
  293     REQUIRE(b->used - b->current >= 4);
  294 
  295     cp = b->base;
  296     cp += b->current;
  297     b->current += 4;
  298     result = ((unsigned int)(cp[0])) << 24;
  299     result |= ((unsigned int)(cp[1])) << 16;
  300     result |= ((unsigned int)(cp[2])) << 8;
  301     result |= ((unsigned int)(cp[3]));
  302 
  303     return (result);
  304 }
  305 
  306 /* Put an unsigned 32-bit integer. */
  307 void
  308 lwres_buffer_putuint32(lwres_buffer_t *b, uint32_t val)
  309 {
  310     unsigned char *cp;
  311 
  312     REQUIRE(LWRES_BUFFER_VALID(b));
  313     REQUIRE(b->used + 4 <= b->length);
  314 
  315     cp = b->base;
  316     cp += b->used;
  317     b->used += 4;
  318     cp[0] = (unsigned char)((val & 0xff000000) >> 24);
  319     cp[1] = (unsigned char)((val & 0x00ff0000) >> 16);
  320     cp[2] = (unsigned char)((val & 0x0000ff00) >> 8);
  321     cp[3] = (unsigned char)(val & 0x000000ff);
  322 }
  323 
  324 /* copies length bytes of memory at base to b */
  325 void
  326 lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
  327             unsigned int length)
  328 {
  329     unsigned char *cp;
  330 
  331     REQUIRE(LWRES_BUFFER_VALID(b));
  332     REQUIRE(b->used + length <= b->length);
  333 
  334     cp = (unsigned char *)b->base + b->used;
  335     memmove(cp, base, length);
  336     b->used += length;
  337 }
  338 
  339 /* copies length bytes of memory at b to base */
  340 void
  341 lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
  342             unsigned int length)
  343 {
  344     unsigned char *cp;
  345 
  346     REQUIRE(LWRES_BUFFER_VALID(b));
  347     REQUIRE(b->used - b->current >= length);
  348 
  349     cp = b->base;
  350     cp += b->current;
  351     b->current += length;
  352 
  353     memmove(base, cp, length);
  354 }