mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 23:13:25 +00:00
parse-xml: read the file into memory separately
Using xmlParseFile() was simple, but I'm planning on extending the file parsing past just XML, since we want to be able to import other formats too. And quite frankly, that means that we'll want to read the file into memory to look at it before we start parsing it. We could decide do it by file extensions too, and I'll look at that approach as well, but regardless of how we do things it's almost certainly a good idea to do the file access in one place. The XML parsing might as well happen from a memory buffer instead anyway. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
11495bbb2b
commit
34dcc119fe
1 changed files with 62 additions and 1 deletions
63
parse-xml.c
63
parse-xml.c
|
@ -4,6 +4,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#define __USE_XOPEN
|
||||
#include <time.h>
|
||||
#include <libxml/parser.h>
|
||||
|
@ -1417,11 +1419,70 @@ static void reset_all(void)
|
|||
import_source = UNKNOWN;
|
||||
}
|
||||
|
||||
struct memblock {
|
||||
void *buffer;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static int readfile(const char *filename, struct memblock *mem)
|
||||
{
|
||||
int ret, fd = open(filename, O_RDONLY);
|
||||
struct stat st;
|
||||
|
||||
mem->buffer = NULL;
|
||||
mem->size = 0;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
ret = fstat(fd, &st);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = -EINVAL;
|
||||
if (!S_ISREG(st.st_mode))
|
||||
goto out;
|
||||
ret = 0;
|
||||
if (!st.st_size)
|
||||
goto out;
|
||||
mem->buffer = malloc(st.st_size);
|
||||
ret = -1;
|
||||
errno = ENOMEM;
|
||||
if (!mem->buffer)
|
||||
goto out;
|
||||
mem->size = st.st_size;
|
||||
ret = read(fd, mem->buffer, mem->size);
|
||||
if (ret < 0)
|
||||
goto free;
|
||||
if (ret == mem->size)
|
||||
goto out;
|
||||
errno = EIO;
|
||||
ret = -1;
|
||||
free:
|
||||
free(mem->buffer);
|
||||
mem->buffer = NULL;
|
||||
mem->size = 0;
|
||||
out:
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void parse_xml_file(const char *filename, GError **error)
|
||||
{
|
||||
xmlDoc *doc;
|
||||
struct memblock mem;
|
||||
|
||||
doc = xmlReadFile(filename, NULL, 0);
|
||||
if (readfile(filename, &mem) < 0) {
|
||||
fprintf(stderr, "Failed to read '%s'.\n", filename);
|
||||
if (error) {
|
||||
*error = g_error_new(g_quark_from_string("subsurface"),
|
||||
DIVE_ERROR_PARSE,
|
||||
"Failed to read '%s'",
|
||||
filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
doc = xmlReadMemory(mem.buffer, mem.size, filename, NULL, 0);
|
||||
if (!doc) {
|
||||
fprintf(stderr, "Failed to parse '%s'.\n", filename);
|
||||
if (error != NULL)
|
||||
|
|
Loading…
Add table
Reference in a new issue