[gcab] Should work on various byte-order
- From: Marc-Andre Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcab] Should work on various byte-order
- Date: Fri, 4 Jan 2013 22:57:40 +0000 (UTC)
commit 70cc64483a1ebf183dba108b8decfeeff4de5e24
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date: Sat Dec 22 00:16:40 2012 +0100
Should work on various byte-order
libgcab/cabinet.c | 117 ++++++++++++++++++++++++++----------------------
libgcab/cabinet.h | 24 ++++++++--
libgcab/gcab-cabinet.c | 56 +++++++++++-----------
3 files changed, 112 insertions(+), 85 deletions(-)
---
diff --git a/libgcab/cabinet.c b/libgcab/cabinet.c
index 0aeb959..a946968 100644
--- a/libgcab/cabinet.c
+++ b/libgcab/cabinet.c
@@ -43,60 +43,64 @@ cdata_set (cdata_t *cd, int type, guint8 *data, size_t size)
}
}
-#define W(data, count) \
- g_output_stream_write (out, data, count, NULL, error)
-
-G_GNUC_INTERNAL gssize
-cheader_write (cheader_t *ch, GOutputStream *out, GError **error)
+#define W1(val) \
+ g_data_output_stream_put_byte (out, val, cancellable, error)
+#define W2(val) \
+ g_data_output_stream_put_uint16 (out, val, cancellable, error)
+#define W4(val) \
+ g_data_output_stream_put_uint32 (out, val, cancellable, error)
+#define WS(val) \
+ g_data_output_stream_put_string (out, val, cancellable, error)
+
+G_GNUC_INTERNAL gboolean
+cheader_write (cheader_t *ch, GDataOutputStream *out,
+ GCancellable *cancellable, GError **error)
{
- ch->versionMIN = 3;
- ch->versionMAJ = 1;
-
- if ((W ("MSCF", 4) == -1) ||
- (W (&ch->res1, 4) == -1) ||
- (W (&ch->size, 4) == -1) ||
- (W (&ch->res2, 4) == -1) ||
- (W (&ch->offsetfiles, 4) == -1) ||
- (W (&ch->res3, 4) == -1) ||
- (W (&ch->versionMIN, 1) == -1) ||
- (W (&ch->versionMAJ, 1) == -1) ||
- (W (&ch->nfolders, 2) == -1) ||
- (W (&ch->nfiles, 2) == -1) ||
- (W (&ch->flags, 2) == -1) ||
- (W (&ch->setID, 2) == -1) ||
- (W (&ch->cabID, 2) == -1))
- return -1;
-
- return 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 2 + 2 + 2 + 2 + 2;
+ if (!W1 ('M') || !W1 ('S') || !W1 ('C') || !W1 ('F') ||
+ !W4 (ch->res1) ||
+ !W4 (ch->size) ||
+ !W4 (ch->res2) ||
+ !W4 (ch->offsetfiles) ||
+ !W4 (ch->res3) ||
+ !W1 (ch->versionMIN = 3) ||
+ !W1 (ch->versionMAJ = 1) ||
+ !W2 (ch->nfolders) ||
+ !W2 (ch->nfiles) ||
+ !W2 (ch->flags) ||
+ !W2 (ch->setID) ||
+ !W2 (ch->cabID))
+ return FALSE;
+
+ return TRUE;
}
-G_GNUC_INTERNAL gssize
-cfolder_write (cfolder_t *cf, GOutputStream *out, GError **error)
+G_GNUC_INTERNAL gboolean
+cfolder_write (cfolder_t *cf, GDataOutputStream *out,
+ GCancellable *cancellable, GError **error)
{
- if ((W (&cf->offsetdata, 4) == -1) ||
- (W (&cf->ndatab, 2) == -1) ||
- (W (&cf->typecomp, 2) == -1))
- return -1;
+ if ((!W4 (cf->offsetdata)) ||
+ (!W2 (cf->ndatab)) ||
+ (!W2 (cf->typecomp)))
+ return FALSE;
- return 4 + 2 + 2;
+ return TRUE;
}
-G_GNUC_INTERNAL gssize
-cfile_write (cfile_t *cf, GOutputStream *out, GError **error)
+G_GNUC_INTERNAL gboolean
+cfile_write (cfile_t *cf, GDataOutputStream *out,
+ GCancellable *cancellable, GError **error)
{
- const gchar *name = cf->name;
-
- if ((W (&cf->usize, 4) == -1) ||
- (W (&cf->uoffset, 4) == -1) ||
- (W (&cf->index, 2) == -1) ||
- (W (&cf->date, 2) == -1) ||
- (W (&cf->time, 2) == -1) ||
- (W (&cf->fattr, 2) == -1) ||
- (W (name, strlen (name) + 1) == -1))
- return -1;
-
- return 4 + 4 + 2 + 2 + 2 + 2 + strlen (name) + 1;
+ if ((!W4 (cf->usize)) ||
+ (!W4 (cf->uoffset)) ||
+ (!W2 (cf->index)) ||
+ (!W2 (cf->date)) ||
+ (!W2 (cf->time)) ||
+ (!W2 (cf->fattr)) ||
+ (!WS (cf->name) || !W1 (0)))
+ return FALSE;
+
+ return TRUE;
}
typedef unsigned long int CHECKSUM;
@@ -133,18 +137,25 @@ compute_checksum (guint8 *in, u2 ncbytes, CHECKSUM seed)
return csum;
}
-G_GNUC_INTERNAL gssize
-cdata_write(cdata_t *cd, GOutputStream *out, int type, guint8 *data, size_t size, GError **error)
+G_GNUC_INTERNAL gboolean
+cdata_write (cdata_t *cd, GDataOutputStream *out, int type,
+ guint8 *data, size_t size, gsize *bytes_written,
+ GCancellable *cancellable, GError **error)
{
cdata_set(cd, type, data, size);
CHECKSUM datacsum = compute_checksum(cd->data, cd->ncbytes, 0);
cd->checksum = compute_checksum ((guint8*)&cd->ncbytes, 4, datacsum);
+ GOutputStream *stream = g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (out));
+
+ *bytes_written = 0;
+
+ if ((!W4 (cd->checksum)) ||
+ (!W2 (cd->ncbytes)) ||
+ (!W2 (cd->nubytes)) ||
+ (g_output_stream_write (stream, cd->data, cd->ncbytes, cancellable, error) == -1))
+ return FALSE;
- if ((W (&cd->checksum, 4) == -1) ||
- (W (&cd->ncbytes, 2) == -1) ||
- (W (&cd->nubytes, 2) == -1) ||
- (W (cd->data, cd->ncbytes) == -1))
- return -1;
+ *bytes_written = 4 + 2 + 2 + cd->ncbytes;
- return 4 + 2 + 2 + cd->ncbytes;
+ return TRUE;
}
diff --git a/libgcab/cabinet.h b/libgcab/cabinet.h
index 1eabc0c..3d575c9 100644
--- a/libgcab/cabinet.h
+++ b/libgcab/cabinet.h
@@ -80,9 +80,25 @@ struct cdata
guint8 data[DATABLOCKSIZE*2];
};
-gssize cheader_write (cheader_t *ch, GOutputStream *out, GError **error);
-gssize cfolder_write (cfolder_t *cf, GOutputStream *out, GError **error);
-gssize cdata_write (cdata_t *cd, GOutputStream *out, int type, guint8 *data, size_t size, GError **error);
-gssize cfile_write (cfile_t *cf, GOutputStream *out, GError **error);
+gboolean cheader_write (cheader_t *ch,
+ GDataOutputStream *out,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cfolder_write (cfolder_t *cf,
+ GDataOutputStream *out,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cdata_write (cdata_t *cd,
+ GDataOutputStream *out,
+ int type,
+ guint8 *data,
+ size_t size,
+ gsize *bytes_written,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cfile_write (cfile_t *cf,
+ GDataOutputStream *out,
+ GCancellable *cancellable,
+ GError **error);
#endif /* CABINET_H */
diff --git a/libgcab/gcab-cabinet.c b/libgcab/gcab-cabinet.c
index d0fe1b8..3dab4de 100644
--- a/libgcab/gcab-cabinet.c
+++ b/libgcab/gcab-cabinet.c
@@ -147,6 +147,12 @@ gcab_cabinet_write (GCabCabinet *self,
GCabFolder *cabfolder = g_ptr_array_index (self->folders, 0);
GCabFile *file;
gsize nfiles = gcab_folder_get_nfiles (cabfolder);
+ GInputStream *in = NULL;
+ GDataOutputStream *dstream = NULL;
+ gboolean success = FALSE;
+
+ dstream = g_data_output_stream_new (out);
+ g_data_output_stream_set_byte_order (dstream, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
size_t sumstr = 0;
g_hash_table_iter_init (&iter, cabfolder->files);
@@ -159,62 +165,53 @@ gcab_cabinet_write (GCabCabinet *self,
if (!g_seekable_seek (G_SEEKABLE (out), folder.offsetdata,
G_SEEK_SET, NULL, error))
- return FALSE;
-
+ goto end;
gssize len, offset = 0;
cdata_t block = { 0, };
guint8 data[DATABLOCKSIZE];
-
+ gsize written;
g_hash_table_iter_init (&iter, cabfolder->files);
while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&file)) {
if (file_callback)
file_callback (file, callback_data);
- GInputStream *in = G_INPUT_STREAM (g_file_read (file->file, cancellable, error));
- if (*error) {
- g_object_unref (in);
- return FALSE;
- }
+ in = G_INPUT_STREAM (g_file_read (file->file, cancellable, error));
+ if (*error)
+ goto end;
while ((len = g_input_stream_read (in,
&data[offset], DATABLOCKSIZE - offset,
cancellable, error)) == (DATABLOCKSIZE - offset)) {
- ssize_t written = cdata_write (&block, out, folder.typecomp, data, DATABLOCKSIZE, error);
+ if (!cdata_write (&block, dstream, folder.typecomp, data, DATABLOCKSIZE, &written, cancellable, error))
+ goto end;
header.size += written;
offset = 0;
}
- if (len == -1) {
- g_object_unref (in);
- return FALSE;
- }
+ if (len == -1)
+ goto end;
offset += len;
- g_object_unref (in);
}
if (offset != 0) {
- ssize_t written = cdata_write (&block, out, folder.typecomp, data, offset, error);
- if (written == -1)
- return FALSE;
+ if (!cdata_write (&block, dstream, folder.typecomp, data, offset, &written, cancellable, error))
+ goto end;
header.size += written;
}
- if (!g_output_stream_flush (out, cancellable, error))
- return FALSE;
-
if (!g_seekable_seek (G_SEEKABLE (out), 0,
G_SEEK_SET, cancellable, error))
- return FALSE;
+ goto end;
header.nfiles = nfiles;
header.size += CFI_START + nfiles * 16; /* 1st part cfile struct = 16 bytes */
header.size += sumstr;
- if (cheader_write (&header, out, error) == -1)
- return FALSE;
+ if (!cheader_write (&header, dstream, cancellable, error))
+ goto end;
- if (cfolder_write (&folder, out, error) == -1)
- return FALSE;
+ if (!cfolder_write (&folder, dstream, cancellable, error))
+ goto end;
cfile_t *prevf = NULL;
g_hash_table_iter_init (&iter, cabfolder->files);
@@ -222,12 +219,15 @@ gcab_cabinet_write (GCabCabinet *self,
file->cfile.uoffset = prevf ? prevf->uoffset + prevf->usize : 0;
prevf = &file->cfile;
- if (cfile_write (&file->cfile, out, error) == -1)
- return FALSE;
+ if (!cfile_write (&file->cfile, dstream, cancellable, error))
+ goto end;
}
- return TRUE;
+ success = TRUE;
+end:
+ g_clear_object (&dstream);
+ g_clear_object (&in);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]