buffer.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2008, 2010, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1998-2002  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 #ifndef ISC_BUFFER_H
00019 #define ISC_BUFFER_H 1
00020 
00021 /*****
00022  ***** Module Info
00023  *****/
00024 
00025 /*! \file isc/buffer.h
00026  *
00027  * \brief A buffer is a region of memory, together with a set of related subregions.
00028  * Buffers are used for parsing and I/O operations.
00029  *
00030  * The 'used region' and the 'available' region are disjoint, and their
00031  * union is the buffer's region.  The used region extends from the beginning
00032  * of the buffer region to the last used byte.  The available region
00033  * extends from one byte greater than the last used byte to the end of the
00034  * buffer's region.  The size of the used region can be changed using various
00035  * buffer commands.  Initially, the used region is empty.
00036  *
00037  * The used region is further subdivided into two disjoint regions: the
00038  * 'consumed region' and the 'remaining region'.  The union of these two
00039  * regions is the used region.  The consumed region extends from the beginning
00040  * of the used region to the byte before the 'current' offset (if any).  The
00041  * 'remaining' region the current pointer to the end of the used
00042  * region.  The size of the consumed region can be changed using various
00043  * buffer commands.  Initially, the consumed region is empty.
00044  *
00045  * The 'active region' is an (optional) subregion of the remaining region.
00046  * It extends from the current offset to an offset in the remaining region
00047  * that is selected with isc_buffer_setactive().  Initially, the active region
00048  * is empty.  If the current offset advances beyond the chosen offset, the
00049  * active region will also be empty.
00050  *
00051  * \verbatim
00052  *  /------------entire length---------------\
00053  *  /----- used region -----\/-- available --\
00054  *  +----------------------------------------+
00055  *  | consumed  | remaining |                |
00056  *  +----------------------------------------+
00057  *  a           b     c     d                e
00058  *
00059  * a == base of buffer.
00060  * b == current pointer.  Can be anywhere between a and d.
00061  * c == active pointer.  Meaningful between b and d.
00062  * d == used pointer.
00063  * e == length of buffer.
00064  *
00065  * a-e == entire length of buffer.
00066  * a-d == used region.
00067  * a-b == consumed region.
00068  * b-d == remaining region.
00069  * b-c == optional active region.
00070  *\endverbatim
00071  *
00072  * The following invariants are maintained by all routines:
00073  *
00074  *\code
00075  *      length > 0
00076  *
00077  *      base is a valid pointer to length bytes of memory
00078  *
00079  *      0 <= used <= length
00080  *
00081  *      0 <= current <= used
00082  *
00083  *      0 <= active <= used
00084  *      (although active < current implies empty active region)
00085  *\endcode
00086  *
00087  * \li MP:
00088  *      Buffers have no synchronization.  Clients must ensure exclusive
00089  *      access.
00090  *
00091  * \li Reliability:
00092  *      No anticipated impact.
00093  *
00094  * \li Resources:
00095  *      Memory: 1 pointer + 6 unsigned integers per buffer.
00096  *
00097  * \li Security:
00098  *      No anticipated impact.
00099  *
00100  * \li Standards:
00101  *      None.
00102  */
00103 
00104 /***
00105  *** Imports
00106  ***/
00107 
00108 #include <isc/lang.h>
00109 #include <isc/magic.h>
00110 #include <isc/types.h>
00111 
00112 /*!
00113  * To make many functions be inline macros (via \#define) define this.
00114  * If it is undefined, a function will be used.
00115  */
00116 /* #define ISC_BUFFER_USEINLINE */
00117 
00118 ISC_LANG_BEGINDECLS
00119 
00120 /*@{*/
00121 /*!
00122  *** Magic numbers
00123  ***/
00124 #define ISC_BUFFER_MAGIC                0x42756621U     /* Buf!. */
00125 #define ISC_BUFFER_VALID(b)             ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
00126 /*@}*/
00127 
00128 /*!
00129  * Size granularity for dynamically resizeable buffers; when reserving
00130  * space in a buffer, we round the allocated buffer length up to the
00131  * nearest * multiple of this value.
00132  */
00133 #define ISC_BUFFER_INCR 2048
00134 
00135 /*
00136  * The following macros MUST be used only on valid buffers.  It is the
00137  * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
00138  * check above, or by calling another isc_buffer_*() function (rather than
00139  * another macro.)
00140  */
00141 
00142 /*@{*/
00143 /*!
00144  * Fundamental buffer elements.  (A through E in the introductory comment.)
00145  */
00146 #define isc_buffer_base(b)    ((void *)(b)->base)                         /*a*/
00147 #define isc_buffer_current(b) \
00148                 ((void *)((unsigned char *)(b)->base + (b)->current))     /*b*/
00149 #define isc_buffer_active(b)  \
00150                 ((void *)((unsigned char *)(b)->base + (b)->active))      /*c*/
00151 #define isc_buffer_used(b)    \
00152                 ((void *)((unsigned char *)(b)->base + (b)->used))        /*d*/
00153 #define isc_buffer_length(b)  ((b)->length)                               /*e*/
00154 /*@}*/
00155 
00156 /*@{*/
00157 /*!
00158  * Derived lengths.  (Described in the introductory comment.)
00159  */
00160 #define isc_buffer_usedlength(b)        ((b)->used)                   /* d-a */
00161 #define isc_buffer_consumedlength(b)    ((b)->current)                /* b-a */
00162 #define isc_buffer_remaininglength(b)   ((b)->used - (b)->current)    /* d-b */
00163 #define isc_buffer_activelength(b)      ((b)->active - (b)->current)  /* c-b */
00164 #define isc_buffer_availablelength(b)   ((b)->length - (b)->used)     /* e-d */
00165 /*@}*/
00166 
00167 /*!
00168  * Note that the buffer structure is public.  This is principally so buffer
00169  * operations can be implemented using macros.  Applications are strongly
00170  * discouraged from directly manipulating the structure.
00171  */
00172 
00173 struct isc_buffer {
00174         unsigned int            magic;
00175         void                   *base;
00176         /*@{*/
00177         /*! The following integers are byte offsets from 'base'. */
00178         unsigned int            length;
00179         unsigned int            used;
00180         unsigned int            current;
00181         unsigned int            active;
00182         /*@}*/
00183         /*! linkable */
00184         ISC_LINK(isc_buffer_t)  link;
00185         /*! private internal elements */
00186         isc_mem_t              *mctx;
00187 };
00188 
00189 /***
00190  *** Functions
00191  ***/
00192 
00193 isc_result_t
00194 isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
00195                     unsigned int length);
00196 /*!<
00197  * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
00198  * data region.
00199  *
00200  * Requires:
00201  *\li   "mctx" is valid.
00202  *
00203  *\li   "dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
00204  *
00205  * Returns:
00206  *\li   ISC_R_SUCCESS           - success
00207  *\li   ISC_R_NOMEMORY          - no memory available
00208  *
00209  * Note:
00210  *\li   Changing the buffer's length field is not permitted.
00211  */
00212 
00213 isc_result_t
00214 isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length);
00215 /*!<
00216  * \brief Reallocate the buffer to be "length" bytes long. The buffer
00217  * pointer may move when you call this function.
00218  *
00219  * Requires:
00220  *\li   "dynbuffer" is not NULL.
00221  *
00222  *\li   "*dynbuffer" is a valid dynamic buffer.
00223  *
00224  *\li   'length' > current length of buffer.
00225  *
00226  * Returns:
00227  *\li   ISC_R_SUCCESS           - success
00228  *\li   ISC_R_NOMEMORY          - no memory available
00229  *
00230  * Ensures:
00231  *\li   "*dynbuffer" will be valid on return and will contain all the
00232  *      original data. However, the buffer pointer may be moved during
00233  *      reallocation.
00234  */
00235 
00236 isc_result_t
00237 isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size);
00238 /*!<
00239  * \brief Make "size" bytes of space available in the buffer. The buffer
00240  * pointer may move when you call this function.
00241  *
00242  * Requires:
00243  *\li   "dynbuffer" is not NULL.
00244  *
00245  *\li   "*dynbuffer" is a valid dynamic buffer.
00246  *
00247  * Returns:
00248  *\li   ISC_R_SUCCESS           - success
00249  *\li   ISC_R_NOMEMORY          - no memory available
00250  *
00251  * Ensures:
00252  *\li   "*dynbuffer" will be valid on return and will contain all the
00253  *      original data. However, the buffer pointer may be moved during
00254  *      reallocation.
00255  */
00256 
00257 void
00258 isc_buffer_free(isc_buffer_t **dynbuffer);
00259 /*!<
00260  * \brief Release resources allocated for a dynamic buffer.
00261  *
00262  * Requires:
00263  *\li   "dynbuffer" is not NULL.
00264  *
00265  *\li   "*dynbuffer" is a valid dynamic buffer.
00266  *
00267  * Ensures:
00268  *\li   "*dynbuffer" will be NULL on return, and all memory associated with
00269  *      the dynamic buffer is returned to the memory context used in
00270  *      isc_buffer_allocate().
00271  */
00272 
00273 void
00274 isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
00275 /*!<
00276  * \brief Make 'b' refer to the 'length'-byte region starting at base.
00277  *
00278  * Requires:
00279  *
00280  *\li   'length' > 0
00281  *
00282  *\li   'base' is a pointer to a sequence of 'length' bytes.
00283  *
00284  */
00285 
00286 void
00287 isc__buffer_initnull(isc_buffer_t *b);
00288 /*!<
00289  *\brief Initialize a buffer 'b' with a null data and zero length/
00290  */
00291 
00292 void
00293 isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length);
00294 /*!<
00295  * \brief Make 'b' refer to the 'length'-byte region starting at base.
00296  * Any existing data will be copied.
00297  *
00298  * Requires:
00299  *
00300  *\li   'length' > 0 AND length >= previous length
00301  *
00302  *\li   'base' is a pointer to a sequence of 'length' bytes.
00303  *
00304  */
00305 
00306 void
00307 isc__buffer_invalidate(isc_buffer_t *b);
00308 /*!<
00309  * \brief Make 'b' an invalid buffer.
00310  *
00311  * Requires:
00312  *\li   'b' is a valid buffer.
00313  *
00314  * Ensures:
00315  *\li   If assertion checking is enabled, future attempts to use 'b' without
00316  *      calling isc_buffer_init() on it will cause an assertion failure.
00317  */
00318 
00319 void
00320 isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
00321 /*!<
00322  * \brief Make 'r' refer to the region of 'b'.
00323  *
00324  * Requires:
00325  *
00326  *\li   'b' is a valid buffer.
00327  *
00328  *\li   'r' points to a region structure.
00329  */
00330 
00331 void
00332 isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
00333 /*!<
00334  * \brief Make 'r' refer to the used region of 'b'.
00335  *
00336  * Requires:
00337  *
00338  *\li   'b' is a valid buffer.
00339  *
00340  *\li   'r' points to a region structure.
00341  */
00342 
00343 void
00344 isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
00345 /*!<
00346  * \brief Make 'r' refer to the available region of 'b'.
00347  *
00348  * Requires:
00349  *
00350  *\li   'b' is a valid buffer.
00351  *
00352  *\li   'r' points to a region structure.
00353  */
00354 
00355 void
00356 isc__buffer_add(isc_buffer_t *b, unsigned int n);
00357 /*!<
00358  * \brief Increase the 'used' region of 'b' by 'n' bytes.
00359  *
00360  * Requires:
00361  *
00362  *\li   'b' is a valid buffer
00363  *
00364  *\li   used + n <= length
00365  *
00366  */
00367 
00368 void
00369 isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
00370 /*!<
00371  * \brief Decrease the 'used' region of 'b' by 'n' bytes.
00372  *
00373  * Requires:
00374  *
00375  *\li   'b' is a valid buffer
00376  *
00377  *\li   used >= n
00378  *
00379  */
00380 
00381 void
00382 isc__buffer_clear(isc_buffer_t *b);
00383 /*!<
00384  * \brief Make the used region empty.
00385  *
00386  * Requires:
00387  *
00388  *\li   'b' is a valid buffer
00389  *
00390  * Ensures:
00391  *
00392  *\li   used = 0
00393  *
00394  */
00395 
00396 void
00397 isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
00398 /*!<
00399  * \brief Make 'r' refer to the consumed region of 'b'.
00400  *
00401  * Requires:
00402  *
00403  *\li   'b' is a valid buffer.
00404  *
00405  *\li   'r' points to a region structure.
00406  */
00407 
00408 void
00409 isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
00410 /*!<
00411  * \brief Make 'r' refer to the remaining region of 'b'.
00412  *
00413  * Requires:
00414  *
00415  *\li   'b' is a valid buffer.
00416  *
00417  *\li   'r' points to a region structure.
00418  */
00419 
00420 void
00421 isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
00422 /*!<
00423  * \brief Make 'r' refer to the active region of 'b'.
00424  *
00425  * Requires:
00426  *
00427  *\li   'b' is a valid buffer.
00428  *
00429  *\li   'r' points to a region structure.
00430  */
00431 
00432 void
00433 isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
00434 /*!<
00435  * \brief Sets the end of the active region 'n' bytes after current.
00436  *
00437  * Requires:
00438  *
00439  *\li   'b' is a valid buffer.
00440  *
00441  *\li   current + n <= used
00442  */
00443 
00444 void
00445 isc__buffer_first(isc_buffer_t *b);
00446 /*!<
00447  * \brief Make the consumed region empty.
00448  *
00449  * Requires:
00450  *
00451  *\li   'b' is a valid buffer
00452  *
00453  * Ensures:
00454  *
00455  *\li   current == 0
00456  *
00457  */
00458 
00459 void
00460 isc__buffer_forward(isc_buffer_t *b, unsigned int n);
00461 /*!<
00462  * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
00463  *
00464  * Requires:
00465  *
00466  *\li   'b' is a valid buffer
00467  *
00468  *\li   current + n <= used
00469  *
00470  */
00471 
00472 void
00473 isc__buffer_back(isc_buffer_t *b, unsigned int n);
00474 /*!<
00475  * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
00476  *
00477  * Requires:
00478  *
00479  *\li   'b' is a valid buffer
00480  *
00481  *\li   n <= current
00482  *
00483  */
00484 
00485 void
00486 isc_buffer_compact(isc_buffer_t *b);
00487 /*!<
00488  * \brief Compact the used region by moving the remaining region so it occurs
00489  * at the start of the buffer.  The used region is shrunk by the size of
00490  * the consumed region, and the consumed region is then made empty.
00491  *
00492  * Requires:
00493  *
00494  *\li   'b' is a valid buffer
00495  *
00496  * Ensures:
00497  *
00498  *\li   current == 0
00499  *
00500  *\li   The size of the used region is now equal to the size of the remaining
00501  *      region (as it was before the call).  The contents of the used region
00502  *      are those of the remaining region (as it was before the call).
00503  */
00504 
00505 isc_uint8_t
00506 isc_buffer_getuint8(isc_buffer_t *b);
00507 /*!<
00508  * \brief Read an unsigned 8-bit integer from 'b' and return it.
00509  *
00510  * Requires:
00511  *
00512  *\li   'b' is a valid buffer.
00513  *
00514  *\li   The length of the available region of 'b' is at least 1.
00515  *
00516  * Ensures:
00517  *
00518  *\li   The current pointer in 'b' is advanced by 1.
00519  *
00520  * Returns:
00521  *
00522  *\li   A 8-bit unsigned integer.
00523  */
00524 
00525 void
00526 isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
00527 /*!<
00528  * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
00529  *
00530  * Requires:
00531  *\li   'b' is a valid buffer.
00532  *
00533  *\li   The length of the unused region of 'b' is at least 1.
00534  *
00535  * Ensures:
00536  *\li   The used pointer in 'b' is advanced by 1.
00537  */
00538 
00539 isc_uint16_t
00540 isc_buffer_getuint16(isc_buffer_t *b);
00541 /*!<
00542  * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
00543  * it to host byte order, and return it.
00544  *
00545  * Requires:
00546  *
00547  *\li   'b' is a valid buffer.
00548  *
00549  *\li   The length of the available region of 'b' is at least 2.
00550  *
00551  * Ensures:
00552  *
00553  *\li   The current pointer in 'b' is advanced by 2.
00554  *
00555  * Returns:
00556  *
00557  *\li   A 16-bit unsigned integer.
00558  */
00559 
00560 void
00561 isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
00562 /*!<
00563  * \brief Store an unsigned 16-bit integer in host byte order from 'val'
00564  * into 'b' in network byte order.
00565  *
00566  * Requires:
00567  *\li   'b' is a valid buffer.
00568  *
00569  *\li   The length of the unused region of 'b' is at least 2.
00570  *
00571  * Ensures:
00572  *\li   The used pointer in 'b' is advanced by 2.
00573  */
00574 
00575 isc_uint32_t
00576 isc_buffer_getuint32(isc_buffer_t *b);
00577 /*!<
00578  * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
00579  * it to host byte order, and return it.
00580  *
00581  * Requires:
00582  *
00583  *\li   'b' is a valid buffer.
00584  *
00585  *\li   The length of the available region of 'b' is at least 4.
00586  *
00587  * Ensures:
00588  *
00589  *\li   The current pointer in 'b' is advanced by 4.
00590  *
00591  * Returns:
00592  *
00593  *\li   A 32-bit unsigned integer.
00594  */
00595 
00596 void
00597 isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
00598 /*!<
00599  * \brief Store an unsigned 32-bit integer in host byte order from 'val'
00600  * into 'b' in network byte order.
00601  *
00602  * Requires:
00603  *\li   'b' is a valid buffer.
00604  *
00605  *\li   The length of the unused region of 'b' is at least 4.
00606  *
00607  * Ensures:
00608  *\li   The used pointer in 'b' is advanced by 4.
00609  */
00610 
00611 isc_uint64_t
00612 isc_buffer_getuint48(isc_buffer_t *b);
00613 /*!<
00614  * \brief Read an unsigned 48-bit integer in network byte order from 'b',
00615  * convert it to host byte order, and return it.
00616  *
00617  * Requires:
00618  *
00619  *\li   'b' is a valid buffer.
00620  *
00621  *\li   The length of the available region of 'b' is at least 6.
00622  *
00623  * Ensures:
00624  *
00625  *\li   The current pointer in 'b' is advanced by 6.
00626  *
00627  * Returns:
00628  *
00629  *\li   A 48-bit unsigned integer (stored in a 64-bit integer).
00630  */
00631 
00632 void
00633 isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
00634 /*!<
00635  * \brief Store an unsigned 48-bit integer in host byte order from 'val'
00636  * into 'b' in network byte order.
00637  *
00638  * Requires:
00639  *\li   'b' is a valid buffer.
00640  *
00641  *\li   The length of the unused region of 'b' is at least 6.
00642  *
00643  * Ensures:
00644  *\li   The used pointer in 'b' is advanced by 6.
00645  */
00646 
00647 void
00648 isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val);
00649 /*!<
00650  * Store an unsigned 24-bit integer in host byte order from 'val'
00651  * into 'b' in network byte order.
00652  *
00653  * Requires:
00654  *\li   'b' is a valid buffer.
00655  *
00656  *      The length of the unused region of 'b' is at least 3.
00657  *
00658  * Ensures:
00659  *\li   The used pointer in 'b' is advanced by 3.
00660  */
00661 
00662 void
00663 isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
00664                    unsigned int length);
00665 /*!<
00666  * \brief Copy 'length' bytes of memory at 'base' into 'b'.
00667  *
00668  * Requires:
00669  *\li   'b' is a valid buffer.
00670  *
00671  *\li   'base' points to 'length' bytes of valid memory.
00672  *
00673  */
00674 
00675 void
00676 isc__buffer_putstr(isc_buffer_t *b, const char *source);
00677 /*!<
00678  * \brief Copy 'source' into 'b', not including terminating NUL.
00679  *
00680  * Requires:
00681  *\li   'b' is a valid buffer.
00682  *
00683  *\li   'source' to be a valid NULL terminated string.
00684  *
00685  *\li   strlen(source) <= isc_buffer_available(b)
00686  */
00687 
00688 isc_result_t
00689 isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
00690 /*!<
00691  * \brief Copy the contents of 'r' into 'b'.
00692  *
00693  * Requires:
00694  *\li   'b' is a valid buffer.
00695  *
00696  *\li   'r' is a valid region.
00697  *
00698  * Returns:
00699  *
00700  *\li   ISC_R_SUCCESS
00701  *\li   ISC_R_NOSPACE                   The available region of 'b' is not
00702  *                                      big enough.
00703  */
00704 
00705 ISC_LANG_ENDDECLS
00706 
00707 /*
00708  * Inline macro versions of the functions.  These should never be called
00709  * directly by an application, but will be used by the functions within
00710  * buffer.c.  The callers should always use "isc_buffer_*()" names, never
00711  * ones beginning with "isc__"
00712  */
00713 
00714 /*! \note
00715  * XXXDCL Something more could be done with initializing buffers that
00716  * point to const data.  For example, isc_buffer_constinit() could
00717  * set a new boolean flag in the buffer structure indicating whether
00718  * the buffer was initialized with that function.  * Then if the
00719  * boolean were true, the isc_buffer_put* functions could assert a
00720  * contractual requirement for a non-const buffer.
00721  *
00722  * One drawback is that the isc_buffer_* functions (macros) that return
00723  * pointers would still need to return non-const pointers to avoid compiler
00724  * warnings, so it would be up to code that uses them to have to deal
00725  * with the possibility that the buffer was initialized as const --
00726  * a problem that they *already* have to deal with but have absolutely
00727  * no ability to.  With a new isc_buffer_isconst() function returning
00728  * true/false, they could at least assert a contractual requirement for
00729  * non-const buffers when needed.
00730  */
00731 #define ISC__BUFFER_INIT(_b, _base, _length) \
00732         do { \
00733                 (_b)->base = _base; \
00734                 (_b)->length = (_length); \
00735                 (_b)->used = 0; \
00736                 (_b)->current = 0; \
00737                 (_b)->active = 0; \
00738                 (_b)->mctx = NULL; \
00739                 ISC_LINK_INIT(_b, link); \
00740                 (_b)->magic = ISC_BUFFER_MAGIC; \
00741         } while (0)
00742 
00743 #define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
00744 
00745 #define ISC__BUFFER_INVALIDATE(_b) \
00746         do { \
00747                 (_b)->magic = 0; \
00748                 (_b)->base = NULL; \
00749                 (_b)->length = 0; \
00750                 (_b)->used = 0; \
00751                 (_b)->current = 0; \
00752                 (_b)->active = 0; \
00753         } while (0)
00754 
00755 #define ISC__BUFFER_REGION(_b, _r) \
00756         do { \
00757                 (_r)->base = (_b)->base; \
00758                 (_r)->length = (_b)->length; \
00759         } while (0)
00760 
00761 #define ISC__BUFFER_USEDREGION(_b, _r) \
00762         do { \
00763                 (_r)->base = (_b)->base; \
00764                 (_r)->length = (_b)->used; \
00765         } while (0)
00766 
00767 #define ISC__BUFFER_AVAILABLEREGION(_b, _r) \
00768         do { \
00769                 (_r)->base = isc_buffer_used(_b); \
00770                 (_r)->length = isc_buffer_availablelength(_b); \
00771         } while (0)
00772 
00773 #define ISC__BUFFER_ADD(_b, _n) \
00774         do { \
00775                 (_b)->used += (_n); \
00776         } while (0)
00777 
00778 #define ISC__BUFFER_SUBTRACT(_b, _n) \
00779         do { \
00780                 (_b)->used -= (_n); \
00781                 if ((_b)->current > (_b)->used) \
00782                         (_b)->current = (_b)->used; \
00783                 if ((_b)->active > (_b)->used) \
00784                         (_b)->active = (_b)->used; \
00785         } while (0)
00786 
00787 #define ISC__BUFFER_CLEAR(_b) \
00788         do { \
00789                 (_b)->used = 0; \
00790                 (_b)->current = 0; \
00791                 (_b)->active = 0; \
00792         } while (0)
00793 
00794 #define ISC__BUFFER_CONSUMEDREGION(_b, _r) \
00795         do { \
00796                 (_r)->base = (_b)->base; \
00797                 (_r)->length = (_b)->current; \
00798         } while (0)
00799 
00800 #define ISC__BUFFER_REMAININGREGION(_b, _r) \
00801         do { \
00802                 (_r)->base = isc_buffer_current(_b); \
00803                 (_r)->length = isc_buffer_remaininglength(_b); \
00804         } while (0)
00805 
00806 #define ISC__BUFFER_ACTIVEREGION(_b, _r) \
00807         do { \
00808                 if ((_b)->current < (_b)->active) { \
00809                         (_r)->base = isc_buffer_current(_b); \
00810                         (_r)->length = isc_buffer_activelength(_b); \
00811                 } else { \
00812                         (_r)->base = NULL; \
00813                         (_r)->length = 0; \
00814                 } \
00815         } while (0)
00816 
00817 #define ISC__BUFFER_SETACTIVE(_b, _n) \
00818         do { \
00819                 (_b)->active = (_b)->current + (_n); \
00820         } while (0)
00821 
00822 #define ISC__BUFFER_FIRST(_b) \
00823         do { \
00824                 (_b)->current = 0; \
00825         } while (0)
00826 
00827 #define ISC__BUFFER_FORWARD(_b, _n) \
00828         do { \
00829                 (_b)->current += (_n); \
00830         } while (0)
00831 
00832 #define ISC__BUFFER_BACK(_b, _n) \
00833         do { \
00834                 (_b)->current -= (_n); \
00835         } while (0)
00836 
00837 #define ISC__BUFFER_PUTMEM(_b, _base, _length) \
00838         do { \
00839                 memmove(isc_buffer_used(_b), (_base), (_length)); \
00840                 (_b)->used += (_length); \
00841         } while (0)
00842 
00843 #define ISC__BUFFER_PUTSTR(_b, _source) \
00844         do { \
00845                 unsigned int _length; \
00846                 unsigned char *_cp; \
00847                 _length = strlen(_source); \
00848                 _cp = isc_buffer_used(_b); \
00849                 memmove(_cp, (_source), _length); \
00850                 (_b)->used += (_length); \
00851         } while (0)
00852 
00853 #define ISC__BUFFER_PUTUINT8(_b, _val) \
00854         do { \
00855                 unsigned char *_cp; \
00856                 isc_uint8_t _val2 = (_val); \
00857                 _cp = isc_buffer_used(_b); \
00858                 (_b)->used++; \
00859                 _cp[0] = _val2 & 0x00ff; \
00860         } while (0)
00861 
00862 #define ISC__BUFFER_PUTUINT16(_b, _val) \
00863         do { \
00864                 unsigned char *_cp; \
00865                 isc_uint16_t _val2 = (_val); \
00866                 _cp = isc_buffer_used(_b); \
00867                 (_b)->used += 2; \
00868                 _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
00869                 _cp[1] = (unsigned char)(_val2 & 0x00ffU); \
00870         } while (0)
00871 
00872 #define ISC__BUFFER_PUTUINT24(_b, _val) \
00873         do { \
00874                 unsigned char *_cp; \
00875                 isc_uint32_t _val2 = (_val); \
00876                 _cp = isc_buffer_used(_b); \
00877                 (_b)->used += 3; \
00878                 _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
00879                 _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
00880                 _cp[2] = (unsigned char)(_val2 & 0x00ffU); \
00881         } while (0)
00882 
00883 #define ISC__BUFFER_PUTUINT32(_b, _val) \
00884         do { \
00885                 unsigned char *_cp; \
00886                 isc_uint32_t _val2 = (_val); \
00887                 _cp = isc_buffer_used(_b); \
00888                 (_b)->used += 4; \
00889                 _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
00890                 _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
00891                 _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
00892                 _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
00893         } while (0)
00894 
00895 #if defined(ISC_BUFFER_USEINLINE)
00896 #define isc_buffer_init                 ISC__BUFFER_INIT
00897 #define isc_buffer_initnull             ISC__BUFFER_INITNULL
00898 #define isc_buffer_invalidate           ISC__BUFFER_INVALIDATE
00899 #define isc_buffer_region               ISC__BUFFER_REGION
00900 #define isc_buffer_usedregion           ISC__BUFFER_USEDREGION
00901 #define isc_buffer_availableregion      ISC__BUFFER_AVAILABLEREGION
00902 #define isc_buffer_add                  ISC__BUFFER_ADD
00903 #define isc_buffer_subtract             ISC__BUFFER_SUBTRACT
00904 #define isc_buffer_clear                ISC__BUFFER_CLEAR
00905 #define isc_buffer_consumedregion       ISC__BUFFER_CONSUMEDREGION
00906 #define isc_buffer_remainingregion      ISC__BUFFER_REMAININGREGION
00907 #define isc_buffer_activeregion         ISC__BUFFER_ACTIVEREGION
00908 #define isc_buffer_setactive            ISC__BUFFER_SETACTIVE
00909 #define isc_buffer_first                ISC__BUFFER_FIRST
00910 #define isc_buffer_forward              ISC__BUFFER_FORWARD
00911 #define isc_buffer_back                 ISC__BUFFER_BACK
00912 #define isc_buffer_putmem               ISC__BUFFER_PUTMEM
00913 #define isc_buffer_putstr               ISC__BUFFER_PUTSTR
00914 #define isc_buffer_putuint8             ISC__BUFFER_PUTUINT8
00915 #define isc_buffer_putuint16            ISC__BUFFER_PUTUINT16
00916 #define isc_buffer_putuint24            ISC__BUFFER_PUTUINT24
00917 #define isc_buffer_putuint32            ISC__BUFFER_PUTUINT32
00918 #else
00919 #define isc_buffer_init                 isc__buffer_init
00920 #define isc_buffer_initnull             isc__buffer_initnull
00921 #define isc_buffer_invalidate           isc__buffer_invalidate
00922 #define isc_buffer_region               isc__buffer_region
00923 #define isc_buffer_usedregion           isc__buffer_usedregion
00924 #define isc_buffer_availableregion      isc__buffer_availableregion
00925 #define isc_buffer_add                  isc__buffer_add
00926 #define isc_buffer_subtract             isc__buffer_subtract
00927 #define isc_buffer_clear                isc__buffer_clear
00928 #define isc_buffer_consumedregion       isc__buffer_consumedregion
00929 #define isc_buffer_remainingregion      isc__buffer_remainingregion
00930 #define isc_buffer_activeregion         isc__buffer_activeregion
00931 #define isc_buffer_setactive            isc__buffer_setactive
00932 #define isc_buffer_first                isc__buffer_first
00933 #define isc_buffer_forward              isc__buffer_forward
00934 #define isc_buffer_back                 isc__buffer_back
00935 #define isc_buffer_putmem               isc__buffer_putmem
00936 #define isc_buffer_putstr               isc__buffer_putstr
00937 #define isc_buffer_putuint8             isc__buffer_putuint8
00938 #define isc_buffer_putuint16            isc__buffer_putuint16
00939 #define isc_buffer_putuint24            isc__buffer_putuint24
00940 #define isc_buffer_putuint32            isc__buffer_putuint32
00941 #endif
00942 
00943 #define isc_buffer_constinit(_b, _d, _l) \
00944         do { \
00945                 union { void *_var; const void *_const; } _deconst; \
00946                 _deconst._const = (_d); \
00947                 isc_buffer_init((_b), _deconst._var, (_l)); \
00948         } while (0)
00949 
00950 /*
00951  * No inline method for this one (yet).
00952  */
00953 #define isc_buffer_putuint48            isc__buffer_putuint48
00954 
00955 #endif /* ISC_BUFFER_H */

Generated on Tue Apr 28 17:41:04 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha