2006-04-25 Hendrik Brandt <heb@gnome-de.org>
[beagle.git] / bludgeon / TarFileObject.cs
blob2901e0133b9714afe5bd0a33e229f3973d49db67
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
6 using ICSharpCode.SharpZipLib;
7 using ICSharpCode.SharpZipLib.Tar;
9 using Beagle.Util;
10 using Beagle;
12 namespace Bludgeon {
14 // FIXME: When we untar (using the command-line 'tar') one of the
15 // files created by this class, it always complains about 'A lone zero
16 // block at xxx'. Are we doing something wrong, or is SharpZipLib the
17 // culprit?
19 public class TarFileObject : FileObject {
21 public TarFileObject (DirectoryObject tar_root)
23 AllowChildren ();
25 ArrayList to_be_tarred;
26 to_be_tarred = new ArrayList (tar_root.Children);
28 foreach (FileSystemObject fso in to_be_tarred) {
29 tar_root.RemoveChild (fso, null);
30 this.AddChild (fso, null);
34 override protected string GetChildUri (FileSystemObject children)
36 // FIXME: What is the uri scheme for tar files?
37 return this.Uri + "#" + children.Name;
40 override public string MimeType {
41 get { return "application/x-tar"; }
44 override public string Extension {
45 get { return ".tar"; }
48 private void WriteObjectToTar (TarOutputStream tar_out,
49 FileSystemObject fso,
50 EventTracker tracker)
52 MemoryStream memory = null;
54 TarHeader header;
55 header = new TarHeader ();
57 StringBuilder name_builder;
58 name_builder = new StringBuilder (fso.FullName);
59 name_builder.Remove (0, this.FullName.Length+1);
60 header.name = name_builder;
62 header.modTime = fso.Timestamp;
63 if (fso is DirectoryObject) {
64 header.mode = 511; // 0777
65 header.typeFlag = TarHeader.LF_DIR;
66 header.size = 0;
67 } else {
68 header.mode = 438; // 0666
69 header.typeFlag = TarHeader.LF_NORMAL;
70 memory = new MemoryStream ();
71 ((FileObject) fso).AddToStream (memory, tracker);
72 header.size = memory.Length;
75 TarEntry entry;
76 entry = new TarEntry (header);
78 tar_out.PutNextEntry (entry);
79 if (memory != null) {
80 tar_out.Write (memory.ToArray (), 0, (int) memory.Length);
81 memory.Close ();
83 tar_out.CloseEntry ();
85 // If this is a directory, write out the children
86 if (fso is DirectoryObject)
87 foreach (FileSystemObject child in fso.Children)
88 WriteObjectToTar (tar_out, child, tracker);
91 override public void AddToStream (Stream stream, EventTracker tracker)
93 if (tracker != null)
94 tracker.ExpectingAdded (this.Uri);
96 UnclosableStream unclosable;
97 unclosable = new UnclosableStream (stream);
99 TarOutputStream tar_out;
100 tar_out = new TarOutputStream (unclosable);
101 foreach (FileSystemObject fso in Children)
102 WriteObjectToTar (tar_out, fso, tracker);
104 // This calls close on the underlying stream,
105 // which is why we wrapped the stream in an
106 // UnclosableStream.
107 tar_out.Close ();
110 override protected bool MatchesQueryPart (QueryPart part)
112 // The only thing that could match is the name, and we check
113 // for that already in FileSystemObject.MatchesQuery.
114 return false;