File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / bufio.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Thu Feb 2 21:32:42 2012 UTC (12 years, 4 months ago) by misho
Branches: MAIN
CVS tags: io2_4, IO2_3, HEAD
version 2.3
added feature for bufio

    1: #include "global.h"
    2: 
    3: 
    4: static void
    5: unmap_cf(struct tagBufIO *buf)
    6: {
    7: 	if (buf)
    8: 		munmap(buf->buf_base, buf->buf_size);
    9: }
   10: 
   11: static int
   12: cf_(struct tagBufIO *buf)
   13: {
   14: 	if (!buf) {
   15: 		io_SetErr(EINVAL, "Invalid arguments ...");
   16: 		return -1;
   17: 	}
   18: 
   19: 	if (buf->buf_mode == BUFIO_MODE_INFINIT)
   20: 		free(buf->buf_base);
   21: 	else if (buf->buf_unmap)
   22: 		buf->buf_unmap(buf);
   23: 
   24: 	free(buf);
   25: 	return 0;
   26: }
   27: 
   28: static fpos_t
   29: sf_lim(struct tagBufIO *buf, fpos_t pos, int w)
   30: {
   31: 	if (!buf)
   32: 		goto err;
   33: 
   34: 	switch (w) {
   35: 		case SEEK_SET:
   36: 			if (buf->buf_size < pos || pos < 0)
   37: 				goto err;
   38: 			buf->buf_offset = pos;
   39: 			break;
   40: 		case SEEK_CUR:
   41: 			if (buf->buf_size < (buf->buf_offset + pos) || (buf->buf_offset + pos) < 0)
   42: 				goto err;
   43: 			buf->buf_offset += pos;
   44: 			break;
   45: 		case SEEK_END:
   46: 			if (buf->buf_size < (buf->buf_size + pos) || (buf->buf_size + pos) < 0)
   47: 				goto err;
   48: 			buf->buf_offset = buf->buf_size + pos;
   49: 			break;
   50: 		default:
   51: 			goto err;
   52: 	}
   53: 
   54: 	return buf->buf_offset;
   55: err:
   56: 	io_SetErr(EINVAL, "Invalid arguments ...");
   57: 	return -1;
   58: }
   59: 
   60: static int
   61: rf_lim(struct tagBufIO *buf, char *dat, int siz)
   62: {
   63: 	if (!buf || !dat) {
   64: 		io_SetErr(EINVAL, "Invalid arguments ...");
   65: 		return -1;
   66: 	}
   67: 
   68: 	if (buf->buf_offset + siz > buf->buf_size)
   69: 		siz = buf->buf_size - buf->buf_offset;
   70: 
   71: 	memcpy(dat, buf->buf_base + buf->buf_offset, siz);
   72: 	buf->buf_offset += siz;
   73: 	return siz;
   74: }
   75: 
   76: static int
   77: wf_lim(struct tagBufIO *buf, const char *dat, int siz)
   78: {
   79: 	if (!buf || !dat) {
   80: 		io_SetErr(EINVAL, "Invalid arguments ...");
   81: 		return -1;
   82: 	}
   83: 
   84: 	if (buf->buf_offset + siz > buf->buf_size)
   85: 		siz = buf->buf_size - buf->buf_offset;
   86: 
   87: 	memcpy(buf->buf_base + buf->buf_offset, dat, siz);
   88: 	buf->buf_offset += siz;
   89: 	return siz;
   90: }
   91: 
   92: static fpos_t
   93: sf_inf(struct tagBufIO *buf, fpos_t pos, int w)
   94: {
   95: 	void *b;
   96: 
   97: 	if (!buf)
   98: 		goto err;
   99: 
  100: 	switch (w) {
  101: 		case SEEK_SET:
  102: 			if (pos < 0)
  103: 				goto err;
  104: 			if (buf->buf_size < pos) {
  105: 				b = realloc(buf->buf_base, pos);
  106: 				if (!b) {
  107: 					LOGERR;
  108: 					return -1;
  109: 				} else {
  110: 					buf->buf_base = b;
  111: 					memset(buf->buf_base + buf->buf_size, 0, pos - buf->buf_size);
  112: 					buf->buf_size = pos;
  113: 				}
  114: 			}
  115: 			buf->buf_offset = pos;
  116: 			break;
  117: 		case SEEK_CUR:
  118: 			if ((buf->buf_offset + pos) < 0)
  119: 				goto err;
  120: 			if (buf->buf_size < (buf->buf_offset + pos)) {
  121: 				b = realloc(buf->buf_base, buf->buf_offset + pos);
  122: 				if (!b) {
  123: 					LOGERR;
  124: 					return -1;
  125: 				} else {
  126: 					buf->buf_base = b;
  127: 					memset(buf->buf_base + buf->buf_size, 0, 
  128: 							buf->buf_offset + pos - buf->buf_size);
  129: 					buf->buf_size = buf->buf_offset + pos;
  130: 				}
  131: 			}
  132: 			buf->buf_offset += pos;
  133: 			break;
  134: 		case SEEK_END:
  135: 			if ((buf->buf_size + pos) < 0)
  136: 				goto err;
  137: 			if (buf->buf_size < (buf->buf_size + pos)) {
  138: 				b = realloc(buf->buf_base, buf->buf_size + pos);
  139: 				if (!b) {
  140: 					LOGERR;
  141: 					return -1;
  142: 				} else {
  143: 					buf->buf_base = b;
  144: 					memset(buf->buf_base + buf->buf_size, 0, pos);
  145: 					buf->buf_size += pos;
  146: 					buf->buf_offset = buf->buf_size;
  147: 				}
  148: 			} else
  149: 				buf->buf_offset = buf->buf_size + pos;
  150: 			break;
  151: 		default:
  152: 			goto err;
  153: 	}
  154: 
  155: 	return buf->buf_offset;
  156: err:
  157: 	io_SetErr(EINVAL, "Invalid arguments ...");
  158: 	return -1;
  159: }
  160: 
  161: static int
  162: wf_inf(struct tagBufIO *buf, const char *dat, int siz)
  163: {
  164: 	void *b;
  165: 
  166: 	if (!buf || !dat) {
  167: 		io_SetErr(EINVAL, "Invalid arguments ...");
  168: 		return -1;
  169: 	}
  170: 
  171: 	if (buf->buf_offset + siz > buf->buf_size) {
  172: 		b = realloc(buf->buf_base, buf->buf_offset + siz);
  173: 		if (!b) {
  174: 			LOGERR;
  175: 			return -1;
  176: 		} else {
  177: 			buf->buf_base = b;
  178: 			memset(buf->buf_base + buf->buf_size, 0, 
  179: 					buf->buf_offset + siz - buf->buf_size);
  180: 			buf->buf_size = buf->buf_offset + siz;
  181: 		}
  182: 	}
  183: 
  184: 	memcpy(buf->buf_base + buf->buf_offset, dat, siz);
  185: 	buf->buf_offset += siz;
  186: 	return siz;
  187: }
  188: 
  189: 
  190: /*
  191:  * io_fmemopen() File buffered stream operations over memory block
  192:  *
  193:  * @base = Base address of memory block, if =NULL Infinit length(auto-grow)
  194:  * @basesize = Size of memory block
  195:  * return: NULL error or !=NULL Opened file resource
  196:  */
  197: FILE *
  198: io_fmemopen(void ** __restrict base, off_t basesize)
  199: {
  200: 	FILE *f = NULL;
  201: 	struct tagBufIO *buf;
  202: 
  203: 	if (!base) {
  204: 		io_SetErr(EINVAL, "Invalid base argument ...");
  205: 		return NULL;
  206: 	}
  207: 
  208: 	buf = malloc(sizeof(struct tagBufIO));
  209: 	if (!buf) {
  210: 		LOGERR;
  211: 		return NULL;
  212: 	} else
  213: 		memset(buf, 0, sizeof(struct tagBufIO));
  214: 
  215: 	if (!*base) {
  216: 		*base = malloc(basesize);
  217: 		if (!*base) {
  218: 			LOGERR;
  219: 			free(buf);
  220: 			return NULL;
  221: 		} else
  222: 			memset(*base, 0, basesize);
  223: 
  224: 		buf->buf_mode = BUFIO_MODE_INFINIT;
  225: 	} else
  226: 		buf->buf_mode = BUFIO_MODE_LIMIT;
  227: 
  228: 	buf->buf_base = *base;
  229: 	buf->buf_size = basesize;
  230: 
  231: 	if (buf->buf_mode == BUFIO_MODE_INFINIT)
  232: 		f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
  233: 				(int (*)(void *, char const *, int)) wf_inf, 
  234: 				(fpos_t (*)(void *, fpos_t, int)) sf_inf, 
  235: 				(int (*)(void *)) cf_);
  236: 	else
  237: 		f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
  238: 				(int (*)(void *, char const *, int)) wf_lim, 
  239: 				(fpos_t (*)(void *, fpos_t, int)) sf_lim, 
  240: 				(int (*)(void *)) cf_);
  241: 	if (!f) {
  242: 		LOGERR;
  243: 		if (buf->buf_mode == BUFIO_MODE_INFINIT) {
  244: 			free(*base);
  245: 			*base = NULL;
  246: 		}
  247: 		free(buf);
  248: 		return NULL;
  249: 	}
  250: 
  251: 	return f;
  252: }
  253: 
  254: /*
  255:  * io_fmapopen() File buffered stream operations over MMAP block
  256:  *
  257:  * @csFile = Filename for MMAP, if =NULL private MMAP block
  258:  * @mode = File open mode
  259:  * @perm = If file not exists will be created with this access permissions
  260:  * @prot = MMAP protection
  261:  * @flags = MMAP mode flags
  262:  * @offset = Map from file offset, if csFile==NULL then this is size of MMAP private block
  263:  * return: NULL error or !=NULL Opened file resource
  264:  */
  265: FILE *
  266: io_fmapopen(const char *csFile, int mode, int perm, int prot, int flags, off_t offset)
  267: {
  268: 	FILE *f;
  269: 	struct tagBufIO *buf;
  270: 	void *base;
  271: 	off_t basesize;
  272: 	int fd = -1;
  273: 
  274: 	if (csFile) {
  275: 		fd = open(csFile, mode, perm);
  276: 		if (fd == -1) {
  277: 			LOGERR;
  278: 			return NULL;
  279: 		}
  280: 		basesize = lseek(fd, 0, SEEK_END);
  281: 		if (basesize == -1) {
  282: 			LOGERR;
  283: 			close(fd);
  284: 			return NULL;
  285: 		} else
  286: 			lseek(fd, 0, SEEK_SET);
  287: 
  288: 		base = mmap(NULL, basesize, prot, flags | MAP_FILE, fd, offset);
  289: 		if (base == MAP_FAILED) {
  290: 			LOGERR;
  291: 			close(fd);
  292: 			return NULL;
  293: 		} else
  294: 			close(fd);
  295: 	} else if (offset) {
  296: 		basesize = offset;
  297: 		base = mmap(NULL, basesize, prot, MAP_ANON, -1, 0);
  298: 		if (base == MAP_FAILED) {
  299: 			LOGERR;
  300: 			return NULL;
  301: 		}
  302: 	} else {
  303: 		io_SetErr(EINVAL, "Invalid base argument ...");
  304: 		return NULL;
  305: 	}
  306: 
  307: 
  308: 	buf = malloc(sizeof(struct tagBufIO));
  309: 	if (!buf) {
  310: 		LOGERR;
  311: 		munmap(base, basesize);
  312: 		return NULL;
  313: 	} else
  314: 		memset(buf, 0, sizeof(struct tagBufIO));
  315: 
  316: 	buf->buf_mode = BUFIO_MODE_LIMIT;
  317: 	buf->buf_base = base;
  318: 	buf->buf_size = basesize;
  319: 	buf->buf_unmap = unmap_cf;
  320: 
  321: 	f = funopen(buf, (int (*)(void *, char *, int)) rf_lim, 
  322: 			(int (*)(void *, char const *, int)) wf_lim, 
  323: 			(fpos_t (*)(void *, fpos_t, int)) sf_lim, 
  324: 			(int (*)(void *)) cf_);
  325: 	if (!f) {
  326: 		LOGERR;
  327: 		free(buf);
  328: 		munmap(base, basesize);
  329: 		return NULL;
  330: 	}
  331: 
  332: 	return f;
  333: }
  334: 
  335: /*
  336:  * io_dumbFile() Create empry or dumb file with fixed size
  337:  *
  338:  * @csFile = Filename for create
  339:  * @mode = File access permissions
  340:  * @size = File size
  341:  * return: -1 error or open file handle
  342:  */
  343: int
  344: io_dumbFile(const char *csFile, int mode, off_t size)
  345: {
  346: 	int fd;
  347: 
  348: 	fd = open(csFile, O_RDWR | O_CREAT, mode);
  349: 	if (fd == -1) {
  350: 		LOGERR;
  351: 		return -1;
  352: 	}
  353: 
  354: 	if (lseek(fd, size - 1, SEEK_SET) == -1)
  355: 		goto err;
  356: 	if (write(fd, "", 1) != 1)
  357: 		goto err;
  358: 	else
  359: 		lseek(fd, 0, SEEK_SET);
  360: 
  361: 	return fd;
  362: err:
  363: 	LOGERR;
  364: 	close(fd);
  365: 	return -1;
  366: }
  367: 
  368: /*
  369:  * io_fd2buf() Convert open file handle to buffered file I/O
  370:  *
  371:  * @fd = File handle
  372:  * @mode = Permissions for new buffered file I/O
  373:  * return: NULL error or open buffered file
  374:  */
  375: inline FILE *
  376: io_fd2buf(int fd, const char *mode)
  377: {
  378: 	FILE *f;
  379: 
  380: 	f = fdopen(fd, mode);
  381: 	if (!f)
  382: 		LOGERR;
  383: 
  384: 	return f;
  385: }

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