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