Move is_gzipped_file to

io-gncxml-v2.c. Extend try_gz_open to read from gzipped files.
 Let gnc_xml2_find_ambiguous and parse_with_subst_push_handler
 read gzipped files.
Add gnc_is_our_first_xml_chunk.
Remove "error" from
 argument list of gnc_xml2_find_ambiguous.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@14217 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Andreas Köhler 2006-05-28 17:47:12 +00:00
parent 576bc55a73
commit c3b8cdcfc6
7 changed files with 161 additions and 117 deletions

View File

@ -1,3 +1,18 @@
2006-05-28 Andreas Köhler <andi5.py@gmx.net>
* src/backend/file/gnc-backend-file.c:
* src/backend/file/io-gncxml-v2.c: Move is_gzipped_file to
io-gncxml-v2.c. Extend try_gz_open to read from gzipped files.
Let gnc_xml2_find_ambiguous and parse_with_subst_push_handler
read gzipped files.
* src/backend/file/sixtp.c:
* src/backend/file/sixtp.h: Add gnc_is_our_first_xml_chunk.
* src/backend/file/io-gncxml-v2.h:
* src/gnome-utils/druid-gnc-xml-import.c: Remove "error" from
argument list of gnc_xml2_find_ambiguous.
2006-05-27 Joshua Sled <jsled@asynchronous.org>
* packaging/gnucash-1.9.x.ebuild: Add docs extraction, un-slot,

View File

@ -391,30 +391,6 @@ gnc_int_link_or_make_backup(FileBackend *be, const char *orig, const char *bkup)
/* ================================================================= */
static gboolean
is_gzipped_file(const gchar *name)
{
unsigned char buf[2];
int fd = open(name, O_RDONLY);
if(fd == 0)
{
return FALSE;
}
if(read(fd, buf, 2) != 2)
{
return FALSE;
}
if(buf[0] == 037 && buf[1] == 0213)
{
return TRUE;
}
return FALSE;
}
static QofBookFileType
gnc_file_be_determine_file_type(const char *path)
{
@ -427,8 +403,6 @@ gnc_file_be_determine_file_type(const char *path)
}
} else if (gnc_is_xml_data_file(path)) {
return GNC_BOOK_XML1_FILE;
} else if (is_gzipped_file(path)) {
return GNC_BOOK_XML2_FILE;
} else if (gnc_is_bin_file(path)) {
return GNC_BOOK_BIN_FILE;
}
@ -452,7 +426,6 @@ gnc_determine_file_type (const char *path)
if (sbuf.st_size == 0) { PINFO (" empty file"); return TRUE; }
if(gnc_is_xml_data_file_v2(path, NULL)) { return TRUE; }
else if(gnc_is_xml_data_file(path)) { return TRUE; }
else if(is_gzipped_file(path)) { return TRUE; }
else if(gnc_is_bin_file(path)) { return TRUE; }
PINFO (" %s is not a gnc file", path);
return FALSE;

View File

