Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2471 - 1

2
namespace GMap.NET.Internals
3
{
4
   using System;
5
   using System.Diagnostics;
6
   using System.IO;
7
   using System.Text;
8
   using GMap.NET.CacheProviders;
9
   using System.Security.Cryptography;
10
 
11
   internal class CacheLocator
12
   {
13
      private static string location;
14
      public static string Location
15
      {
16
         get
17
         {
18
            if(string.IsNullOrEmpty(location))
19
            {
20
               Reset();
21
            }
22
 
23
            return location;
24
         }
25
         set
26
         {
27
            if(string.IsNullOrEmpty(value)) // setting to null resets to default
28
            {
29
               Reset();
30
            }
31
            else
32
            {
33
               location = value;
34
            }
35
 
36
            if(Delay)
37
            {
38
               Cache.Instance.CacheLocation = location;
39
            }
40
         }
41
      }
42
 
43
      static void Reset()
44
      {    
45
         string appDataLocation = GetApplicationDataFolderPath();
46
 
47
#if !PocketPC
48
         // http://greatmaps.codeplex.com/discussions/403151
49
         // by default Network Service don't have disk write access
50
         if(string.IsNullOrEmpty(appDataLocation))
51
         {
52
            GMaps.Instance.Mode = AccessMode.ServerOnly;
53
            GMaps.Instance.UseDirectionsCache = false;
54
            GMaps.Instance.UseGeocoderCache = false;
55
            GMaps.Instance.UsePlacemarkCache = false;
56
            GMaps.Instance.UseRouteCache = false;
57
            GMaps.Instance.UseUrlCache = false;
58
         }
59
         else
60
#endif
61
         {
62
            Location = appDataLocation;
63
         }
64
      }
65
 
66
      public static string GetApplicationDataFolderPath()
67
      {
68
#if !PocketPC
69
         bool isSystem = false;
70
         try
71
         {
72
            using(var identity = System.Security.Principal.WindowsIdentity.GetCurrent())
73
            {
74
               if(identity != null)
75
               {
76
                  isSystem = identity.IsSystem;
77
               }
78
            }
79
         }
80
         catch(Exception ex)
81
         {
82
            Trace.WriteLine("SQLitePureImageCache, WindowsIdentity.GetCurrent: " + ex);
83
         }
84
 
85
         string path = string.Empty;
86
 
87
         // https://greatmaps.codeplex.com/workitem/16112
88
         if(isSystem)
89
         {
90
            path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData);
91
         }
92
         else
93
         {
94
            path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
95
         }
96
#else
97
         path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
98
#endif
99
 
100
         if(!string.IsNullOrEmpty(path))
101
         {
102
            path += Path.DirectorySeparatorChar + "GMap.NET" + Path.DirectorySeparatorChar;
103
         }
104
 
105
         return path;
106
      }
107
 
108
      public static bool Delay = false;
109
   }
110
 
111
   /// <summary>
112
   /// cache system for tiles, geocoding, etc...
113
   /// </summary>
114
   internal class Cache : Singleton<Cache>
