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>