[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/stdio/fmemopen.c b/ap/build/uClibc/libc/stdio/fmemopen.c
new file mode 100644
index 0000000..4a67376
--- /dev/null
+++ b/ap/build/uClibc/libc/stdio/fmemopen.c
@@ -0,0 +1,181 @@
+/* Copyright (C) 2004       Manuel Novoa III    <mjn3@codepoet.org>
+ *
+ * GNU Library General Public License (LGPL) version 2 or later.
+ *
+ * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
+ */
+
+#include <features.h>
+
+#ifdef __USE_GNU
+#include "_stdio.h"
+
+
+#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
+#error no custom streams!
+#endif
+
+typedef struct {
+	size_t pos;
+	size_t len;
+	size_t eof;
+	int dynbuf;
+	unsigned char *buf;
+	FILE *fp;
+} __fmo_cookie;
+
+#define COOKIE ((__fmo_cookie *) cookie)
+
+static ssize_t fmo_read(register void *cookie, char *buf, size_t bufsize)
+{
+	size_t count = COOKIE->len - COOKIE->pos;
+
+	/* Note: 0 < bufsize < SSIZE_MAX because of _stdio_READ. */
+	if (!count) {				/* EOF! */
+		return 0;
+	}
+
+	if (bufsize > count) {
+		bufsize = count;
+	}
+
+	memcpy(buf, COOKIE->buf + COOKIE->pos, bufsize);
+	COOKIE->pos += bufsize;
+
+	return bufsize;
+}
+
+static ssize_t fmo_write(register void *cookie, const char *buf, size_t bufsize)
+{
+	size_t count;
+
+	/* Note: bufsize < SSIZE_MAX because of _stdio_WRITE. */
+
+	/* If appending, need to seek to end of file!!!! */
+	if (COOKIE->fp->__modeflags & __FLAG_APPEND) {
+		COOKIE->pos = COOKIE->eof;
+	}
+
+	count = COOKIE->len - COOKIE->pos;
+
+	if (bufsize > count) {
+		bufsize = count;
+		if (count == 0) {		/* We're at the end of the buffer... */
+			__set_errno(EFBIG);
+			return -1;
+		}
+	}
+
+	memcpy(COOKIE->buf + COOKIE->pos, buf, bufsize);
+	COOKIE->pos += bufsize;
+
+	if (COOKIE->pos > COOKIE->eof) {
+		COOKIE->eof = COOKIE->pos;
+		if (bufsize < count) {	/* New eof and still room in buffer? */
+			*(COOKIE->buf + COOKIE->pos) = 0;
+		}
+	}
+
+	return bufsize;
+}
+
+/* glibc doesn't allow seeking, but it has in-buffer seeks... we don't. */
+static int fmo_seek(register void *cookie, __offmax_t *pos, int whence)
+{
+	__offmax_t p = *pos;
+
+	/* Note: fseek already checks that whence is legal, so don't check here
+	 * unless debugging. */
+	assert(((unsigned int) whence) <= 2);
+
+	if (whence != SEEK_SET) {
+		p += (whence == SEEK_CUR) ? COOKIE->pos : /* SEEK_END */ COOKIE->eof;
+	}
+
+	/* Note: glibc only allows seeking in the buffer.  We'll actually restrict
+	 * to the data. */
+	/* Check for offset < 0, offset > eof, or offset overflow... */
+	if (((uintmax_t) p) > COOKIE->eof) {
+		return -1;
+	}
+
+	COOKIE->pos = *pos = p;
+	return 0;
+}
+
+static int fmo_close(register void *cookie)
+{
+	if (COOKIE->dynbuf) {
+		free(COOKIE->buf);
+	}
+	free(cookie);
+	return 0;
+}
+
+#undef COOKIE
+
+static const cookie_io_functions_t _fmo_io_funcs = {
+	fmo_read, fmo_write, fmo_seek, fmo_close
+};
+
+/* TODO: If we have buffers enabled, it might be worthwile to add a pointer
+ * to the FILE in the cookie and have read, write, and seek operate directly
+ * on the buffer itself (ie replace the FILE buffer with the cookie buffer
+ * and update FILE bufstart, etc. whenever we seek). */
+
+FILE *fmemopen(void *s, size_t len, const char *modes)
+{
+	FILE *fp;
+	register __fmo_cookie *cookie;
+	size_t i;
+
+	if ((cookie = malloc(sizeof(__fmo_cookie))) != NULL) {
+		cookie->len = len;
+		cookie->eof = cookie->pos = 0; /* pos and eof adjusted below. */
+		cookie->dynbuf = 0;
+		if (((cookie->buf = s) == NULL) && (len > 0)) {
+			if ((cookie->buf = malloc(len)) == NULL) {
+				goto EXIT_cookie;
+			}
+			cookie->dynbuf = 1;
+			*cookie->buf = 0;	/* If we're appending, treat as empty file. */
+		}
+
+#ifndef __BCC__
+		fp = fopencookie(cookie, modes, _fmo_io_funcs);
+#else
+		fp = fopencookie(cookie, modes, &_fmo_io_funcs);
+#endif
+		/* Note: We don't need to worry about locking fp in the thread case
+		 * as the only possible access would be a close or flush with
+		 * nothing currently in the FILE's write buffer. */
+
+		if (fp != NULL) {
+			cookie->fp = fp;
+			if (fp->__modeflags & __FLAG_READONLY) {
+				cookie->eof = len;
+			}
+			if ((fp->__modeflags & __FLAG_APPEND) && (len > 0)) {
+				for (i = 0 ; i < len ; i++) {
+					if (cookie->buf[i] == 0) {
+						break;
+					}
+				}
+				cookie->eof = cookie->pos = i; /* Adjust eof and pos. */
+			}
+
+			__STDIO_STREAM_VALIDATE(fp);
+
+			return fp;
+		}
+	}
+
+	if (!s) {
+		free(cookie->buf);
+	}
+ EXIT_cookie:
+	free(cookie);
+
+	return NULL;
+}
+#endif