[ostree] core: Extract stage_and_checksum() internal API



commit 556662b24c216e1fc8771048521023e8b3945106
Author: Colin Walters <walters verbum org>
Date:   Wed Nov 30 21:15:46 2011 -0500

    core: Extract stage_and_checksum() internal API
    
    This will be used for staging both metadata and data consistently
    before actually importing it.

 src/libostree/ostree-core.c  |   52 +++-----------------
 src/libostree/ostree-repo.c  |  112 +++++++++++++++++++++++++++++------------
 src/libotutil/ot-gio-utils.c |   46 +++++++++++++++++
 src/libotutil/ot-gio-utils.h |    7 +++
 4 files changed, 139 insertions(+), 78 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 147d0f3..49b3d43 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -704,41 +704,6 @@ ostree_pack_object (GOutputStream     *output,
 }
 
 static gboolean
-splice_and_checksum (GOutputStream  *out,
-                     GInputStream   *in,
-                     GChecksum      *checksum,
-                     GCancellable   *cancellable,
-                     GError        **error)
-{
-  gboolean ret = FALSE;
-  
-  if (checksum != NULL)
-    {
-      gsize bytes_read, bytes_written;
-      char buf[4096];
-      do
-        {
-          if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
-            goto out;
-          if (checksum)
-            g_checksum_update (checksum, (guint8*)buf, bytes_read);
-          if (!g_output_stream_write_all (out, buf, bytes_read, &bytes_written, cancellable, error))
-            goto out;
-        }
-      while (bytes_read > 0);
-    }
-  else
-    {
-      if (g_output_stream_splice (out, in, 0, cancellable, error) < 0)
-        goto out;
-    }
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-static gboolean
 unpack_meta (GFile        *file,
              GFile        *dest_file,    
              GChecksum   **out_checksum,
@@ -749,9 +714,6 @@ unpack_meta (GFile        *file,
   GChecksum *ret_checksum = NULL;
   GFileOutputStream *out = NULL;
 
-  if (out_checksum)
-    ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
-
   in = g_file_read (file, NULL, error);
   if (!in)
     goto out;
@@ -760,7 +722,8 @@ unpack_meta (GFile        *file,
   if (!out)
     goto out;
 
-  if (!splice_and_checksum ((GOutputStream*)out, (GInputStream*)in, ret_checksum, NULL, error))
+  if (!ot_gio_splice_and_checksum ((GOutputStream*)out, (GInputStream*)in,
+                                   out_checksum ? &ret_checksum : NULL, NULL, error))
     goto out;
 
   if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
@@ -768,8 +731,10 @@ unpack_meta (GFile        *file,
 
   ret = TRUE;
   if (out_checksum)
-    *out_checksum = ret_checksum;
-  ret_checksum = NULL;
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
  out:
   ot_clear_checksum (&ret_checksum);
   g_clear_object (&in);
@@ -869,16 +834,13 @@ unpack_file (GFile        *file,
   mode = GUINT32_FROM_BE (mode);
   content_len = GUINT64_FROM_BE (content_len);
 
-  if (out_checksum)
-    ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
-
   if (S_ISREG (mode))
     {
       out = g_file_replace (dest_file, NULL, FALSE, 0, NULL, error);
       if (!out)
         goto out;
 
-      if (!splice_and_checksum ((GOutputStream*)out, in, ret_checksum, NULL, error))
+      if (!ot_gio_splice_and_checksum ((GOutputStream*)out, in, out_checksum ? &ret_checksum : NULL, NULL, error))
         goto out;
 
       if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 729f9d4..f58eec4 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -563,65 +563,111 @@ ostree_repo_is_archive (OstreeRepo  *self)
 }
 
 static gboolean
-write_gvariant_to_tmp (OstreeRepo  *self,
-                       OstreeSerializedVariantType type,
-                       GVariant    *variant,
-                       GFile        **out_tmpname,
-                       GChecksum    **out_checksum,
-                       GError       **error)
+stage_and_checksum (OstreeRepo       *self,
+                    OstreeObjectType  objtype,
+                    GInputStream     *input,
+                    GFile           **out_tmpname,
+                    GChecksum       **out_checksum,
+                    GCancellable     *cancellable,
+                    GError          **error)
 {
-  OstreeRepoPrivate *priv = GET_PRIVATE (self);
-  GVariant *serialized = NULL;
   gboolean ret = FALSE;
-  gsize bytes_written;
+  const char *prefix = NULL;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GFile *tmp_f = NULL;
   GOutputStream *stream = NULL;
-  GChecksum *checksum = NULL;
   GFile *ret_tmpname = NULL;
+  GChecksum *ret_checksum = NULL;
+  
+  switch (objtype)
+    {
+    case OSTREE_OBJECT_TYPE_FILE:
+      prefix = "file-tmp-";
+      break;
+    case OSTREE_OBJECT_TYPE_META:
+      prefix = "meta-tmp-";
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
 
-  serialized = ostree_wrap_metadata_variant (type, variant);
-
-  if (!ot_gfile_create_tmp (priv->tmp_dir, "variant-tmp-", NULL, 0666,
-                            &tmp_f, &stream, NULL, error))
+  if (!ot_gfile_create_tmp (priv->tmp_dir, prefix, NULL, 0666,
+                            &tmp_f, &stream, cancellable, error))
     goto out;
 
-  checksum = g_checksum_new (G_CHECKSUM_SHA256);
-
-  if (!g_output_stream_write_all ((GOutputStream*)stream,
-                                  g_variant_get_data (serialized),
-                                  g_variant_get_size (serialized),
-                                  &bytes_written,
-                                  NULL,
-                                  error))
+  if (!ot_gio_splice_and_checksum (stream, input, &ret_checksum, cancellable, error))
     goto out;
 
-  g_checksum_update (checksum, (guint8*)g_variant_get_data (serialized), g_variant_get_size (serialized));
-
-  if (!g_output_stream_close ((GOutputStream*)stream,
-                              NULL, error))
+  if (!g_output_stream_close ((GOutputStream*)stream, NULL, error))
     goto out;
 
-  ret_tmpname = g_file_get_child (priv->tmp_dir, g_checksum_get_string (checksum));
+  ret_tmpname = g_file_get_child (priv->tmp_dir, g_checksum_get_string (ret_checksum));
   if (rename (ot_gfile_get_path_cached (tmp_f), ot_gfile_get_path_cached (ret_tmpname)) < 0)
     {
       ot_util_set_error_from_errno (error, errno);
       goto out;
     }
+  /* Clear it here, since we know the file is now gone */ 
   g_clear_object (&tmp_f);
 
   ret = TRUE;
-  *out_tmpname = ret_tmpname;
-  ret_tmpname = NULL;
-  *out_checksum = checksum;
-  checksum = NULL;
+  if (out_tmpname)
+    {
+      *out_tmpname = ret_tmpname;
+      ret_tmpname = NULL;
+    }
+  if (out_checksum)
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
  out:
   if (tmp_f)
     (void) g_file_delete (tmp_f, NULL, NULL);
   g_clear_object (&tmp_f);
   g_clear_object (&stream);
   g_clear_object (&ret_tmpname);
-  ot_clear_checksum (&checksum);
-  ot_clear_gvariant (&serialized);
+  ot_clear_checksum (&ret_checksum);
+  return ret;
+}
+
+static gboolean
+write_gvariant_to_tmp (OstreeRepo  *self,
+                       OstreeSerializedVariantType type,
+                       GVariant    *variant,
+                       GFile        **out_tmpname,
+                       GChecksum    **out_checksum,
+                       GError       **error)
+{
+  gboolean ret = FALSE;
+  GVariant *serialized = NULL;
+  GInputStream *mem = NULL;
+  GChecksum *ret_checksum = NULL;
+  GFile *ret_tmpname = NULL;
+
+  serialized = ostree_wrap_metadata_variant (type, variant);
+  mem = g_memory_input_stream_new_from_data (g_variant_get_data (serialized),
+                                             g_variant_get_size (serialized),
+                                             NULL);
+  if (!stage_and_checksum (self, OSTREE_OBJECT_TYPE_META,
+                           mem, &ret_tmpname, &ret_checksum, NULL, error))
+    goto out;
+  
+  ret = TRUE;
+  if (out_tmpname)
+    {
+      *out_tmpname = ret_tmpname;
+      ret_tmpname = NULL;
+    }
+  if (out_checksum)
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
+ out:
+  g_clear_object (&ret_tmpname);
+  ot_clear_checksum (&ret_checksum);
   return ret;
 }
 
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index 0c4e001..945bd41 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -139,6 +139,52 @@ ot_gfile_get_basename_cached (GFile *file)
 }
 
 gboolean
+ot_gio_splice_and_checksum (GOutputStream  *out,
+                            GInputStream   *in,
+                            GChecksum     **out_checksum,
+                            GCancellable   *cancellable,
+                            GError        **error)
+{
+  gboolean ret = FALSE;
+  GChecksum *ret_checksum = NULL;
+
+  if (out_checksum)
+    ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
+  
+  if (ret_checksum != NULL)
+    {
+      gsize bytes_read, bytes_written;
+      char buf[4096];
+      do
+        {
+          if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
+            goto out;
+          if (ret_checksum)
+            g_checksum_update (ret_checksum, (guint8*)buf, bytes_read);
+          if (!g_output_stream_write_all (out, buf, bytes_read, &bytes_written, cancellable, error))
+            goto out;
+        }
+      while (bytes_read > 0);
+    }
+  else
+    {
+      if (g_output_stream_splice (out, in, 0, cancellable, error) < 0)
+        goto out;
+    }
+
+  ret = TRUE;
+  if (out_checksum)
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
+ out:
+  ot_clear_checksum (&ret_checksum);
+  return ret;
+}
+
+
+gboolean
 ot_gfile_create_tmp (GFile       *dir,
                      const char  *prefix,
                      const char  *suffix,
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 26da9ad..ffdb028 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -43,6 +43,13 @@ gboolean ot_gfile_load_contents_utf8 (GFile         *file,
                                       GCancellable  *cancellable,
                                       GError       **error);
 
+gboolean ot_gio_splice_and_checksum (GOutputStream  *out,
+                                     GInputStream   *in,
+                                     GChecksum     **out_checksum,
+                                     GCancellable   *cancellable,
+                                     GError        **error);
+
+
 gboolean ot_gfile_create_tmp (GFile       *dir,
                               const char  *prefix,
                               const char  *suffix,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]