@ -23,6 +23,7 @@
#include <glib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
@ -1233,7 +1234,8 @@ gnc_book_write_accounts_to_xml_filehandle_v2(QofBackend *be, QofBook *book, FILE
#define BUFLEN 4096
static FILE *
try_gz_open (const char *filename, const char *perms, gboolean use_gzip)
try_gz_open (const char *filename, const char *perms, gboolean use_gzip,
gboolean compress)
{
if (strstr(filename, ".gz.") != NULL) /* its got a temp extension */
use_gzip = TRUE;
@ -1249,7 +1251,8 @@ try_gz_open (const char *filename, const char *perms, gboolean use_gzip)
the g_spawn glib wrappers. */
{
/* Start gzip from a command line, not by fork(). */
gchar *argv[] = {"gzip", NULL};
gchar *argv[] = {compress ? "gzip" : "gunzip",
NULL};
GPid child_pid;
GError *error;
int child_stdin;
@ -1268,7 +1271,7 @@ try_gz_open (const char *filename, const char *perms, gboolean use_gzip)
/* FIXME: Now need to set up the child process to write to the
file. */
return fdopen(child_stdin, "w");
return fdopen(child_stdin, compress ? "w" : "r");
/* Eventually the GPid must be cleanup up, but not here? */
/* g_spawn_close_pid(child_pid); */
@ -1293,24 +1296,39 @@ try_gz_open (const char *filename, const char *perms, gboolean use_gzip)
case 0: /* child */ {
char buffer[BUFLEN];
unsigned bytes;
gzFile *out;
gzFile *file;
close(filedes[1]);
out = gzopen(filename, perms);
if (out == NULL) {
PWARN("child gzopen failed\n");
exit(0);
file = gzopen(filename, perms);
if (file == NULL) {
PWARN("child gzopen failed\n");
exit(0);
}
while ((bytes = read(filedes[0], buffer, BUFLEN)) > 0)
gzwrite(out, buffer, bytes);
gzclose(out);
if (compress) {
close(filedes[1]);
while ((bytes = read(filedes[0], buffer, BUFLEN)) > 0)
gzwrite(file, buffer, bytes);
}
else
{
close(filedes[0]);
while ((bytes = gzread(file, buffer, BUFLEN)) > 0)
write(filedes[1], buffer, bytes);
}
gzclose(file);
_exit(0);
}
default: /* parent */
sleep(2);
close(filedes[0]);
return fdopen(filedes[1], "w");
if (compress) {
close(filedes[0]);
return fdopen(filedes[1], "w");
}
else
{
close(filedes[1]);
return fdopen(filedes[0], "r");
}
}
}
#endif
@ -1324,7 +1342,7 @@ gnc_book_write_to_xml_file_v2(
{
FILE *out;
out = try_gz_open(filename, "w", compress);
out = try_gz_open(filename, "w", compress, TRUE);
if (out == NULL)
{
return FALSE;
@ -1374,10 +1392,55 @@ gnc_book_write_accounts_to_xml_file_v2(
}
/***********************************************************************/
static gboolean
is_gzipped_file(const gchar *name)
{
unsigned char buf[2];
int fd = open(name, O_RDONLY);
if (fd == -1) {
return FALSE;
}
if (read(fd, buf, 2) != 2) {
close(fd);
return FALSE;
}
close(fd);
if (buf[0] == 037 && buf[1] == 0213) {
return TRUE;
}
return FALSE;
}
gboolean
gnc_is_xml_data_file_v2(const gchar *name, gboolean *with_encoding)
{
return gnc_is_our_xml_file(name, GNC_V2_STRING, with_encoding);
if (gnc_is_our_xml_file(name, GNC_V2_STRING, with_encoding))
return TRUE;
if (is_gzipped_file(name)) {
gzFile *file;
char first_chunk[256];
int num_read;
file = gzopen(name, "r");
if (file == NULL)
return FALSE;
num_read = gzread(file, first_chunk, sizeof(first_chunk) - 1);
gzclose(file);
if (num_read < 1)
return FALSE;
return gnc_is_our_first_xml_chunk(first_chunk, GNC_V2_STRING,
with_encoding);
}
return FALSE;
}
@ -1447,29 +1510,25 @@ typedef struct {
gint
gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings,
GHashTable **unique, GHashTable **ambiguous,
GList **impossible, GError **error)
GList **impossible)
{
GIOChannel *channel=NULL;
GIOStatus status;
FILE *file=NULL;
GList *iconv_list=NULL, *conv_list=NULL, *iter;
iconv_item_type *iconv_item=NULL, *ascii=NULL;
const gchar *enc;
GHashTable *processed=NULL;
gint n_impossible = 0;
gboolean clean_return = FALSE;
GError *error=NULL;
gboolean is_compressed;
gboolean clean_return=FALSE;
channel = g_io_channel_new_file(filename, "r", error);
if (*error) {
is_compressed = is_gzipped_file(filename);
file = try_gz_open(filename, "r", is_compressed, FALSE);
if (file == NULL) {
PWARN("Unable to open file %s", filename);
goto cleanup_find_ambs;
}
status = g_io_channel_set_encoding(channel, NULL, error);
if (status != G_IO_STATUS_NORMAL) {
PWARN("Error on unsetting encoding on IOChannel");
goto cleanup_find_ambs;
}
/* we need ascii */
ascii = g_new(iconv_item_type, 1);
ascii->encoding = g_quark_from_string("ASCII");
@ -1510,25 +1569,21 @@ gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings,
/* loop through lines */
while (1) {
gchar *line, *word, *utf8;
gchar line[256], *word, *utf8;
gchar **word_array, **word_cursor;
conv_type *conv = NULL;
status = g_io_channel_read_line(channel, &line, NULL, NULL, error);
if (status == G_IO_STATUS_EOF) {
break;
}
if (status == G_IO_STATUS_AGAIN) {
continue;
}
if (status != G_IO_STATUS_NORMAL) {
goto cleanup_find_ambs;
if (!fgets(line, sizeof(line)-1, file)) {
if (feof(file)) {
break;
} else {
goto cleanup_find_ambs;
}
}
g_strchomp(line);
replace_character_references(line);
word_array = g_strsplit_set(line, "> <", 0);
g_free(line);
/* loop through words */
for (word_cursor = word_array; *word_cursor; word_cursor++) {
@ -1537,14 +1592,14 @@ gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings,
continue;
utf8 = g_convert_with_iconv(word, -1, ascii->iconv,
NULL, NULL, error);
NULL, NULL, &error);
if (utf8) {
/* pure ascii */
g_free(utf8);
continue;
}
g_error_free(*error);
*error = NULL;
g_error_free(error);
error = NULL;
if (g_hash_table_lookup_extended(processed, word, NULL, NULL)) {
/* already processed */
@ -1556,15 +1611,15 @@ gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings,
for (iter = iconv_list; iter; iter = iter->next) {
iconv_item = iter->data;
utf8 = g_convert_with_iconv(word, -1, iconv_item->iconv,
NULL, NULL, error);
NULL, NULL, &error);
if (utf8) {
conv = g_new(conv_type, 1);
conv->encoding = iconv_item->encoding;
conv->utf8_string = utf8;
conv_list = g_list_prepend(conv_list, conv);
} else {
g_error_free(*error);
*error = NULL;
g_error_free(error);
error = NULL;
}
}
@ -1616,8 +1671,8 @@ gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings,
g_hash_table_destroy(processed);
if (ascii)
g_free(ascii);
if (channel)
g_io_channel_unref(channel);
if (file)
fclose(file);
return (clean_return) ? n_impossible : -1;
}
@ -1631,21 +1686,18 @@ static void
parse_with_subst_push_handler (xmlParserCtxtPtr xml_context,
push_data_type *push_data)
{
GIOChannel *channel=NULL;
GIOStatus status;
const gchar *filename;
FILE *file = NULL;
GIConv ascii=(GIConv)-1;
GString *output=NULL;
GError *error=NULL;
gboolean is_compressed;
channel = g_io_channel_new_file(push_data->filename, "r", &error);
if (error) {
PWARN("Unable to open file %s", push_data->filename);
goto cleanup_push_handler;
}
status = g_io_channel_set_encoding(channel, NULL, &error);
if (status != G_IO_STATUS_NORMAL) {
PWARN("Error on unsetting encoding on IOChannel");
filename = push_data->filename;
is_compressed = is_gzipped_file(filename);
file = try_gz_open(filename, "r", is_compressed, FALSE);
if (file == NULL) {
PWARN("Unable to open file %s", filename);
goto cleanup_push_handler;
}
@ -1657,24 +1709,20 @@ parse_with_subst_push_handler (xmlParserCtxtPtr xml_context,
/* loop through lines */
while (1) {
gchar *line, *word, *repl, *utf8;
gchar line[256], *word, *repl, *utf8;
gint pos, len;
gchar *start, *cursor;
status = g_io_channel_read_line(channel, &line, NULL, NULL, &error);
if (status == G_IO_STATUS_EOF) {
break;
}
if (status == G_IO_STATUS_AGAIN) {
continue;
}
if (status != G_IO_STATUS_NORMAL) {
goto cleanup_push_handler;
if (!fgets(line, sizeof(line)-1, file)) {
if (feof(file)) {
break;
} else {
goto cleanup_push_handler;
}
}
replace_character_references(line);
output = g_string_new(line);
g_free(line);
/* loop through words */
cursor = output->str;
@ -1740,8 +1788,8 @@ parse_with_subst_push_handler (xmlParserCtxtPtr xml_context,
g_string_free(output, TRUE);
if (ascii != (GIConv) -1)
g_iconv_close(ascii);
if (channel)
g_io_channel_unref(channel);
if (file)
fclose(file);
}
gboolean

View File

@ -180,10 +180,10 @@ typedef struct {
*/
gint gnc_xml2_find_ambiguous(
const gchar *filename, GList *encodings, GHashTable **unique,
GHashTable **ambiguous, GList **impossible, GError **error);
GHashTable **ambiguous, GList **impossible);
typedef gint (*find_ambiguous_handler)(
const gchar *filename, GList *encodings, GHashTable **unique,
GHashTable **ambiguous, GList **impossible, GError **error);
GHashTable **ambiguous, GList **impossible);
/** Parse a file in push mode, but replace byte sequences in the file given a
* hash table of substitutions

View File

@ -838,16 +838,11 @@ gnc_is_our_xml_file(const char *filename, const char *first_tag,
{
FILE *f = NULL;
char first_chunk[256];
unsigned char* cursor = NULL;
ssize_t num_read;
g_return_val_if_fail(filename, FALSE);
g_return_val_if_fail(first_tag, FALSE);
if (with_encoding) {
*with_encoding = FALSE;
}
f = fopen(filename, "r");
if (f == NULL) {
return FALSE;
@ -856,21 +851,34 @@ gnc_is_our_xml_file(const char *filename, const char *first_tag,
num_read = fread(first_chunk, sizeof(char), sizeof(first_chunk) - 1, f);
fclose(f);
if(num_read == 0)
if(num_read == 0)
{
return FALSE;
}
first_chunk[num_read] = '\0';
cursor = first_chunk;
return gnc_is_our_first_xml_chunk(first_chunk, first_tag, with_encoding);
}
gboolean
gnc_is_our_first_xml_chunk(char *chunk, const char *first_tag,
gboolean *with_encoding)
{
unsigned char* cursor = NULL;
if (with_encoding) {
*with_encoding = FALSE;
}
cursor = chunk;
if(!eat_whitespace(&cursor))
{
return FALSE;
}
if(strncmp(cursor, "<?xml", 5) == 0)
if(strncmp(cursor, "<?xml", 5) == 0)
{
char *tag_compare;
gboolean result;
@ -892,7 +900,7 @@ gnc_is_our_xml_file(const char *filename, const char *first_tag,
if (result && with_encoding) {
*cursor = '\0';
cursor = first_chunk;
cursor = chunk;
while (search_for('e', &cursor)) {
if (strncmp(cursor, "ncoding=", 8) == 0) {
*with_encoding = TRUE;

View File

@ -207,5 +207,8 @@ gboolean sixtp_add_sub_parser(sixtp *parser, const gchar* tag,
gboolean gnc_is_our_xml_file(const char *filename, const char *first_tag,
gboolean *with_encoding);
gboolean gnc_is_our_first_xml_chunk(char *chunk, const char *first_tag,
gboolean *with_encoding);
#endif /* _SIXTP_H_ */

View File

@ -570,8 +570,6 @@ gxi_session_destroy (GncXmlImportData *data)
static void
gxi_check_file (GncXmlImportData *data)
{
GError *error=NULL;
if (!data->encodings) {
gboolean is_utf8;
const gchar *locale_enc;
@ -630,8 +628,7 @@ gxi_check_file (GncXmlImportData *data)
/* analyze file */
data->n_impossible = (*find_ambiguous) (
data->filename, data->encodings, &data->unique, &data->ambiguous_ht,
NULL, &error);
data->filename, data->encodings, &data->unique, &data->ambiguous_ht, NULL);
if (data->n_impossible != -1) {
/* sort ambiguous words */