115
   {
116
      /// <summary>
117
      /// abstract image cache
118
      /// </summary>
119
      public PureImageCache ImageCache;
120
 
121
      /// <summary>
122
      /// second level abstract image cache
123
      /// </summary>
124
      public PureImageCache ImageCacheSecond;
125
 
126
      string cache;
127
 
128
      /// <summary>
129
      /// local cache location
130
      /// </summary>
131
      public string CacheLocation
132
      {
133
         get
134
         {
135
            return cache;
136
         }
137
         set
138
         {
139
            cache = value;
140
#if SQLite
141
            if(ImageCache is SQLitePureImageCache)
142
            {
143
               (ImageCache as SQLitePureImageCache).CacheLocation = value;
144
            }
145
#else
146
            if(ImageCache is MsSQLCePureImageCache)
147
            {
148
               (ImageCache as MsSQLCePureImageCache).CacheLocation = value;
149
            }
150
#endif
151
            CacheLocator.Delay = true;
152
         }
153
      }
154
 
155
      public Cache()
156
      {
157
         #region singleton check
158
         if(Instance != null)
159
         {
160
            throw (new System.Exception("You have tried to create a new singleton class where you should have instanced it. Replace your \"new class()\" with \"class.Instance\""));
161
         }
162
         #endregion
163
 
164
#if SQLite
165
         ImageCache = new SQLitePureImageCache();
166
#else
167
         // you can use $ms stuff if you like too ;}
168
         ImageCache = new MsSQLCePureImageCache();
169
#endif
170
 
171
#if PocketPC
172
         // use sd card if exist for cache
173
         string sd = Native.GetRemovableStorageDirectory();
174
         if(!string.IsNullOrEmpty(sd))
175
         {
176
            CacheLocation = sd + Path.DirectorySeparatorChar +  "GMap.NET" + Path.DirectorySeparatorChar;
177
         }
178
         else
179
#endif
180
         {
181
#if PocketPC
182
            CacheLocation = CacheLocator.Location;
183
#else
184
            string newCache = CacheLocator.Location;
185
 
186
            string oldCache = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + "GMap.NET" + Path.DirectorySeparatorChar;
187
 
188
            // move database to non-roaming user directory
189
            if(Directory.Exists(oldCache))
190
            {
191
               try
192
               {
193
                  if(Directory.Exists(newCache))
194
                  {
195
                     Directory.Delete(oldCache, true);
196
                  }
197
                  else
198
                  {
199
                     Directory.Move(oldCache, newCache);
200
                  }
201
                  CacheLocation = newCache;
202
               }
203
               catch(Exception ex)
204
               {
205
                  CacheLocation = oldCache;
206
                  Trace.WriteLine("SQLitePureImageCache, moving data: " + ex.ToString());
207
               }
208
            }
209
            else
210
            {
211
               CacheLocation = newCache;
212
            }
213
#endif
214
         }
215
      }
216
 
217
      #region -- etc cache --
218
 
219
      static readonly SHA1CryptoServiceProvider HashProvider = new SHA1CryptoServiceProvider();
220
 
221
      void ConvertToHash(ref string s)
222
      {
223
          s = BitConverter.ToString(HashProvider.ComputeHash(Encoding.Unicode.GetBytes(s)));
224
      }
225
 
226
      public void SaveContent(string url, CacheType type, string content)
227
      {
228
         try
229
         {
230
            ConvertToHash(ref url);
231
 
232
            string dir = Path.Combine(cache, type.ToString()) + Path.DirectorySeparatorChar;
233
 
234
            // precrete dir
235
            if(!Directory.Exists(dir))
236
            {
237
               Directory.CreateDirectory(dir);
238
            }
239
 
240
            string file = dir + url + ".txt";
241
 
242
            using(StreamWriter writer = new StreamWriter(file, false, Encoding.UTF8))
243
            {
244
               writer.Write(content);
245
            }
246
         }
247
         catch(Exception ex)
248
         {
249
            Debug.WriteLine("SaveContent: " + ex);
250
         }
251
      }
252
 
253
      public string GetContent(string url, CacheType type, TimeSpan stayInCache)
254
      {
255
         string ret = null;
256
 
257
         try
258
         {
259
            ConvertToHash(ref url);
260
 
261
            string dir = Path.Combine(cache, type.ToString()) + Path.DirectorySeparatorChar;
262
            string file = dir + url + ".txt";
263
 
264
            if(File.Exists(file))
265
            {
266
               var writeTime = File.GetLastWriteTime(file);
267
               if (DateTime.Now - writeTime < stayInCache)
268
               {
269
                   using (StreamReader r = new StreamReader(file, Encoding.UTF8))
270
                   {
271
                       ret = r.ReadToEnd();
272
                   }
273
               }
274
               else
275
               {
276
                   File.Delete(file);
277
               }
278
            }
279
         }
280
         catch(Exception ex)
281
         {
282
            ret = null;
283
            Debug.WriteLine("GetContent: " + ex);
284
         }
285
 
286
         return ret;
287
      }
288
 
289
      public string GetContent(string url, CacheType type)
290
      {
291
         return GetContent(url, type, TimeSpan.FromDays(88));
292
      }
293
 
294
      #endregion
295
   }
296
 
297
   internal enum CacheType
298
   {
299
      GeocoderCache,
300
      PlacemarkCache,
301
      RouteCache,
302
      UrlCache,
303
      DirectionsCache,
304
   }
305
}