lib: Create an internal static delta parsing/opening function

We had code to deal with opening/checksumming/decompressing static
deltas in a few places.  I'd like to teach `ostree static-delta show`
how to display more information, and this will allow it to just use
`_ostree_static_delta_part_open()` too.
This commit is contained in:
Colin Walters committed 2016-02-08 14:46:13 +01:00
1 parent 8702ec7b3e
commit 56fc249d08
4 files changed
+284 -257

No files matched your search

@@ -150,42 +150,12 @@ open_output_target (StaticDeltaExecutionState *state,
}
gboolean
_ostree_static_delta_part_validate (OstreeRepo *repo,
GInputStream *in,
guint part_offset,
const char *expected_checksum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
g_autofree guchar *actual_checksum_bytes = NULL;
g_autofree char *actual_checksum = NULL;
if (!ot_gio_checksum_stream (in, &actual_checksum_bytes,
cancellable, error))
goto out;
actual_checksum = ostree_checksum_from_bytes (actual_checksum_bytes);
if (strcmp (actual_checksum, expected_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Checksum mismatch in static delta part %u; expected=%s actual=%s",
part_offset, expected_checksum, actual_checksum);
goto out;
}
ret = TRUE;
out:
return ret;
}
gboolean
_ostree_static_delta_part_execute_raw (OstreeRepo *repo,
GVariant *objects,
GVariant *part,
gboolean trusted,
GCancellable *cancellable,
GError **error)
_ostree_static_delta_part_execute (OstreeRepo *repo,
GVariant *objects,
GVariant *part,
gboolean trusted,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
guint8 *checksums_data;
@@ -280,99 +250,10 @@ _ostree_static_delta_part_execute_raw (OstreeRepo *repo,
return ret;
}
static gboolean
decompress_all (GConverter *converter,
GBytes *data,
GBytes **out_uncompressed,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
g_autoptr(GMemoryInputStream) memin = (GMemoryInputStream*)g_memory_input_stream_new_from_bytes (data);
g_autoptr(GMemoryOutputStream) memout = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
g_autoptr(GInputStream) convin = g_converter_input_stream_new ((GInputStream*)memin, converter);
{
gssize n_bytes_written = g_output_stream_splice ((GOutputStream*)memout, convin,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
cancellable, error);
if (n_bytes_written < 0)
goto out;
}
ret = TRUE;
*out_uncompressed = g_memory_output_stream_steal_as_bytes (memout);
out:
return ret;
}
gboolean
_ostree_static_delta_part_execute (OstreeRepo *repo,
GVariant *header,
GBytes *part_bytes,
gboolean trusted,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gsize partlen;
const guint8*partdata;
g_autoptr(GBytes) part_payload_bytes = NULL;
g_autoptr(GBytes) payload_data = NULL;
g_autoptr(GVariant) payload = NULL;
guint8 comptype;
partdata = g_bytes_get_data (part_bytes, &partlen);
if (partlen < 1)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Corrupted 0 length delta part");
goto out;
}
/* First byte is compression type */
comptype = partdata[0];
/* Then the rest may be compressed or uncompressed */
part_payload_bytes = g_bytes_new_from_bytes (part_bytes, 1, partlen - 1);
switch (comptype)
{
case 0:
/* No compression */
payload_data = g_bytes_ref (part_payload_bytes);
break;
case 'x':
{
g_autoptr(GConverter) decomp =
(GConverter*) _ostree_lzma_decompressor_new ();
if (!decompress_all (decomp, part_payload_bytes, &payload_data,
cancellable, error))
goto out;
}
break;
default:
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid compression type '%u'", comptype);
goto out;
}
payload = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
payload_data, FALSE);
if (!_ostree_static_delta_part_execute_raw (repo, header, payload, trusted,
cancellable, error))
goto out;
ret = TRUE;
out:
return ret;
}
typedef struct {
OstreeRepo *repo;
GVariant *header;
GBytes *partdata;
GVariant *part;
GCancellable *cancellable;
GSimpleAsyncResult *result;
gboolean trusted;
@@ -385,7 +266,7 @@ static_delta_part_execute_async_data_free (gpointer user_data)
g_clear_object (&data->repo);
g_variant_unref (data->header);
g_bytes_unref (data->partdata);
g_variant_unref (data->part);
g_clear_object (&data->cancellable);
g_free (data);
}
@@ -401,7 +282,7 @@ static_delta_part_execute_thread (GSimpleAsyncResult *res,
data = g_simple_async_result_get_op_res_gpointer (res);
if (!_ostree_static_delta_part_execute (data->repo,
data->header,
data->partdata,
data->part,
data->trusted,
cancellable, &error))
g_simple_async_result_take_error (res, error);
@@ -410,7 +291,7 @@ static_delta_part_execute_thread (GSimpleAsyncResult *res,
void
_ostree_static_delta_part_execute_async (OstreeRepo *repo,
GVariant *header,
GBytes *partdata,
GVariant *part,
gboolean trusted,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -421,7 +302,7 @@ _ostree_static_delta_part_execute_async (OstreeRepo *repo,
asyncdata = g_new0 (StaticDeltaPartExecuteAsyncData, 1);
asyncdata->repo = g_object_ref (repo);
asyncdata->header = g_variant_ref (header);
asyncdata->partdata = g_bytes_ref (partdata);
asyncdata->part = g_variant_ref (part);
asyncdata->trusted = trusted;
asyncdata->cancellable = cancellable ? g_object_ref (cancellable) : NULL;