File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / confuse / src / fmemopen.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:49:17 2021 UTC (4 years, 1 month ago) by misho
Branches: confuse, MAIN
CVS tags: v3_3, HEAD
confuse 3.3

    1: /*
    2:  * Copyright (c) 2017  Joachim Nilsson <troglobit@gmail.com>
    3:  *
    4:  * Permission to use, copy, modify, and/or distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15:  */
   16: 
   17: #ifdef HAVE_CONFIG_H
   18: # include <config.h>
   19: #endif
   20: 
   21: #include <stdio.h>
   22: 
   23: #ifdef HAVE_FUNOPEN
   24: #include <stdlib.h>
   25: #include <memory.h>
   26: 
   27: struct ops {
   28: 	char   *buf;
   29: 	size_t  len, pos;
   30: };
   31: 
   32: typedef struct ops ops_t;
   33: 
   34: static int readfn(void *arg, char *buf, int len)
   35: {
   36: 	int sz;
   37: 	ops_t *ops = (ops_t *)arg;
   38: 
   39: 	sz = (int)(ops->len - ops->pos);
   40: 	if (sz < 0)
   41: 		sz = 0;
   42: 	if (len > sz)
   43: 		len = sz;
   44: 
   45: 	memcpy(buf, &ops->buf[ops->pos], len);
   46: 	ops->pos += len;
   47: 
   48: 	return len;
   49: }
   50: 
   51: static int writefn(void *arg, const char *buf, int len)
   52: {
   53: 	int sz;
   54: 	ops_t *ops = (ops_t *)arg;
   55: 
   56: 	sz = (int)(ops->len - ops->pos);
   57: 	if (sz < 0)
   58: 		sz = 0;
   59: 	if (len > sz)
   60: 		len = sz;
   61: 
   62: 	memcpy(&ops->buf[ops->pos], buf, len);
   63: 	ops->pos += len;
   64: 
   65: 	return len;
   66: }
   67: 
   68: static fpos_t seekfn(void *arg, fpos_t offset, int whence)
   69: {
   70: 	fpos_t pos;
   71: 	ops_t *ops = (ops_t *)arg;
   72: 
   73: 	switch (whence) {
   74: 	case SEEK_SET:
   75: 		pos = offset;
   76: 		break;
   77: 
   78: 	case SEEK_END:
   79: 		pos = ops->len + offset;
   80: 		break;
   81: 
   82: 	case SEEK_CUR:
   83: 		pos = ops->pos + offset;
   84: 		break;
   85: 
   86: 	default:
   87: 		return -1;
   88: 	}
   89: 
   90: 	if (pos < 0 || (size_t)pos > ops->len) {
   91: 		ops->pos = 0;
   92: 		return -1;
   93: 	}
   94: 
   95: 	return 0;
   96: }
   97: 
   98: static int closefn(void *arg)
   99: {
  100: 	free(arg);
  101: 	return 0;
  102: }
  103: 
  104: FILE *fmemopen(void *buf, size_t len, const char *type)
  105: {
  106: 	ops_t *ops = malloc(sizeof(*ops));
  107: 
  108: 	if (!ops)
  109: 		return NULL;
  110: 
  111: 	memset(ops, 0, sizeof(*ops));
  112: 	ops->buf = buf;
  113: 	ops->len = len;
  114: 	ops->pos = 0;
  115: 
  116: 	return funopen(ops, readfn, writefn, seekfn, closefn);
  117: }
  118: #elif defined(HAVE_WINDOWS_H)
  119: #include <io.h>
  120: #include <fcntl.h>
  121: #include <sys/stat.h>
  122: #include <windows.h>
  123: 
  124: FILE *fmemopen(void *buf, size_t len, const char *type)
  125: {
  126: 	int fd;
  127: 	FILE *fp;
  128: 	char tp[MAX_PATH - 13];
  129: 	char fn[MAX_PATH + 1];
  130: 
  131: 	if (!GetTempPathA(sizeof(tp), tp))
  132: 		return NULL;
  133: 
  134: 	if (!GetTempFileNameA(tp, "confuse", 0, fn))
  135: 		return NULL;
  136: 
  137: 	fd = _open(fn,
  138: 		_O_CREAT | _O_RDWR | _O_SHORT_LIVED | _O_TEMPORARY | _O_BINARY,
  139: 		_S_IREAD | _S_IWRITE);
  140: 	if (fd == -1)
  141: 		return NULL;
  142: 
  143: 	fp = _fdopen(fd, "w+");
  144: 	if (!fp) {
  145: 		_close(fd);
  146: 		return NULL;
  147: 	}
  148: 
  149: 	fwrite(buf, len, 1, fp);
  150: 	rewind(fp);
  151: 
  152: 	return fp;
  153: }
  154: 
  155: #else
  156: #error Sorry, this platform currently has no fmemopen() replacement.
  157: #endif
  158: 
  159: /**
  160:  * Local Variables:
  161:  *  indent-tabs-mode: t
  162:  *  c-file-style: "linux"
  163:  * End:
  164:  */

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