File:  [ELWIX - Embedded LightWeight unIX -] / libelwix / src / iov.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sun Mar 21 01:32:04 2021 UTC (3 years, 1 month ago) by misho
Branches: MAIN
CVS tags: elwix5_9, elwix5_8, elwix5_7, elwix5_6, elwix5_5, elwix5_4, elwix5_3, elwix5_2, elwix5_12, elwix5_11, elwix5_10, elwix5_1, elwix5_0, HEAD, ELWIX5_9, ELWIX5_8, ELWIX5_7, ELWIX5_6, ELWIX5_5, ELWIX5_4, ELWIX5_3, ELWIX5_2, ELWIX5_11, ELWIX5_10, ELWIX5_1, ELWIX5_0, ELWIX4_26
ver 4.26

    1: /*************************************************************************
    2: * (C) 2021 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: iov.c,v 1.2 2021/03/21 01:32:04 misho Exp $
    7: *
    8: **************************************************************************
    9: The ELWIX and AITNET software is distributed under the following
   10: terms:
   11: 
   12: All of the documentation and software included in the ELWIX and AITNET
   13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   14: 
   15: Copyright 2004 - 2021
   16: 	by Michael Pounov <misho@elwix.org>.  All rights reserved.
   17: 
   18: Redistribution and use in source and binary forms, with or without
   19: modification, are permitted provided that the following conditions
   20: are met:
   21: 1. Redistributions of source code must retain the above copyright
   22:    notice, this list of conditions and the following disclaimer.
   23: 2. Redistributions in binary form must reproduce the above copyright
   24:    notice, this list of conditions and the following disclaimer in the
   25:    documentation and/or other materials provided with the distribution.
   26: 3. All advertising materials mentioning features or use of this software
   27:    must display the following acknowledgement:
   28: This product includes software developed by Michael Pounov <misho@elwix.org>
   29: ELWIX - Embedded LightWeight unIX and its contributors.
   30: 4. Neither the name of AITNET nor the names of its contributors
   31:    may be used to endorse or promote products derived from this software
   32:    without specific prior written permission.
   33: 
   34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
   35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   44: SUCH DAMAGE.
   45: */
   46: #include "global.h"
   47: 
   48: 
   49: /*
   50:  * iov_Init() - Init new iovec array
   51:  *
   52:  * return: =NULL error, !=NULL ready array
   53:  */
   54: iovec_t *
   55: iov_Init()
   56: {
   57: 	iovec_t *iov;
   58: 
   59: 	iov = e_malloc(sizeof(iovec_t));
   60: 	if (iov)
   61: 		memset(iov, 0, sizeof(iovec_t));
   62: 
   63: 	return iov;
   64: }
   65: 
   66: /*
   67:  * iov_Destroy() - Destroy iovec array
   68:  *
   69:  * @iov = iovec array
   70:  * return: none
   71:  */
   72: void
   73: iov_Destroy(iovec_t ** __restrict iov)
   74: {
   75: 	if (iov && *iov) {
   76: 		if ((*iov)->iov_array)
   77: 			e_free((*iov)->iov_array);
   78: 		e_free((*iov));
   79: 		*iov = NULL;
   80: 	}
   81: }
   82: 
   83: /*
   84:  * iov_Get() - Get data and length from position
   85:  *
   86:  * @iov = iovec array
   87:  * @pos = position
   88:  * @data = data
   89:  * @datlen = data length
   90:  * return: -1 error, 0 ok
   91:  */
   92: int
   93: iov_Get(iovec_t * __restrict iov, u_int pos, void *data, size_t *datlen)
   94: {
   95: 	if (!iov || !data || !datlen)
   96: 		return -1;
   97: 
   98: 	if (pos >= iov->iov_size)
   99: 		return -1;
  100: 
  101: 	*datlen = MIN(*datlen, iov->iov_array[pos].iov_len);
  102: 	memcpy(data, iov->iov_array[pos].iov_base, *datlen);
  103: 
  104: 	return 0;
  105: }
  106: 
  107: /*
  108:  * iov_Insert() - Insert data at position into array
  109:  *
  110:  * @iov = iovec array
  111:  * @pos = position
  112:  * @data = data
  113:  * @datlen = data length
  114:  * return: -1 error, 0 ok
  115:  */
  116: int
  117: iov_Insert(iovec_t * __restrict iov, u_int pos, void *data, size_t datlen)
  118: {
  119: 	struct iovec *iv;
  120: 
  121: 	if (!iov)
  122: 		return -1;
  123: 
  124: 	if (pos >= iov->iov_size) {
  125: 		iv = e_realloc(iov->iov_array, sizeof(struct iovec) * (pos + 1));
  126: 		if (!iv)
  127: 			return -1;
  128: 
  129: 		iov->iov_array = iv;
  130: 		iov->iov_size = pos + 1;
  131: 	}
  132: 
  133: 	iov->iov_array[pos].iov_base = data;
  134: 	iov->iov_array[pos].iov_len = datlen;
  135: 
  136: 	return 0;
  137: }
  138: 
  139: /*
  140:  * iov_Delete() - Delete data at position into array
  141:  *
  142:  * @iov = iovec array
  143:  * @pos = position
  144:  * @mustfree = data must be free before delete
  145:  * return: -1 error, 0 ok
  146:  */
  147: int
  148: iov_Delete(iovec_t * __restrict iov, u_int pos, int mustfree)
  149: {
  150: 	if (!iov)
  151: 		return -1;
  152: 
  153: 	if (pos < iov->iov_size) {
  154: 		if (mustfree)
  155: 			e_free(iov->iov_array[pos].iov_base);
  156: 		memset(iov->iov_array + pos, 0, sizeof(struct iovec));
  157: 	}
  158: 
  159: 	return 0;
  160: }
  161: 
  162: /*
  163:  * iov_Push() - Push data on first free position
  164:  *
  165:  * @iov = iovec array
  166:  * @data = data
  167:  * @datlen = data length
  168:  * return: -1 error, !=-1 pushed at position
  169:  */
  170: int
  171: iov_Push(iovec_t * __restrict iov, void *data, size_t datlen)
  172: {
  173: 	register int pos;
  174: 
  175: 	if (!iov)
  176: 		return -1;
  177: 
  178: 	for (pos = 0; pos < iov->iov_size; pos++)
  179: 		if (!iov->iov_array[pos].iov_len && !iov->iov_array[pos].iov_base)
  180: 			break;
  181: 
  182: 	if (iov_Insert(iov, pos, data, datlen))
  183: 		return -1;
  184: 
  185: 	return (int) pos;
  186: }
  187: 
  188: /*
  189:  * iov_Pop() - Pop data from last used position
  190:  *
  191:  * @iov = iovec array
  192:  * @data = data
  193:  * @datlen = data length
  194:  * @mustfree = data must be free before delete
  195:  * return: -1 error, !=-1 poped from position
  196:  */
  197: int
  198: iov_Pop(iovec_t * __restrict iov, void *data, size_t *datlen, int mustfree)
  199: {
  200: 	register int pos;
  201: 
  202: 	if (!iov)
  203: 		return -1;
  204: 
  205: 	if (iov->iov_size < 1)
  206: 		return 0;
  207: 
  208: 	for (pos = iov->iov_size - 1; pos >= 0; pos--)
  209: 		if (iov->iov_array[pos].iov_base)
  210: 			break;
  211: 
  212: 	iov_Get(iov, pos, data, datlen);
  213: 	iov_Delete(iov, pos, mustfree);
  214: 	return (int) pos;
  215: }
  216: 
  217: /*
  218:  * iov_PushPair() - Push pair/named data on first free position
  219:  *
  220:  * @iov = iovec array
  221:  * @name = name of data
  222:  * @data = data
  223:  * @datlen = data length
  224:  * return: -1 error, !=-1 pushed at position
  225:  */
  226: int
  227: iov_PushPair(iovec_t * __restrict iov, const char *name, void *data, size_t datlen)
  228: {
  229: 	char *str;
  230: 	int pos;
  231: 
  232: 	if (!iov)
  233: 		return -1;
  234: 
  235: 	str = e_strdup(name);
  236: 	if (!str)
  237: 		return -1;
  238: 	if (datlen == (size_t) -1) {
  239: 		if (data)
  240: 			datlen = strlen(data) + 1;
  241: 		else
  242: 			datlen = 0;
  243: 	}
  244: 
  245: 	if ((pos = iov_Push(iov, str, strlen(str) + 1)) == -1) {
  246: 		e_free(str);
  247: 		return -1;
  248: 	}
  249: 	if (iov_Push(iov, data, datlen) == -1) {
  250: 		iov_Delete(iov, pos, 42);
  251: 		return -1;
  252: 	}
  253: 
  254: 	return pos;
  255: }
  256: 
  257: /*
  258:  * iov_PopPair() - Pop pair/named data from last used position
  259:  *
  260:  * @iov = iovec array
  261:  * @name = name of data
  262:  * @namlen = name length
  263:  * @data = data
  264:  * @datlen = data length
  265:  * @mustfree = data must be free before delete
  266:  * return: -1 error, !=-1 poped from position
  267:  */
  268: int
  269: iov_PopPair(iovec_t * __restrict iov, char *name, size_t *namlen, 
  270: 		void *data, size_t *datlen, int mustfree)
  271: {
  272: 	int pos;
  273: 
  274: 	if (!iov)
  275: 		return -1;
  276: 
  277: 	if (iov_Pop(iov, data, datlen, mustfree) == -1)
  278: 		return -1;
  279: 	if ((pos = iov_Pop(iov, name, namlen, 42)) == -1)
  280: 		return -1;
  281: 
  282: 	return pos;
  283: }
  284: 
  285: /*
  286:  * iov_FreePairs() - Free pairs/named data in iovec array
  287:  *
  288:  * @iov = iovec array
  289:  * @mustfree = data must be free before delete
  290:  * return: -1 error or 0 ok
  291:  */
  292: int
  293: iov_FreePairs(iovec_t * __restrict iov, int mustfree)
  294: {
  295: 	register int pos;
  296: 
  297: 	if (!iov)
  298: 		return -1;
  299: 
  300: 	if (iov->iov_size < 1)
  301: 		return 0;
  302: 
  303: 	for (pos = 0; pos < (iov_Size(iov) & ~1); pos += 2) {
  304: 		if (iov->iov_array[pos].iov_base)
  305: 			iov_Delete(iov, pos, 42);
  306: 		if (iov->iov_array[pos + 1].iov_base)
  307: 			iov_Delete(iov, pos + 1, mustfree);
  308: 	}
  309: 
  310: 	return 0;
  311: }
  312: 
  313: /*
  314:  * iov_Debug() - Debug of iovec array
  315:  *
  316:  * @iov = iovec array
  317:  * return: none
  318:  */
  319: void
  320: iov_Debug(iovec_t * __restrict iov)
  321: {
  322: 	register size_t pos;
  323: 
  324: 	if (!iov)
  325: 		return;
  326: 
  327: 	printf("iov_size=%zu iov_array=%p\n", iov->iov_size, iov->iov_array);
  328: 	for (pos = 0; pos < iov->iov_size; pos++)
  329: 		printf("IOVEC[%zu] base=%p len=%zu (%s)\n", pos, iov->iov_array[pos].iov_base, 
  330: 				iov->iov_array[pos].iov_len, (char*) iov->iov_array[pos].iov_base);
  331: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>