6 using System.Collections.Generic;
8 using ICSharpCode.SharpZipLib.Zip;
10 namespace Monodoc.Storage
12 public class ZipStorage : IDocStorage
16 ZipOutputStream zipOutput;
18 // SharpZipLib use linear search to map name to index, correct that a bit
19 Dictionary<string, int> entries = new Dictionary<string, int> ();
21 public ZipStorage (string zipFileName)
23 this.zipFileName = zipFileName;
26 public bool SupportRevision {
32 public IDocRevisionManager RevisionManager {
38 public bool SupportChange {
44 public string Store (string id, string text)
47 SetupEntry (zipOutput, ref id);
48 var writer = new StreamWriter (zipOutput);
55 public string Store (string id, byte[] data)
58 SetupEntry (zipOutput, ref id);
59 zipOutput.Write (data, 0, data.Length);
63 public string Store (string id, Stream stream)
66 SetupEntry (zipOutput, ref id);
67 stream.CopyTo (zipOutput);
71 void SetupEntry (ZipOutputStream zipOutput, ref string id)
73 if (string.IsNullOrEmpty (id))
76 ZipEntry entry = new ZipEntry (id);
77 zipOutput.PutNextEntry (entry);
80 public Stream Retrieve (string id)
85 if (!entries.TryGetValue (id, out index) || (entry = zipFile[index]) == null)
86 entry = zipFile.GetEntry (id);
88 return zipFile.GetInputStream (entry);
90 throw new ArgumentException ("id", string.Format ("'{0}' isn't a valid id for this storage", id));
93 public IEnumerable<string> GetAvailableIds ()
96 return zipFile.Cast<ZipEntry> ().Select (ze => ze.Name);
102 throw new InvalidOperationException ("This ZipStorage instance is already used in read-mode");
103 if (zipOutput != null)
105 zipOutput = new ZipOutputStream (File.Create (zipFileName));
110 if (zipOutput != null)
111 throw new InvalidOperationException ("This ZipStorage instance is already used in write-mode");
114 zipFile = new ZipFile (zipFileName);
115 entries = Enumerable.Range (0, zipFile.Size).ToDictionary (i => zipFile[i].Name, i => i);
118 public void Dispose ()
120 if (zipOutput != null)
121 zipOutput.Dispose ();
128 return String.Format ("{0}", code++);