[ostree] repo: Add API to load any object as a stream



commit 11bdbe1fb860b1bd4693343adb4d53a223d3c8d6
Author: Colin Walters <walters verbum org>
Date:   Wed Aug 14 18:18:10 2013 -0400

    repo: Add API to load any object as a stream
    
    We have APIs to load metadata as variants, and files as parsed
    content/info/xattrs, but for some cases such as static deltas, all we
    want is to operate on all objects in their canonical representation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706031

 src/libgsystem                     |    2 +-
 src/libostree/ostree-repo.c        |  163 +++++++++++++++++++++++++-----------
 src/libostree/ostree-repo.h        |    8 ++
 src/ostree/ot-builtin-pull-local.c |   14 +---
 4 files changed, 126 insertions(+), 61 deletions(-)
---
diff --git a/src/libgsystem b/src/libgsystem
index 4150e63..4501b42 160000
--- a/src/libgsystem
+++ b/src/libgsystem
@@ -1 +1 @@
-Subproject commit 4150e6336881faec1a31f557567ca89c283b38c9
+Subproject commit 4501b425953c3849112206c4a3f6f27cd3264936
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index d585ad8..f696440 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -2041,6 +2041,73 @@ list_loose_objects (OstreeRepo                     *self,
   return ret;
 }
 
