Annotation of embedaddon/confuse/src/fmemopen.c, revision 1.1
1.1 ! misho 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>