From b968b05d705db1840216db93ec50a16408287ba3 Mon Sep 17 00:00:00 2001 From: Baudouin Raoult Date: Mon, 2 Nov 2020 11:41:36 +0000 Subject: [PATCH] Support for MEMFS on older Linux --- CMakeLists.txt | 1 - memfs.py | 211 ++++++------------------------------------------- 2 files changed, 24 insertions(+), 188 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb9196b87..118c15f90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,6 @@ endif() ecbuild_add_option( FEATURE MEMFS DESCRIPTION "Memory based access to definitions/samples" DEFAULT OFF - CONDITION ECCODES_HAVE_FMEMOPEN OR ECCODES_HAVE_FUNOPEN OR (EC_OS_NAME MATCHES "windows") REQUIRED_PACKAGES PythonInterp ) #if( HAVE_MEMFS AND "${CMAKE_C_COMPILER_ID}" STREQUAL "Cray") diff --git a/memfs.py b/memfs.py index 642849cb2..428063633 100755 --- a/memfs.py +++ b/memfs.py @@ -107,7 +107,7 @@ for directory in dirs: # e.g. 23 -> 0x23 for n in range(0, len(contents_hex), 2): twoChars = ascii(contents_hex[n : n + 2]) - + buffer.write(encode("0x%s," % (twoChars,))) i += 1 @@ -130,195 +130,32 @@ opath = output_file_base + "_final.c" print("MEMFS: Generating output:", opath) g = open(opath, "w") -print( - """ -#include "eccodes_config.h" -#ifdef ECCODES_HAVE_FMEMOPEN -#define _GNU_SOURCE -#endif +f = open(os.path.join(os.path.dirname(__file__), "src", "memfs.c")) +for line in f.readlines(): + line = line.rstrip() + if "" in line: + # Write extern variables with sizes + for k, v in SIZES.items(): + print("extern const unsigned char %s[%d];" % (k, v), file=g) -#include -#include -#include -#include -#include "eccodes_windef.h" -""", - file=g, -) + print( + "static struct entry entries[] = {", + file=g, + ) + items = [(v, k) for k, v in FILES.items()] + for k, v in sorted(items): + print( + '{"/MEMFS%s", &%s[0], sizeof(%s) / sizeof(%s[0]) },' % (k, v, v, v), + file=g, + ) + print( + "};", + file=g, + ) -# Write extern variables with sizes -for k, v in SIZES.items(): - print("extern const unsigned char %s[%d];" % (k, v), file=g) + else: + print(line, file=g) -print( - """ -struct entry { - const char* path; - const unsigned char* content; - size_t length; -} entries[] = { """, - file=g, -) - -items = [(v, k) for k, v in FILES.items()] - -for k, v in sorted(items): - print('{"/MEMFS%s", &%s[0], sizeof(%s) / sizeof(%s[0]) },' % (k, v, v, v), file=g) - - -print( - """}; - -#if defined(ECCODES_HAVE_FUNOPEN) && !defined(ECCODES_HAVE_FMEMOPEN) - -typedef struct mem_file { - const char* buffer; - size_t size; - size_t pos; -} mem_file; - -static int read_mem(void *data, char * buf, int len) { - mem_file* f = (mem_file*)data; - int n = len; - - if(f->pos + n > f->size) { - n = f->size - f->pos; - } - - memcpy(buf, f->buffer + f->pos, n); - - f->pos += n; - return n; -} - -static int write_mem(void* data, const char* buf, int len) { - mem_file* f = (mem_file*)data; - return -1; -} - -static fpos_t seek_mem(void *data, fpos_t pos, int whence) { - mem_file* f = (mem_file*)data; - long newpos = 0; - - switch (whence) { - case SEEK_SET: - newpos = (long)pos; - break; - - case SEEK_CUR: - newpos = (long)f->pos + (long)pos; - break; - - case SEEK_END: - newpos = (long)f->size - (long)pos; - break; - - default: - return -1; - break; - } - - if(newpos < 0) { newpos = 0; } - if(newpos > f->size) { newpos = f->size; } - - f->pos = newpos; - return newpos; -} - -static int close_mem(void *data) { - mem_file* f = (mem_file*)data; - free(f); - return 0; -} - -static FILE* fmemopen(const char* buffer, size_t size, const char* mode){ - mem_file* f = (mem_file*)calloc(sizeof(mem_file), 1); - if(!f) return NULL; - - f->buffer = buffer; - f->size = size; - - return funopen(f, &read_mem, &write_mem, &seek_mem, &close_mem); -} - -#elif defined(ECCODES_ON_WINDOWS) - -#include -#include -#include - -static FILE *fmemopen(void* buffer, size_t size, const char* mode) { - char path[MAX_PATH - 13]; - if (!GetTempPath(sizeof(path), path)) - return NULL; - - char filename[MAX_PATH + 1]; - if (!GetTempFileName(path, "eccodes", 0, filename)) - return NULL; - - HANDLE h = CreateFile(filename, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - - if (h == INVALID_HANDLE_VALUE) - return NULL; - - int fd = _open_osfhandle((intptr_t)h, _O_RDWR); - if (fd < 0) { - CloseHandle(h); - return NULL; - } - - FILE* f = _fdopen(fd, "w+"); - if (!f) { - _close(fd); - return NULL; - } - - fwrite(buffer, size, 1, f); - rewind(f); - return f; -} - -#endif - -static size_t entries_count = sizeof(entries)/sizeof(entries[0]); - -static const unsigned char* find(const char* path, size_t* length) { - size_t i; - - for(i = 0; i < entries_count; i++) { - if(strcmp(path, entries[i].path) == 0) { - /*printf("Found in MEMFS %s\\n", path);*/ - *length = entries[i].length; - return entries[i].content; - } - } - - return NULL; -} - -int codes_memfs_exists(const char* path) { - size_t dummy; - return find(path, &dummy) != NULL; -} - -FILE* codes_memfs_open(const char* path) { - size_t size; - const unsigned char* mem = find(path, &size); - if(!mem) { - return NULL; - } - return fmemopen((void*)mem, size, "r"); -} - -""", - file=g, -) print("Finished")