[f-spot/taglib-metadata: 9/20] Implement a safe writing pattern for GIOTagLibFileAbstraction.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/taglib-metadata: 9/20] Implement a safe writing pattern for GIOTagLibFileAbstraction.
- Date: Sat, 26 Jun 2010 19:36:50 +0000 (UTC)
commit 2b03a815c529523c599fd826888482ce81bee922
Author: Ruben Vermeersch <ruben savanne be>
Date: Sun Jun 13 16:32:55 2010 +0200
Implement a safe writing pattern for GIOTagLibFileAbstraction.
src/Utils/GIOTagLibFileAbstraction.cs | 47 ++++++++++++++++++++++++++++++--
1 files changed, 44 insertions(+), 3 deletions(-)
---
diff --git a/src/Utils/GIOTagLibFileAbstraction.cs b/src/Utils/GIOTagLibFileAbstraction.cs
index 1f559a5..d66c624 100644
--- a/src/Utils/GIOTagLibFileAbstraction.cs
+++ b/src/Utils/GIOTagLibFileAbstraction.cs
@@ -5,9 +5,21 @@ using Hyena;
namespace FSpot.Utils
{
+ /// <summary>
+ /// Wraps GIO into a TagLib IFileAbstraction.
+ /// </summary>
+ /// <remarks>
+ /// Implements a safe writing pattern by first copying the file to a
+ /// temporary location. This temporary file is used for writing. When the
+ /// stream is closed, the temporary file is moved to the original
+ /// location.
+ /// </remarks>
public sealed class GIOTagLibFileAbstraction : TagLib.File.IFileAbstraction
{
private GioStream stream;
+ private SafeUri tmp_write_uri;
+
+ private const string TMP_INFIX = ".tmpwrite";
public string Name {
get {
@@ -33,8 +45,9 @@ namespace FSpot.Utils
public Stream WriteStream {
get {
if (stream == null) {
- var file = FileFactory.NewForUri (Uri);
- stream = new GioStream (file.ReplaceReadwrite (null, true, FileCreateFlags.None, null));
+ CopyToTmp ();
+ var file = FileFactory.NewForUri (tmp_write_uri);
+ stream = new GioStream (file.OpenReadwrite (null));
}
if (!stream.CanWrite) {
throw new Exception ("Stream still open in reading mode!");
@@ -43,11 +56,39 @@ namespace FSpot.Utils
}
}
+ private void CopyToTmp ()
+ {
+ tmp_write_uri = CreateTmpFile ();
+ var file = FileFactory.NewForUri (Uri);
+ var tmp_file = FileFactory.NewForUri (tmp_write_uri);
+
+ file.Copy (tmp_file, GLib.FileCopyFlags.AllMetadata | GLib.FileCopyFlags.Overwrite, null, null);
+ }
+
+ private void CommitTmp ()
+ {
+ var file = FileFactory.NewForUri (Uri);
+ var tmp_file = FileFactory.NewForUri (tmp_write_uri);
+
+ tmp_file.Copy (file, GLib.FileCopyFlags.AllMetadata | GLib.FileCopyFlags.Overwrite, null, null);
+ }
+
+ private SafeUri CreateTmpFile ()
+ {
+ var uri = Uri.GetBaseUri ().Append (Uri.GetFilenameWithoutExtension ());
+ var tmp_uri = uri.ToString () + TMP_INFIX + Uri.GetExtension ();
+ return new SafeUri (tmp_uri, true);
+ }
+
public void CloseStream (Stream stream)
{
stream.Close ();
- if (stream == this.stream)
+ if (stream == this.stream) {
+ if (stream.CanWrite) {
+ CommitTmp ();
+ }
this.stream = null;
+ }
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]