summaryrefslogtreecommitdiffstats
path: root/libmsi/libmsi-record.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2012-12-18 14:35:14 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2013-01-09 13:56:07 +0100
commit0a97c9f43718d34aacc834c60f3ced60e9ce956f (patch)
tree7a5b5975cd92862283df669f9af62005fe63baa9 /libmsi/libmsi-record.c
parent880b9016b1d751d480a282b9a8556c54701a86f4 (diff)
downloadmsitools-0a97c9f43718d34aacc834c60f3ced60e9ce956f.tar.gz
msitools-0a97c9f43718d34aacc834c60f3ced60e9ce956f.tar.xz
msitools-0a97c9f43718d34aacc834c60f3ced60e9ce956f.zip
record: add set_stream() and get_stream() using GIO
Use GInputStream for record stream manipulation
Diffstat (limited to 'libmsi/libmsi-record.c')
-rw-r--r--libmsi/libmsi-record.c123
1 files changed, 72 insertions, 51 deletions
diff --git a/libmsi/libmsi-record.c b/libmsi/libmsi-record.c
index aa77ad6..da5d8bf 100644
--- a/libmsi/libmsi-record.c
+++ b/libmsi/libmsi-record.c
@@ -577,80 +577,101 @@ libmsi_record_load_stream(LibmsiRecord *rec, unsigned field, const char *szFilen
return ret == LIBMSI_RESULT_SUCCESS;
}
-unsigned _libmsi_record_save_stream(const LibmsiRecord *rec, unsigned field, char *buf, unsigned *sz)
+/**
+ * libmsi_record_set_stream:
+ * @record: a #LibmsiRecord
+ * @field: a field identifier
+ * @input: a #GInputStream
+ * @count: the number of bytes to read from @input
+ * @cancellable: (allow-none): optional GCancellable object, %NULL to ignore
+ * @error: (allow-none): #GError to set on error, or %NULL
+ *
+ * Set the stream content from @input stream.
+ *
+ * Returns: %TRUE on success
+ **/
+gboolean
+libmsi_record_set_stream (LibmsiRecord *rec, guint field,
+ GInputStream *input, gsize count,
+ GCancellable *cancellable, GError **error)
{
- uint64_t left;
- GsfInput *stm;
-
- TRACE("%p %d %p %p\n", rec, field, buf, sz);
-
- if( !sz )
- return LIBMSI_RESULT_INVALID_PARAMETER;
-
- if( field > rec->count)
- return LIBMSI_RESULT_INVALID_PARAMETER;
-
- if ( rec->fields[field].type == LIBMSI_FIELD_TYPE_NULL )
- {
- *sz = 0;
- return LIBMSI_RESULT_INVALID_DATA;
+ g_return_val_if_fail (LIBMSI_IS_RECORD (rec), FALSE);
+ g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
+ g_return_val_if_fail (field > 0 && field <= rec->count, FALSE);
+ g_return_val_if_fail (count > 0, FALSE);
+ g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (!error || *error == NULL, FALSE);
+
+ gsize bytes_read = 0;
+ GsfInput *stm = NULL;
+ guint8 *data = g_malloc (count);
+
+ if (!g_input_stream_read_all (input, data, count, &bytes_read,
+ cancellable, error) ||
+ bytes_read != count) {
+ g_free (data);
+ return FALSE;
}
- if( rec->fields[field].type != LIBMSI_FIELD_TYPE_STREAM )
- return LIBMSI_RESULT_INVALID_DATATYPE;
+ stm = gsf_input_memory_new (data, count, TRUE);
+ if (_libmsi_record_load_stream (rec, field, stm) != LIBMSI_RESULT_SUCCESS) {
+ g_object_unref (stm);
+ return FALSE;
+ }
- stm = rec->fields[field].u.stream;
- if( !stm )
- return LIBMSI_RESULT_INVALID_PARAMETER;
+ return TRUE;
+}
- left = gsf_input_size(stm) - gsf_input_tell(stm);
+static GsfInput *
+_libmsi_record_get_stream (LibmsiRecord *rec, unsigned field, GError **error)
+{
+ GsfInput *stm;
- /* if there's no buffer pointer, calculate the length to the end */
- if( !buf )
- {
- *sz = left;
+ if (field > rec->count) {
+ g_set_error (error, LIBMSI_RESULT_ERROR, LIBMSI_RESULT_INVALID_PARAMETER, G_STRFUNC);
+ return NULL;
+ }
- return LIBMSI_RESULT_SUCCESS;
+ if (rec->fields[field].type == LIBMSI_FIELD_TYPE_NULL) {
+ g_set_error (error, LIBMSI_RESULT_ERROR, LIBMSI_RESULT_INVALID_DATA, G_STRFUNC);
+ return NULL;
}
- /* read the data */
- if (*sz > left)
- *sz = left;
+ if (rec->fields[field].type != LIBMSI_FIELD_TYPE_STREAM) {
+ g_set_error (error, LIBMSI_RESULT_ERROR, LIBMSI_RESULT_INVALID_DATATYPE, G_STRFUNC);
+ return NULL;
+ }
- if (*sz > 0 && !gsf_input_read( stm, *sz, buf ))
- {
- *sz = 0;
- return LIBMSI_RESULT_FUNCTION_FAILED;
+ stm = rec->fields[field].u.stream;
+ if (!stm) {
+ g_set_error (error, LIBMSI_RESULT_ERROR, LIBMSI_RESULT_INVALID_PARAMETER, G_STRFUNC);
+ return NULL;
}
- return LIBMSI_RESULT_SUCCESS;
+ return stm;
}
/**
- * libmsi_record_save_stream:
- * @rec: a %LibmsiRecord
+ * libmsi_record_get_stream:
+ * @record: a #LibmsiRecord
* @field: a field identifier
- * @buf: a buffer of size specified by %sz, or %NULL to return size
- * @sz: a pointer to %buf size
*
- * Read the stream data into %buf from record %field.
+ * Get the stream associated with the given record @field.
*
- * Returns: %TRUE on success.
+ * Returns: (transfer full): a new #GInputStream
**/
-gboolean
-libmsi_record_save_stream(LibmsiRecord *rec, unsigned field, char *buf, unsigned *sz)
+GInputStream *
+libmsi_record_get_stream (LibmsiRecord *rec, guint field)
{
- unsigned ret;
-
- TRACE("%d %d %p %p\n", rec, field, buf, sz);
+ GsfInput *stm;
- g_return_val_if_fail (LIBMSI_IS_RECORD (rec), FALSE);
+ g_return_val_if_fail (LIBMSI_IS_RECORD (rec), NULL);
- g_object_ref(rec);
- ret = _libmsi_record_save_stream( rec, field, buf, sz );
- g_object_unref(rec);
+ stm = _libmsi_record_get_stream (rec, field, NULL);
+ if (!stm)
+ return NULL;
- return ret == LIBMSI_RESULT_SUCCESS;
+ return G_INPUT_STREAM (libmsi_istream_new (stm));
}
unsigned _libmsi_record_set_gsf_input( LibmsiRecord *rec, unsigned field, GsfInput *stm )