+static gboolean
+load_metadata_internal (OstreeRepo       *self,
+                        OstreeObjectType  objtype,
+                        const char       *sha256, 
+                        gboolean          error_if_not_found,
+                        GVariant        **out_variant,
+                        GInputStream    **out_stream,
+                        guint64          *out_size,
+                        GCancellable     *cancellable,
+                        GError          **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_object GFile *object_path = NULL;
+  gs_unref_object GInputStream *ret_stream = NULL;
+  gs_unref_variant GVariant *ret_variant = NULL;
+
+  g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
+
+  if (!repo_find_object (self, objtype, sha256, &object_path,
+                         cancellable, error))
+    goto out;
+
+  if (object_path != NULL)
+    {
+      if (out_variant)
+        {
+          if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype),
+                                    TRUE, &ret_variant, error))
+            goto out;
+          if (out_size)
+            *out_size = g_variant_get_size (ret_variant);
+        }
+      else if (out_stream)
+        {
+          ret_stream = gs_file_read_noatime (object_path, cancellable, error);
+          if (!ret_stream)
+            goto out;
+          if (out_size)
+            {
+              struct stat stbuf;
+              
+              if (!gs_stream_fstat ((GFileDescriptorBased*)ret_stream, &stbuf, cancellable, error))
+                goto out;
+              *out_size = stbuf.st_size;
+            }
+        }
+    }
+  else if (self->parent_repo)
+    {
+      if (!ostree_repo_load_variant (self->parent_repo, objtype, sha256, &ret_variant, error))
+        goto out;
+    }
+  else if (error_if_not_found)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "No such metadata object %s.%s",
+                   sha256, ostree_object_type_to_string (objtype));
+      goto out;
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_variant, &ret_variant);
+  ot_transfer_out_value (out_stream, &ret_stream);
+ out:
+  return ret;
+}
+
 gboolean
 ostree_repo_load_file (OstreeRepo         *self,
                        const char         *checksum,
@@ -2164,6 +2231,49 @@ ostree_repo_load_file (OstreeRepo         *self,
   return ret;
 }
 
+gboolean
+ostree_repo_load_object_stream (OstreeRepo         *self,
+                                OstreeObjectType    objtype,
+                                const char         *checksum,
+                                GInputStream      **out_input,
+                                guint64            *out_size,
+                                GCancellable       *cancellable,
+                                GError            **error)
+{
+  gboolean ret = FALSE;
+  guint64 size;
+  gs_unref_object GInputStream *ret_input = NULL;
+      
+  if (OSTREE_OBJECT_TYPE_IS_META (objtype))
+    {
+      if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL,
+                                   &ret_input, &size,
+                                   cancellable, error))
+        goto out;
+    }
+  else
+    {
+      gs_unref_object GInputStream *input = NULL;
+      gs_unref_object GFileInfo *finfo = NULL;
+      gs_unref_variant GVariant *xattrs = NULL;
+
+      if (!ostree_repo_load_file (self, checksum, &input, &finfo, &xattrs,
+                                  cancellable, error))
+        goto out;
+
+      if (!ostree_raw_file_to_content_stream (input, finfo, xattrs,
+                                              &ret_input, &size,
+                                              cancellable, error))
+        goto out;
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_input, &ret_input);
+  *out_size = size;
+ out:
+  return ret;
+}
+
 static gboolean      
 repo_find_object (OstreeRepo           *self,
                   OstreeObjectType      objtype,
@@ -2305,50 +2415,6 @@ ostree_repo_load_variant_c (OstreeRepo          *self,
   return ret;
 }
 
-static gboolean
-load_variant_internal (OstreeRepo       *self,
-                       OstreeObjectType  objtype,
-                       const char       *sha256, 
-                       gboolean          error_if_not_found,
-                       GVariant        **out_variant,
-                       GError          **error)
-{
-  gboolean ret = FALSE;
-  GCancellable *cancellable = NULL;
-  gs_unref_object GFile *object_path = NULL;
-  gs_unref_variant GVariant *ret_variant = NULL;
-
-  g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
-
-  if (!repo_find_object (self, objtype, sha256, &object_path,
-                         cancellable, error))
-    goto out;
-
-  if (object_path != NULL)
-    {
-      if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype),
-                                TRUE, &ret_variant, error))
-        goto out;
-    }
-  else if (self->parent_repo)
-    {
-      if (!ostree_repo_load_variant (self->parent_repo, objtype, sha256, &ret_variant, error))
-        goto out;
-    }
-  else if (error_if_not_found)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "No such metadata object %s.%s",
-                   sha256, ostree_object_type_to_string (objtype));
-      goto out;
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value (out_variant, &ret_variant);
- out:
-  return ret;
-}
-
 /**
  * ostree_repo_load_variant_if_exists:
  * 
@@ -2363,8 +2429,8 @@ ostree_repo_load_variant_if_exists (OstreeRepo       *self,
                                     GVariant        **out_variant,
                                     GError          **error)
 {
-  return load_variant_internal (self, objtype, sha256, FALSE,
-                                out_variant, error);
+  return load_metadata_internal (self, objtype, sha256, FALSE,
+                                 out_variant, NULL, NULL, NULL, error);
 }
 
 /**
@@ -2385,11 +2451,10 @@ ostree_repo_load_variant (OstreeRepo       *self,
                           GVariant        **out_variant,
                           GError          **error)
 {
-  return load_variant_internal (self, objtype, sha256, TRUE,
-                                out_variant, error);
+  return load_metadata_internal (self, objtype, sha256, TRUE,
+                                 out_variant, NULL, NULL, NULL, error);
 }
 
-
 /**
  * ostree_repo_list_objects:
  * @self:
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index e67a6f3..89be951 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -198,6 +198,14 @@ gboolean ostree_repo_load_file (OstreeRepo         *self,
                                 GCancellable       *cancellable,
                                 GError            **error);
 
+gboolean ostree_repo_load_object_stream (OstreeRepo         *self,
+                                         OstreeObjectType    objtype,
+                                         const char         *checksum,
+                                         GInputStream      **out_input,
+                                         guint64            *out_size,
+                                         GCancellable       *cancellable,
+                                         GError            **error);
+
 gboolean      ostree_repo_query_object_storage_size (OstreeRepo           *self,
                                                      OstreeObjectType      objtype,
                                                      const char           *sha256, 
diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c
index cd63450..d98a3a7 100644
--- a/src/ostree/ot-builtin-pull-local.c
+++ b/src/ostree/ot-builtin-pull-local.c
@@ -68,18 +68,10 @@ import_one_object (OtLocalCloneData *data,
     {
       guint64 length;
       gs_unref_object GInputStream *file_object = NULL;
-      gs_unref_object GInputStream *input = NULL;
-      gs_unref_object GFileInfo *file_info = NULL;
-      gs_unref_variant GVariant *xattrs = NULL;
 
-      if (!ostree_repo_load_file (data->src_repo, checksum,
-                                  &input, &file_info, &xattrs,
-                                  cancellable, error))
-        goto out;
-
-      if (!ostree_raw_file_to_content_stream (input, file_info, xattrs,
-                                              &file_object, &length,
-                                              cancellable, error))
+      if (!ostree_repo_load_object_stream (data->src_repo, objtype, checksum,
+                                           &file_object, &length,
+                                           cancellable, error))
         goto out;
 
       if (!ostree_repo_stage_content_trusted (data->dest_repo, checksum,


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