ROHC compression/decompression library
rohc_buf.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2014 Didier Barvaux
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 
00019 /**
00020  * @file   common/rohc_buf.h
00021  * @brief  Define a network buffer for the ROHC library
00022  * @author Didier Barvaux <didier@barvaux.org>
00023  */
00024 
00025 #ifndef ROHC_BUF_H
00026 #define ROHC_BUF_H
00027 
00028 #ifdef __cplusplus
00029 extern "C"
00030 {
00031 #endif
00032 
00033 /** Macro that handles DLL export declarations gracefully */
00034 #ifdef DLL_EXPORT /* passed by autotools on command line */
00035         #define ROHC_EXPORT __declspec(dllexport)
00036 #else
00037         #define ROHC_EXPORT
00038 #endif
00039 
00040 #include "rohc_time.h" /* for struct rohc_ts */
00041 
00042 #include <stdbool.h>
00043 #include <stdlib.h>
00044 
00045 
00046 /**
00047  * @brief A network buffer for the ROHC library
00048  *
00049  * May represent one uncompressed packet, one ROHC packet, or a ROHC feedback.
00050  *
00051  * The network buffer does not contain the packet data itself. It only has
00052  * a pointer on it. This is designed this way for performance reasons: no copy
00053  * required to initialize a network buffer, the struct is small and may be
00054  * passed as copy to function.
00055  *
00056  * The network buffer is able to keep some free space at its beginning. The
00057  * unused space at the beginning of the buffer may be used to prepend a
00058  * network header at the very end of the packet handling.
00059  *
00060  * The beginning of the network buffer may also be shifted forward with the
00061  * \ref rohc_buf_pull function or shifted backward with the \ref rohc_buf_push
00062  * function. This is useful when parsing a network packet (once bytes are
00063  * read, shift them forward) for example.
00064  *
00065  * The network buffer may be initialized manually (see below) or with the
00066  * helper functions \ref rohc_buf_init_empty or \ref rohc_buf_init_full.
00067  * \code
00068    struct rohc_buf packet;
00069    ...
00070    packet.time.sec = 0;
00071    packet.time.nsec = 0;
00072    packet.max_len = 100;
00073    packet.data = malloc(packet.max_len);
00074    packet.offset = 2;
00075    packet.len = 2;
00076    packet[packet.offset] = 0x01;
00077    packet[packet.offset + 1] = 0x02;
00078    ...
00079 \endcode
00080  *
00081  * or as below:
00082  * \code
00083    struct rohc_buf packet;
00084    unsigned char input[100];
00085    ...
00086    input[2] = 0x01;
00087    input[3] = 0x02;
00088    ...
00089    packet.time.sec = 0;
00090    packet.time.nsec = 0;
00091    packet.max_len = 100;
00092    packet.data = input;
00093    packet.offset = 2;
00094    packet.len = 2;
00095    ...
00096 \endcode
00097  *
00098  * @ingroup rohc
00099  */
00100 struct rohc_buf
00101 {
00102         struct rohc_ts time;  /**< The timestamp associated to the data */
00103         uint8_t *data;        /**< The buffer data */
00104         size_t max_len;       /**< The maximum length of the buffer */
00105         size_t offset;        /**< The offset for the beginning of the data */
00106         size_t len;           /**< The data length (in bytes) */
00107 };
00108 
00109 
00110 /**
00111  * @brief Initialize the given network buffer with no data
00112  *
00113  * This method is used to initialize an empty network buffer that will be used
00114  * to create a packet. For example, the ROHC packet for a compression
00115  * operation, or the uncompressed packet for a decompression operation.
00116  *
00117  * @param __data     The packet data to point to
00118  * @param __max_len  The maxmimum length (in bytes) of the packet data
00119  *
00120  * \par Example:
00121  * \code
00122         #define PKT_DATA_LEN  145U
00123         uint8_t pkt_data[PKT_DATA_LEN];
00124         struct rohc_buf packet = rohc_buf_init_empty(pkt_data, PKT_DATA_LEN);
00125 \endcode
00126  *
00127  * @ingroup rohc
00128  */
00129 #define rohc_buf_init_empty(__data, __max_len) \
00130         { \
00131                 .time = { .sec = 0, .nsec = 0, }, \
00132                 .data = (__data), \
00133                 .max_len = (__max_len), \
00134                 .offset = 0, \
00135                 .len = 0, \
00136         }
00137 
00138 
00139 /**
00140  * @brief Initialize the given network buffer with all its data
00141  *
00142  * This method is used to initialize a network buffer that will be used for
00143  * parsing only. For example, the uncompressed packet for a compression
00144  * operation, or the ROHC packet for a decompression operation.
00145  *
00146  * @param __data  The packet data to point to
00147  * @param __len   The maxmimum length (in bytes) of the packet data
00148  * @param __time  The timestamp at which the packet was received/handled
00149  *
00150  * \par Example:
00151  * \code
00152         #define PKT_DATA_LEN  145U
00153         const uint8_t pkt_data[PKT_DATA_LEN];
00154         const struct rohc_ts arrival_time = { .sec = 1399745625, .nsec = 42 };
00155         const struct rohc_buf packet =
00156                 rohc_buf_init_full(pkt_data, PKT_DATA_LEN, arrival_time);
00157 \endcode
00158  *
00159  * @ingroup rohc
00160  */
00161 #define rohc_buf_init_full(__data, __len, __time) \
00162         { \
00163                 .time = (__time), \
00164                 .data = (__data), \
00165                 .max_len = (__len), \
00166                 .offset = 0, \
00167                 .len = (__len), \
00168         }
00169 
00170 
00171 /**
00172  * @brief Get the byte at the given offset in the given network buffer
00173  *
00174  * @param __buf     The network buffer to get a byte from
00175  * @param __offset  The offset to get bytes at
00176  * @return          The byte stored in the network buffer at the offset
00177  *
00178  * @ingroup rohc
00179  */
00180 #define rohc_buf_byte_at(__buf, __offset) \
00181         ((__buf).data)[(__buf).offset + (__offset)]
00182 
00183 
00184 /**
00185  * @brief Get the next byte in the given network buffer
00186  *
00187  * @param __buf  The network buffer to get the next byte from
00188  * @return       The next byte stored in the network buffer
00189  *
00190  * @ingroup rohc
00191  */
00192 #define rohc_buf_byte(__buf) \
00193         rohc_buf_byte_at((__buf), 0)
00194 
00195 
00196 
00197 bool rohc_buf_is_malformed(const struct rohc_buf buf)
00198         __attribute__((warn_unused_result));
00199 
00200 bool rohc_buf_is_empty(const struct rohc_buf buf)
00201         __attribute__((warn_unused_result));
00202 
00203 void rohc_buf_pull(struct rohc_buf *const buf, const size_t offset)
00204         __attribute__((nonnull(1)));
00205 void rohc_buf_push(struct rohc_buf *const buf, const size_t offset)
00206         __attribute__((nonnull(1)));
00207 
00208 size_t rohc_buf_avail_len(const struct rohc_buf buf)
00209         __attribute__((warn_unused_result));
00210 
00211 uint8_t * rohc_buf_data_at(const struct rohc_buf buf, const size_t offset)
00212         __attribute__((warn_unused_result));
00213 uint8_t * rohc_buf_data(const struct rohc_buf buf)
00214         __attribute__((warn_unused_result));
00215 
00216 void rohc_buf_prepend(struct rohc_buf *const buf,
00217                       const uint8_t *const data,
00218                       const size_t len)
00219         __attribute__((nonnull(1, 2)));
00220 void rohc_buf_append(struct rohc_buf *const buf,
00221                      const uint8_t *const data,
00222                      const size_t len)
00223         __attribute__((nonnull(1, 2)));
00224 void rohc_buf_append_buf(struct rohc_buf *const dst,
00225                          const struct rohc_buf src)
00226         __attribute__((nonnull(1)));
00227 
00228 void rohc_buf_reset(struct rohc_buf *const buf)
00229         __attribute__((nonnull(1)));
00230 
00231 
00232 #undef ROHC_EXPORT /* do not pollute outside this header */
00233 
00234 #ifdef __cplusplus
00235 }
00236 #endif
00237 
00238 #endif /* ROHC_BUF_H */
00239