[runtime] Disable some tests in full-aot mode which cannot be AOTed because of type...
[mono.git] / mcs / class / monodoc / Monodoc / storage / ZipStorage.cs
1 using System;
2 using System.IO;
3 using System.Xml;
4 using System.Linq;
5 using System.Text;
6 using System.Collections.Generic;
7
8 using ICSharpCode.SharpZipLib.Zip;
9
10 namespace Monodoc.Storage
11 {
12         public class ZipStorage : IDocStorage
13         {
14                 string zipFileName;
15                 int code;
16                 ZipOutputStream zipOutput;
17                 ZipFile zipFile;
18                 // SharpZipLib use linear search to map name to index, correct that a bit
19                 Dictionary<string, int> entries = new Dictionary<string, int> ();
20
21                 public ZipStorage (string zipFileName)
22                 {
23                         this.zipFileName = zipFileName;
24                 }
25
26                 public bool SupportRevision {
27                         get {
28                                 return false;
29                         }
30                 }
31
32                 public IDocRevisionManager RevisionManager {
33                         get {
34                                 return null;
35                         }
36                 }
37
38                 public bool SupportChange {
39                         get {
40                                 return true;
41                         }
42                 }
43
44                 public string Store (string id, string text)
45                 {
46                         EnsureOutput ();
47                         SetupEntry (zipOutput, ref id);
48                         var writer = new StreamWriter (zipOutput);
49                         writer.Write (text);
50                         writer.Flush ();
51                         
52                         return id;
53                 }
54
55                 public string Store (string id, byte[] data)
56                 {
57                         EnsureOutput ();
58                         SetupEntry (zipOutput, ref id);
59                         zipOutput.Write (data, 0, data.Length);
60                         return id;
61                 }
62
63                 public string Store (string id, Stream stream)
64                 {
65                         EnsureOutput ();
66                         SetupEntry (zipOutput, ref id);
67                         stream.CopyTo (zipOutput);
68                         return id;
69                 }
70
71                 void SetupEntry (ZipOutputStream zipOutput, ref string id)
72                 {
73                         if (string.IsNullOrEmpty (id))
74                                 id = GetNewCode ();
75
76                         ZipEntry entry = new ZipEntry (id);
77                         zipOutput.PutNextEntry (entry);
78                 }
79
80                 public Stream Retrieve (string id)
81                 {
82                         EnsureInput ();
83                         int index;
84                         ZipEntry entry;
85                         if (!entries.TryGetValue (id, out index) || (entry = zipFile[index]) == null)
86                                 entry = zipFile.GetEntry (id);
87                         if (entry != null)
88                                 return zipFile.GetInputStream (entry);
89                         else
90                                 throw new ArgumentException ("id", string.Format ("'{0}' isn't a valid id for this storage", id));
91                 }
92
93                 public IEnumerable<string> GetAvailableIds ()
94                 {
95                         EnsureInput ();
96                         return zipFile.Cast<ZipEntry> ().Select (ze => ze.Name);
97                 }
98
99                 void EnsureOutput ()
100                 {
101                         if (zipFile != null)
102                                 throw new InvalidOperationException ("This ZipStorage instance is already used in read-mode");
103                         if (zipOutput != null)
104                                 return;
105                         zipOutput = new ZipOutputStream (File.Create (zipFileName));
106                 }
107
108                 void EnsureInput ()
109                 {
110                         if (zipOutput != null)
111                                 throw new InvalidOperationException ("This ZipStorage instance is already used in write-mode");
112                         if (zipFile != null)
113                                 return;
114                         zipFile = new ZipFile (zipFileName);
115                         entries = Enumerable.Range (0, zipFile.Size).ToDictionary (i => zipFile[i].Name, i => i);
116                 }
117
118                 public void Dispose ()
119                 {
120                         if (zipOutput != null)
121                                 zipOutput.Dispose ();
122                         if (zipFile != null)
123                                 zipFile.Close ();
124                 }
125
126                 string GetNewCode ()
127                 {
128                         return String.Format ("{0}", code++);
129                 }
130         }
131 }