mirror of https://github.com/ecmwf/eccodes.git
Support for MEMFS on older Linux
This commit is contained in:
parent
204e99805c
commit
b968b05d70
|
@ -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")
|
||||
|
|
211
memfs.py
211
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 "<MARKER>" 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#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 <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
|
||||
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")
|
||||
|
||||
|
|
Loading…
Reference in New Issue