From b275f83f4b6d4b5c70d4db50f3083fad739f1fe6 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <andrewrandrianasulu@Andrews-MacBook-Pro.local>
Date: Wed, 19 Jun 2024 17:55:57 +0300
Subject: [PATCH 07/11] fmemopen.C implementation

---
 cinelerra-5.1/guicast/fmemopen.C | 170 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)
 create mode 100644 cinelerra-5.1/guicast/fmemopen.C

diff --git a/cinelerra-5.1/guicast/fmemopen.C b/cinelerra-5.1/guicast/fmemopen.C
new file mode 100644
index 00000000..bdb32dfe
--- /dev/null
+++ b/cinelerra-5.1/guicast/fmemopen.C
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017  Joachim Nilsson <troglobit@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+extern "C" {
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef __APPLE__
+#include <stdlib.h>
+#include <memory.h>
+
+struct ops {
+	char   *buf;
+	size_t  len, pos;
+};
+
+typedef struct ops ops_t;
+
+static int readfn(void *arg, char *buf, int len)
+{
+	int sz;
+	ops_t *ops = (ops_t *)arg;
+
+	sz = (int)(ops->len - ops->pos);
+	if (sz < 0)
+		sz = 0;
+	if (len > sz)
+		len = sz;
+
+	memcpy(buf, &ops->buf[ops->pos], len);
+	ops->pos += len;
+
+	return len;
+}
+
+static int writefn(void *arg, const char *buf, int len)
+{
+	int sz;
+	ops_t *ops = (ops_t *)arg;
+
+	sz = (int)(ops->len - ops->pos);
+	if (sz < 0)
+		sz = 0;
+	if (len > sz)
+		len = sz;
+
+	memcpy(&ops->buf[ops->pos], buf, len);
+	ops->pos += len;
+
+	return len;
+}
+
+static fpos_t seekfn(void *arg, fpos_t offset, int whence)
+{
+	fpos_t pos;
+	ops_t *ops = (ops_t *)arg;
+
+	switch (whence) {
+	case SEEK_SET:
+		pos = offset;
+		break;
+
+	case SEEK_END:
+		pos = ops->len + offset;
+		break;
+
+	case SEEK_CUR:
+		pos = ops->pos + offset;
+		break;
+
+	default:
+		return -1;
+	}
+
+	if (pos < 0 || (size_t)pos > ops->len) {
+		ops->pos = 0;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int closefn(void *arg)
+{
+	free(arg);
+	return 0;
+}
+
+FILE *fmemopen(void *buf, size_t len, const char *type)
+{
+	ops_t *ops = (ops_t *)(malloc(sizeof(*ops)));
+
+	if (!ops)
+		return NULL;
+
+	memset(ops, 0, sizeof(*ops));
+	ops->buf = (char *)(buf);
+	ops->len = len;
+	ops->pos = 0;
+
+	return funopen(ops, readfn, writefn, seekfn, closefn);
+}
+#elif defined(HAVE_WINDOWS_H)
+#include <io.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <windows.h>
+
+FILE *fmemopen(void *buf, size_t len, const char *type)
+{
+	int fd;
+	FILE *fp;
+	char tp[MAX_PATH - 13];
+	char fn[MAX_PATH + 1];
+
+	if (!GetTempPathA(sizeof(tp), tp))
+		return NULL;
+
+	if (!GetTempFileNameA(tp, "confuse", 0, fn))
+		return NULL;
+
+	fd = _open(fn,
+		_O_CREAT | _O_RDWR | _O_SHORT_LIVED | _O_TEMPORARY | _O_BINARY,
+		_S_IREAD | _S_IWRITE);
+	if (fd == -1)
+		return NULL;
+
+	fp = _fdopen(fd, "w+");
+	if (!fp) {
+		_close(fd);
+		return NULL;
+	}
+
+	fwrite(buf, len, 1, fp);
+	rewind(fp);
+
+	return fp;
+}
+
+#else
+#error Sorry, this platform currently has no fmemopen() replacement.
+#endif
+
+}
+
+
+/**
+ * Local Variables:
+ *  indent-tabs-mode: t
+ *  c-file-style: "linux"
+ * End:
+ */
-- 
2.13.5 (Apple Git-94)

