Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

iovec.h

Go to the documentation of this file.
00001 /*
00002  * $Id: iovec.h 11456 2006-08-07 07:50:50Z cbiere $
00003  *
00004  * Copyright (c) 2004, Christian Biere
00005  *
00006  *----------------------------------------------------------------------
00007  * This file is part of gtk-gnutella.
00008  *
00009  *  gtk-gnutella is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  gtk-gnutella is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with gtk-gnutella; if not, write to the Free Software
00021  *  Foundation, Inc.:
00022  *      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *----------------------------------------------------------------------
00024  */
00025 
00026 #ifndef _lib_iovec_h_
00027 #define _lib_iovec_h_
00028 
00029 #include "common.h"
00030 
00035 static inline struct iovec *
00036 iov_alloc_n(size_t n)
00037 {
00038     struct iovec *iov;
00039 
00040     if (n > (size_t) -1 / sizeof *iov) {
00041         g_assert_not_reached(); /* We don't want to handle failed allocations */
00042         return NULL;
00043     }
00044     iov = g_malloc(n * sizeof *iov);
00045     return iov;
00046 }
00047 
00048 static inline struct iovec
00049 iov_get(gpointer base, size_t size)
00050 {
00051     static const struct iovec zero_iov;
00052     struct iovec iov;
00053 
00054     iov = zero_iov;
00055     iov.iov_base = base;
00056     iov.iov_len = size;
00057     return iov;
00058 }
00059 
00067 static inline void
00068 iov_reset_n(struct iovec *iov, size_t n)
00069 {
00070     size_t i;
00071 
00072     g_assert(iov);
00073     for (i = 0; i < n; i++) {
00074         static const struct iovec zero_iov;
00075         iov[i] = zero_iov;
00076     }
00077 }
00078 
00089 static inline size_t 
00090 iov_init_from_string_vector(struct iovec *iov, size_t iov_cnt,
00091     gchar *argv[], size_t argc)
00092 {
00093     size_t i, n;
00094 
00095     g_assert(iov);
00096     g_assert(iov_cnt >= argc);
00097     g_assert(argv);
00098 
00099     n = MIN(iov_cnt, argc);
00100     for (i = 0; i < n; i++) {
00101         iov[i].iov_base = argv[i];
00102         iov[i].iov_len = argv[i] ? (1 + strlen(argv[i])) : 0;
00103     }
00104     return n;
00105 }
00106 
00112 static inline gboolean
00113 iov_is_contiguous(const struct iovec * const a, const struct iovec * const b)
00114 {
00115     g_assert(a);
00116     g_assert(b);
00117 
00118     return (size_t) a->iov_base + a->iov_len == (size_t) b->iov_base;
00119 }
00120 
00128 static inline size_t 
00129 iov_contiguous_size(const struct iovec *iov, size_t iov_cnt)
00130 {
00131     struct iovec iov0;
00132     size_t i;
00133 
00134     g_assert(iov);
00135 
00136     iov0 = iov[0];
00137 
00138     for (i = 1; i < iov_cnt && iov_is_contiguous(&iov0, &iov[i]); i++) {
00139         size_t n = iov[i].iov_len;
00140 
00141         if (n >= (size_t) -1 - iov0.iov_len) {
00142             /* Abort if size would overflow */
00143             iov0.iov_len = (size_t) -1;
00144             break;
00145         }
00146         iov0.iov_len += n;
00147     }
00148     return iov0.iov_len;
00149 }
00150 
00158 static inline void
00159 iov_clear(struct iovec *iov, size_t byte_offset)
00160 {
00161     g_assert(iov);
00162     
00163     if (byte_offset < iov->iov_len) {
00164         gchar *p = iov->iov_base;
00165         memset(&p[byte_offset], 0, iov->iov_len - byte_offset);
00166     }
00167 }
00168 
00177 static inline size_t
00178 iov_calculate_size(struct iovec *iov, size_t iov_cnt)
00179 {
00180     size_t size = 0;
00181     size_t i;
00182 
00183     g_assert(iov);
00184 
00185     for (i = 0; i < iov_cnt; i++) {
00186         size_t n = iov[i].iov_len;
00187 
00188         if (n >= (size_t) -1 - size) {
00189             /* Abort if size would overflow */
00190             size = (size_t) -1;
00191             break;
00192         }
00193         size += n;
00194     }
00195     return size;
00196 }
00197 
00208 static inline size_t
00209 iov_scatter_string(struct iovec *iov, size_t iov_cnt, const gchar *s)
00210 {
00211     size_t i, len, avail, size;
00212 
00213     g_assert(iov);
00214     g_assert(s);
00215 
00216     /* Reserve one byte for the trailing NUL */
00217     size = iov_calculate_size(iov, iov_cnt);
00218     len = strlen(s);
00219     if (len >= size) {
00220         len = size > 0 ? (size - 1) : 0;
00221     }
00222     avail = len;
00223 
00224     for (i = 0; i < iov_cnt; i++) {
00225         size_t n;
00226 
00227         n = MIN(iov[i].iov_len, avail);
00228         memmove(iov[i].iov_base, s, n);
00229         avail -= n;
00230         s += n;
00231         if (0 == avail) {
00232             iov_clear(&iov[i], n);
00233             i++;
00234             break;
00235         }
00236     }
00237     while (i < iov_cnt) {
00238         iov_clear(&iov[i], 0);
00239         i++;
00240     }
00241     return len;
00242 }
00243 
00244 #endif /* _lib_iovec_h_ */
00245 /* vi: set ts=4 sw=4 cindent: */

Generated on Sat Jun 30 17:53:23 2007 for gtk-gnutella by  doxygen 1.3.9.1