You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2016/10/26 12:15:59 UTC
[36/50] [abbrv] celix git commit: CELIX-281: Moved
fmemopen/open_memstream to utils. Added usage of open_memstream to bonjour
shell for OSX.
CELIX-281: Moved fmemopen/open_memstream to utils. Added usage of open_memstream to bonjour shell for OSX.
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2c74cc35
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2c74cc35
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2c74cc35
Branch: refs/heads/master
Commit: 2c74cc35b573eb2e0b587065808181286f830362
Parents: 652741c
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Oct 14 21:10:15 2016 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Oct 14 21:10:15 2016 +0200
----------------------------------------------------------------------
dfi/CMakeLists.txt | 8 +-
dfi/private/src/memstream/fmemopen.c | 78 -----------
dfi/private/src/memstream/open_memstream.c | 130 -------------------
dfi/public/include/memstream/README.md | 49 -------
dfi/public/include/memstream/fmemopen.h | 52 --------
dfi/public/include/memstream/open_memstream.h | 15 ---
shell_bonjour/CMakeLists.txt | 8 +-
shell_bonjour/private/src/activator.c | 2 +-
shell_bonjour/private/src/bonjour_shell.c | 15 ++-
utils/private/src/memstream/fmemopen.c | 78 +++++++++++
utils/private/src/memstream/open_memstream.c | 130 +++++++++++++++++++
utils/public/include/memstream/README.md | 49 +++++++
utils/public/include/memstream/fmemopen.h | 52 ++++++++
utils/public/include/memstream/open_memstream.h | 15 +++
14 files changed, 348 insertions(+), 333 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/dfi/CMakeLists.txt b/dfi/CMakeLists.txt
index 6fe7071..c672f94 100644
--- a/dfi/CMakeLists.txt
+++ b/dfi/CMakeLists.txt
@@ -28,10 +28,10 @@ include_directories(
set(MEMSTREAM_SOURCES )
set(MEMSTREAM_INCLUDES )
-if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR ANDROID)
- set(MEMSTREAM_SOURCES private/src/memstream/open_memstream.c private/src/memstream/fmemopen.c)
- set(MEMSTREAM_INCLUDES public/include/memstream/open_memstream.h public/include/memstream/fmemopen.h)
- include_directories(public/include/memstream)
+if (APPLE OR ANDROID)
+ set(MEMSTREAM_SOURCES ${PROJECT_SOURCE_DIR}/utils/private/src/memstream/open_memstream.c ${PROJECT_SOURCE_DIR}/utils/private/src/memstream/fmemopen.c)
+ set(MEMSTREAM_INCLUDES ${PROJECT_SOURCE_DIR}/utils/public/include/memstream/open_memstream.h ${PROJECT_SOURCE_DIR}/utils/public/include/memstream/fmemopen.h)
+ include_directories(${PROJECT_SOURCE_DIR}/utils/public/include/memstream)
endif()
add_library(celix_dfi SHARED
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/private/src/memstream/fmemopen.c
----------------------------------------------------------------------
diff --git a/dfi/private/src/memstream/fmemopen.c b/dfi/private/src/memstream/fmemopen.c
deleted file mode 100644
index 66fc9c5..0000000
--- a/dfi/private/src/memstream/fmemopen.c
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/*
- * fmem.c : fmemopen() on top of BSD's funopen()
- * 20081017 AF
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef linux
-struct fmem {
- size_t pos;
- size_t size;
- char *buffer;
-};
-typedef struct fmem fmem_t;
-
-static int readfn(void *handler, char *buf, int size)
-{
- int count = 0;
- fmem_t *mem = handler;
- size_t available = mem->size - mem->pos;
-
- if(size > available) size = available;
- for(count=0; count < size; mem->pos++, count++)
- buf[count] = mem->buffer[mem->pos];
-
- return count;
-}
-
-static int writefn(void *handler, const char *buf, int size)
-{
- int count = 0;
- fmem_t *mem = handler;
- size_t available = mem->size - mem->pos;
-
- if(size > available) size = available;
- for(count=0; count < size; mem->pos++, count++)
- mem->buffer[mem->pos] = buf[count];
-
- return count; // ? count : size;
-}
-
-static fpos_t seekfn(void *handler, fpos_t offset, int whence)
-{
- size_t pos;
- fmem_t *mem = handler;
-
- switch(whence) {
- case SEEK_SET: pos = offset; break;
- case SEEK_CUR: pos = mem->pos + offset; break;
- case SEEK_END: pos = mem->size + offset; break;
- default: return -1;
- }
-
- if(pos > mem->size) return -1;
-
- mem->pos = pos;
- return (fpos_t) pos;
-}
-
-static int closefn(void *handler)
-{
- free(handler);
- return 0;
-}
-
-/* simple, but portable version of fmemopen for OS X / BSD */
-FILE *fmemopen(void *buf, size_t size, const char *mode)
-{
- fmem_t *mem = (fmem_t *) malloc(sizeof(fmem_t));
-
- memset(mem, 0, sizeof(fmem_t));
- mem->size = size, mem->buffer = buf;
- return funopen(mem, readfn, writefn, seekfn, closefn);
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/private/src/memstream/open_memstream.c
----------------------------------------------------------------------
diff --git a/dfi/private/src/memstream/open_memstream.c b/dfi/private/src/memstream/open_memstream.c
deleted file mode 100644
index 6bc4f01..0000000
--- a/dfi/private/src/memstream/open_memstream.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Use funopen(3) to provide open_memstream(3) like functionality. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-struct memstream {
- char **cp;
- size_t *lenp;
- size_t offset;
-};
-
-static void
-memstream_grow(struct memstream *ms, size_t newsize)
-{
- char *buf;
-
- if (newsize > *ms->lenp) {
- buf = realloc(*ms->cp, newsize + 1);
- if (buf != NULL) {
-#ifdef DEBUG
- fprintf(stderr, "MS: %p growing from %zd to %zd\n",
- ms, *ms->lenp, newsize);
-#endif
- memset(buf + *ms->lenp + 1, 0, newsize - *ms->lenp);
- *ms->cp = buf;
- *ms->lenp = newsize;
- }
- }
-}
-
-static int
-memstream_read(void *cookie, char *buf, int len)
-{
- struct memstream *ms;
- int tocopy;
-
- ms = cookie;
- memstream_grow(ms, ms->offset + len);
- tocopy = *ms->lenp - ms->offset;
- if (len < tocopy)
- tocopy = len;
- memcpy(buf, *ms->cp + ms->offset, tocopy);
- ms->offset += tocopy;
-#ifdef DEBUG
- fprintf(stderr, "MS: read(%p, %d) = %d\n", ms, len, tocopy);
-#endif
- return (tocopy);
-}
-
-static int
-memstream_write(void *cookie, const char *buf, int len)
-{
- struct memstream *ms;
- int tocopy;
-
- ms = cookie;
- memstream_grow(ms, ms->offset + len);
- tocopy = *ms->lenp - ms->offset;
- if (len < tocopy)
- tocopy = len;
- memcpy(*ms->cp + ms->offset, buf, tocopy);
- ms->offset += tocopy;
-#ifdef DEBUG
- fprintf(stderr, "MS: write(%p, %d) = %d\n", ms, len, tocopy);
-#endif
- return (tocopy);
-}
-
-static fpos_t
-memstream_seek(void *cookie, fpos_t pos, int whence)
-{
- struct memstream *ms;
-#ifdef DEBUG
- size_t old;
-#endif
-
- ms = cookie;
-#ifdef DEBUG
- old = ms->offset;
-#endif
- switch (whence) {
- case SEEK_SET:
- ms->offset = pos;
- break;
- case SEEK_CUR:
- ms->offset += pos;
- break;
- case SEEK_END:
- ms->offset = *ms->lenp + pos;
- break;
- }
-#ifdef DEBUG
- fprintf(stderr, "MS: seek(%p, %zd, %d) %zd -> %zd\n", ms, pos, whence,
- old, ms->offset);
-#endif
- return (ms->offset);
-}
-
-static int
-memstream_close(void *cookie)
-{
-
- free(cookie);
- return (0);
-}
-
-FILE *
-open_memstream(char **cp, size_t *lenp)
-{
- struct memstream *ms;
- int save_errno;
- FILE *fp;
-
- *cp = NULL;
- *lenp = 0;
- ms = malloc(sizeof(*ms));
- ms->cp = cp;
- ms->lenp = lenp;
- ms->offset = 0;
- fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
- memstream_close);
- if (fp == NULL) {
- save_errno = errno;
- free(ms);
- errno = save_errno;
- }
- return (fp);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/public/include/memstream/README.md
----------------------------------------------------------------------
diff --git a/dfi/public/include/memstream/README.md b/dfi/public/include/memstream/README.md
deleted file mode 100644
index 476810e..0000000
--- a/dfi/public/include/memstream/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-fmemopen for Mac OS and iOS
-===========================
-
-Originally ported from [ingenuitas python-tesseract](https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c). Ported by Jeff Verkoeyen under the Apache 2.0 License.
-
-From the fmemopen man page:
-
-> FILE *fmemopen(void *buf, size_t size, const char *mode);
->
-> The fmemopen() function opens a stream that permits the access specified by mode. The stream
-> allows I/O to be performed on the string or memory buffer pointed to by buf. This buffer must be
-> at least size bytes long.
-
-Alas, this method does not exist on BSD operating systems (specifically Mac OS X and iOS). It is
-possible to recreate this functionality using a BSD-specific method called `funopen`.
-
-From the funopen man page:
-
-> FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int),
-> int (*writefn)(void *, const char *, int), fpos_t (*seekfn)(void *, fpos_t, int),
-> int (*closefn)(void *));
->
-> The funopen() function associates a stream with up to four ``I/O functions''. Either readfn or
-> writefn must be specified; the others can be given as an appropriately-typed NULL pointer. These
-> I/O functions will be used to read, write, seek and close the new stream.
-
-fmemopen.c provides a simple implementation of fmemopen using funopen so that you can create FILE
-pointers to blocks of memory.
-
-Adding it to your Project
-=========================
-
-Drag fmemopen.h and fmemopen.c to your project and add them to your target. `#include "fmemopen.h"`
-wherever you need to use `fmemopen`.
-
-Examples
-========
-
-```obj-c
-#import "fmemopen.h"
-
-NSString* string = @"fmemopen in Objective-C";
-const char* cstr = [string UTF8String];
-FILE* file = fmemopen((void *)cstr, sizeof(char) * (string.length + 1), "r");
-
-// fread on file will now read the contents of the NSString
-
-fclose(file);
-```
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/public/include/memstream/fmemopen.h
----------------------------------------------------------------------
diff --git a/dfi/public/include/memstream/fmemopen.h b/dfi/public/include/memstream/fmemopen.h
deleted file mode 100644
index 3d06b20..0000000
--- a/dfi/public/include/memstream/fmemopen.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright 2012 Jeff Verkoeyen
-// Originally ported from https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef FMEMOPEN_H_
-#define FMEMOPEN_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * A BSD port of the fmemopen Linux method using funopen.
- *
- * man docs for fmemopen:
- * http://linux.die.net/man/3/fmemopen
- *
- * man docs for funopen:
- * https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/funopen.3.html
- *
- * This method is ported from ingenuitas' python-tesseract project.
- *
- * You must call fclose on the returned file pointer or memory will be leaked.
- *
- * @param buf The data that will be used to back the FILE* methods. Must be at least
- * @c size bytes.
- * @param size The size of the @c buf data.
- * @param mode The permitted stream operation modes.
- * @returns A pointer that can be used in the fread/fwrite/fseek/fclose family of methods.
- * If a failure occurred NULL will be returned.
- */
-FILE *fmemopen(void *buf, size_t size, const char *mode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/dfi/public/include/memstream/open_memstream.h
----------------------------------------------------------------------
diff --git a/dfi/public/include/memstream/open_memstream.h b/dfi/public/include/memstream/open_memstream.h
deleted file mode 100644
index e87bb0a..0000000
--- a/dfi/public/include/memstream/open_memstream.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef OPEN_MEMSTREAM_H_
-#define OPEN_MEMSTREAM_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-FILE *open_memstream(char **cp, size_t *lenp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/shell_bonjour/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/shell_bonjour/CMakeLists.txt b/shell_bonjour/CMakeLists.txt
index 38ef9a1..300fef0 100644
--- a/shell_bonjour/CMakeLists.txt
+++ b/shell_bonjour/CMakeLists.txt
@@ -30,12 +30,18 @@ if (SHELL_BONJOUR)
include_directories("${PROJECT_SOURCE_DIR}/shell/public/include")
include_directories("${LIBXML2_INCLUDE_DIR}")
include_directories("private/include")
-
+
+ set(MEMSTREAM_SOURCES )
+ if (APPLE OR ANDROID)
+ set(MEMSTREAM_SOURCES ${PROJECT_SOURCE_DIR}/utils/private/src/memstream/open_memstream.c ${PROJECT_SOURCE_DIR}/utils/private/src/memstream/fmemopen.c)
+ include_directories(${PROJECT_SOURCE_DIR}/utils/public/include/memstream)
+ endif()
add_bundle(bonjour_shell
VERSION "1.0.0"
SOURCES
private/src/activator.c
private/src/bonjour_shell.c
+ ${MEMSTREAM_SOURCES}
)
target_link_libraries(bonjour_shell celix_framework celix_utils ${LIBXML2_LIBRARIES} ${DNS_SD_LIB})
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/shell_bonjour/private/src/activator.c
----------------------------------------------------------------------
diff --git a/shell_bonjour/private/src/activator.c b/shell_bonjour/private/src/activator.c
index 75340b2..e05211d 100644
--- a/shell_bonjour/private/src/activator.c
+++ b/shell_bonjour/private/src/activator.c
@@ -73,7 +73,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
char id[128];
if (bonjourShellId != NULL) {
- snprintf(id, 128, bonjourShellId);
+ snprintf(id, 128, "%s", bonjourShellId);
} else if (hostname != NULL) {
snprintf(id, 128, "Celix-%.8s@%s", uuid, hostname);
} else {
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/shell_bonjour/private/src/bonjour_shell.c
----------------------------------------------------------------------
diff --git a/shell_bonjour/private/src/bonjour_shell.c b/shell_bonjour/private/src/bonjour_shell.c
index a93d3e1..59ee18a 100644
--- a/shell_bonjour/private/src/bonjour_shell.c
+++ b/shell_bonjour/private/src/bonjour_shell.c
@@ -40,6 +40,11 @@
#include <celixbool.h>
#include <shell.h>
+#if defined(BSD) || defined(__APPLE__) || defined(ANDROID)
+#include "open_memstream.h"
+#include "fmemopen.h"
+#endif
+
#define MAX_BUFFER_SIZE 5120
//static xmlBufferPtr buf; //FOR DEBUG
@@ -358,9 +363,13 @@ static void bonjourShell_parseCommand(bonjour_shell_pt shell, struct connection_
static void bonjourShell_addDataToCurrentContext(const char* out, const char* err) {
pthread_mutex_lock(¤tContext->mutex);
- arrayList_add(currentContext->dataList, strdup(out));
- arrayList_add(currentContext->dataList, strdup(err));
- gettimeofday(¤tContext->lastUpdated, NULL);
+ if (out != NULL) {
+ arrayList_add(currentContext->dataList, strdup(out));
+ }
+ if (err != NULL) {
+ arrayList_add(currentContext->dataList, strdup(err));
+ }
+ gettimeofday(¤tContext->lastUpdated, NULL);
pthread_mutex_unlock(¤tContext->mutex);
pthread_cond_signal(¤tContext->dataAvailCond);
}
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/utils/private/src/memstream/fmemopen.c
----------------------------------------------------------------------
diff --git a/utils/private/src/memstream/fmemopen.c b/utils/private/src/memstream/fmemopen.c
new file mode 100644
index 0000000..66fc9c5
--- /dev/null
+++ b/utils/private/src/memstream/fmemopen.c
@@ -0,0 +1,78 @@
+
+/*
+ * fmem.c : fmemopen() on top of BSD's funopen()
+ * 20081017 AF
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef linux
+struct fmem {
+ size_t pos;
+ size_t size;
+ char *buffer;
+};
+typedef struct fmem fmem_t;
+
+static int readfn(void *handler, char *buf, int size)
+{
+ int count = 0;
+ fmem_t *mem = handler;
+ size_t available = mem->size - mem->pos;
+
+ if(size > available) size = available;
+ for(count=0; count < size; mem->pos++, count++)
+ buf[count] = mem->buffer[mem->pos];
+
+ return count;
+}
+
+static int writefn(void *handler, const char *buf, int size)
+{
+ int count = 0;
+ fmem_t *mem = handler;
+ size_t available = mem->size - mem->pos;
+
+ if(size > available) size = available;
+ for(count=0; count < size; mem->pos++, count++)
+ mem->buffer[mem->pos] = buf[count];
+
+ return count; // ? count : size;
+}
+
+static fpos_t seekfn(void *handler, fpos_t offset, int whence)
+{
+ size_t pos;
+ fmem_t *mem = handler;
+
+ switch(whence) {
+ case SEEK_SET: pos = offset; break;
+ case SEEK_CUR: pos = mem->pos + offset; break;
+ case SEEK_END: pos = mem->size + offset; break;
+ default: return -1;
+ }
+
+ if(pos > mem->size) return -1;
+
+ mem->pos = pos;
+ return (fpos_t) pos;
+}
+
+static int closefn(void *handler)
+{
+ free(handler);
+ return 0;
+}
+
+/* simple, but portable version of fmemopen for OS X / BSD */
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+ fmem_t *mem = (fmem_t *) malloc(sizeof(fmem_t));
+
+ memset(mem, 0, sizeof(fmem_t));
+ mem->size = size, mem->buffer = buf;
+ return funopen(mem, readfn, writefn, seekfn, closefn);
+}
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/utils/private/src/memstream/open_memstream.c
----------------------------------------------------------------------
diff --git a/utils/private/src/memstream/open_memstream.c b/utils/private/src/memstream/open_memstream.c
new file mode 100644
index 0000000..6bc4f01
--- /dev/null
+++ b/utils/private/src/memstream/open_memstream.c
@@ -0,0 +1,130 @@
+/* Use funopen(3) to provide open_memstream(3) like functionality. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+struct memstream {
+ char **cp;
+ size_t *lenp;
+ size_t offset;
+};
+
+static void
+memstream_grow(struct memstream *ms, size_t newsize)
+{
+ char *buf;
+
+ if (newsize > *ms->lenp) {
+ buf = realloc(*ms->cp, newsize + 1);
+ if (buf != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "MS: %p growing from %zd to %zd\n",
+ ms, *ms->lenp, newsize);
+#endif
+ memset(buf + *ms->lenp + 1, 0, newsize - *ms->lenp);
+ *ms->cp = buf;
+ *ms->lenp = newsize;
+ }
+ }
+}
+
+static int
+memstream_read(void *cookie, char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(buf, *ms->cp + ms->offset, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: read(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static int
+memstream_write(void *cookie, const char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(*ms->cp + ms->offset, buf, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: write(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static fpos_t
+memstream_seek(void *cookie, fpos_t pos, int whence)
+{
+ struct memstream *ms;
+#ifdef DEBUG
+ size_t old;
+#endif
+
+ ms = cookie;
+#ifdef DEBUG
+ old = ms->offset;
+#endif
+ switch (whence) {
+ case SEEK_SET:
+ ms->offset = pos;
+ break;
+ case SEEK_CUR:
+ ms->offset += pos;
+ break;
+ case SEEK_END:
+ ms->offset = *ms->lenp + pos;
+ break;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "MS: seek(%p, %zd, %d) %zd -> %zd\n", ms, pos, whence,
+ old, ms->offset);
+#endif
+ return (ms->offset);
+}
+
+static int
+memstream_close(void *cookie)
+{
+
+ free(cookie);
+ return (0);
+}
+
+FILE *
+open_memstream(char **cp, size_t *lenp)
+{
+ struct memstream *ms;
+ int save_errno;
+ FILE *fp;
+
+ *cp = NULL;
+ *lenp = 0;
+ ms = malloc(sizeof(*ms));
+ ms->cp = cp;
+ ms->lenp = lenp;
+ ms->offset = 0;
+ fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
+ memstream_close);
+ if (fp == NULL) {
+ save_errno = errno;
+ free(ms);
+ errno = save_errno;
+ }
+ return (fp);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/utils/public/include/memstream/README.md
----------------------------------------------------------------------
diff --git a/utils/public/include/memstream/README.md b/utils/public/include/memstream/README.md
new file mode 100644
index 0000000..476810e
--- /dev/null
+++ b/utils/public/include/memstream/README.md
@@ -0,0 +1,49 @@
+fmemopen for Mac OS and iOS
+===========================
+
+Originally ported from [ingenuitas python-tesseract](https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c). Ported by Jeff Verkoeyen under the Apache 2.0 License.
+
+From the fmemopen man page:
+
+> FILE *fmemopen(void *buf, size_t size, const char *mode);
+>
+> The fmemopen() function opens a stream that permits the access specified by mode. The stream
+> allows I/O to be performed on the string or memory buffer pointed to by buf. This buffer must be
+> at least size bytes long.
+
+Alas, this method does not exist on BSD operating systems (specifically Mac OS X and iOS). It is
+possible to recreate this functionality using a BSD-specific method called `funopen`.
+
+From the funopen man page:
+
+> FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int),
+> int (*writefn)(void *, const char *, int), fpos_t (*seekfn)(void *, fpos_t, int),
+> int (*closefn)(void *));
+>
+> The funopen() function associates a stream with up to four ``I/O functions''. Either readfn or
+> writefn must be specified; the others can be given as an appropriately-typed NULL pointer. These
+> I/O functions will be used to read, write, seek and close the new stream.
+
+fmemopen.c provides a simple implementation of fmemopen using funopen so that you can create FILE
+pointers to blocks of memory.
+
+Adding it to your Project
+=========================
+
+Drag fmemopen.h and fmemopen.c to your project and add them to your target. `#include "fmemopen.h"`
+wherever you need to use `fmemopen`.
+
+Examples
+========
+
+```obj-c
+#import "fmemopen.h"
+
+NSString* string = @"fmemopen in Objective-C";
+const char* cstr = [string UTF8String];
+FILE* file = fmemopen((void *)cstr, sizeof(char) * (string.length + 1), "r");
+
+// fread on file will now read the contents of the NSString
+
+fclose(file);
+```
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/utils/public/include/memstream/fmemopen.h
----------------------------------------------------------------------
diff --git a/utils/public/include/memstream/fmemopen.h b/utils/public/include/memstream/fmemopen.h
new file mode 100644
index 0000000..3d06b20
--- /dev/null
+++ b/utils/public/include/memstream/fmemopen.h
@@ -0,0 +1,52 @@
+//
+// Copyright 2012 Jeff Verkoeyen
+// Originally ported from https://github.com/ingenuitas/python-tesseract/blob/master/fmemopen.c
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef FMEMOPEN_H_
+#define FMEMOPEN_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * A BSD port of the fmemopen Linux method using funopen.
+ *
+ * man docs for fmemopen:
+ * http://linux.die.net/man/3/fmemopen
+ *
+ * man docs for funopen:
+ * https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/funopen.3.html
+ *
+ * This method is ported from ingenuitas' python-tesseract project.
+ *
+ * You must call fclose on the returned file pointer or memory will be leaked.
+ *
+ * @param buf The data that will be used to back the FILE* methods. Must be at least
+ * @c size bytes.
+ * @param size The size of the @c buf data.
+ * @param mode The permitted stream operation modes.
+ * @returns A pointer that can be used in the fread/fwrite/fseek/fclose family of methods.
+ * If a failure occurred NULL will be returned.
+ */
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef FMEMOPEN_H_
http://git-wip-us.apache.org/repos/asf/celix/blob/2c74cc35/utils/public/include/memstream/open_memstream.h
----------------------------------------------------------------------
diff --git a/utils/public/include/memstream/open_memstream.h b/utils/public/include/memstream/open_memstream.h
new file mode 100644
index 0000000..e87bb0a
--- /dev/null
+++ b/utils/public/include/memstream/open_memstream.h
@@ -0,0 +1,15 @@
+#ifndef OPEN_MEMSTREAM_H_
+#define OPEN_MEMSTREAM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+FILE *open_memstream(char **cp, size_t *lenp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef FMEMOPEN_H_