0,0 → 1,305 |
|
namespace GMap.NET.Internals |
{ |
using System; |
using System.Diagnostics; |
using System.IO; |
using System.Text; |
using GMap.NET.CacheProviders; |
using System.Security.Cryptography; |
|
internal class CacheLocator |
{ |
private static string location; |
public static string Location |
{ |
get |
{ |
if(string.IsNullOrEmpty(location)) |
{ |
Reset(); |
} |
|
return location; |
} |
set |
{ |
if(string.IsNullOrEmpty(value)) // setting to null resets to default |
{ |
Reset(); |
} |
else |
{ |
location = value; |
} |
|
if(Delay) |
{ |
Cache.Instance.CacheLocation = location; |
} |
} |
} |
|
static void Reset() |
{ |
string appDataLocation = GetApplicationDataFolderPath(); |
|
#if !PocketPC |
// http://greatmaps.codeplex.com/discussions/403151 |
// by default Network Service don't have disk write access |
if(string.IsNullOrEmpty(appDataLocation)) |
{ |
GMaps.Instance.Mode = AccessMode.ServerOnly; |
GMaps.Instance.UseDirectionsCache = false; |
GMaps.Instance.UseGeocoderCache = false; |
GMaps.Instance.UsePlacemarkCache = false; |
GMaps.Instance.UseRouteCache = false; |
GMaps.Instance.UseUrlCache = false; |
} |
else |
#endif |
{ |
Location = appDataLocation; |
} |
} |
|
public static string GetApplicationDataFolderPath() |
{ |
#if !PocketPC |
bool isSystem = false; |
try |
{ |
using(var identity = System.Security.Principal.WindowsIdentity.GetCurrent()) |
{ |
if(identity != null) |
{ |
isSystem = identity.IsSystem; |
} |
} |
} |
catch(Exception ex) |
{ |
Trace.WriteLine("SQLitePureImageCache, WindowsIdentity.GetCurrent: " + ex); |
} |
|
string path = string.Empty; |
|
// https://greatmaps.codeplex.com/workitem/16112 |
if(isSystem) |
{ |
path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData); |
} |
else |
{ |
path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData); |
} |
#else |
path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData); |
#endif |
|
if(!string.IsNullOrEmpty(path)) |
{ |
path += Path.DirectorySeparatorChar + "GMap.NET" + Path.DirectorySeparatorChar; |
} |
|
return path; |
} |
|
public static bool Delay = false; |
} |
|
/// <summary> |
/// cache system for tiles, geocoding, etc... |
/// </summary> |
internal class Cache : Singleton<Cache> |
{ |
/// <summary> |
/// abstract image cache |
/// </summary> |
public PureImageCache ImageCache; |
|
/// <summary> |
/// second level abstract image cache |
/// </summary> |
public PureImageCache ImageCacheSecond; |
|
string cache; |
|
/// <summary> |
/// local cache location |
/// </summary> |
public string CacheLocation |
{ |
get |
{ |
return cache; |
} |
set |
{ |
cache = value; |
#if SQLite |
if(ImageCache is SQLitePureImageCache) |
{ |
(ImageCache as SQLitePureImageCache).CacheLocation = value; |
} |
#else |
if(ImageCache is MsSQLCePureImageCache) |
{ |
(ImageCache as MsSQLCePureImageCache).CacheLocation = value; |
} |
#endif |
CacheLocator.Delay = true; |
} |
} |
|
public Cache() |
{ |
#region singleton check |
if(Instance != null) |
{ |
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\"")); |
} |
#endregion |
|
#if SQLite |
ImageCache = new SQLitePureImageCache(); |
#else |
// you can use $ms stuff if you like too ;} |
ImageCache = new MsSQLCePureImageCache(); |
#endif |
|
#if PocketPC |
// use sd card if exist for cache |
string sd = Native.GetRemovableStorageDirectory(); |
if(!string.IsNullOrEmpty(sd)) |
{ |
CacheLocation = sd + Path.DirectorySeparatorChar + "GMap.NET" + Path.DirectorySeparatorChar; |
} |
else |
#endif |
{ |
#if PocketPC |
CacheLocation = CacheLocator.Location; |
#else |
string newCache = CacheLocator.Location; |
|
string oldCache = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + "GMap.NET" + Path.DirectorySeparatorChar; |
|
// move database to non-roaming user directory |
if(Directory.Exists(oldCache)) |
{ |
try |
{ |
if(Directory.Exists(newCache)) |
{ |
Directory.Delete(oldCache, true); |
} |
else |
{ |
Directory.Move(oldCache, newCache); |
} |
CacheLocation = newCache; |
} |
catch(Exception ex) |
{ |
CacheLocation = oldCache; |
Trace.WriteLine("SQLitePureImageCache, moving data: " + ex.ToString()); |
} |
} |
else |
{ |
CacheLocation = newCache; |
} |
#endif |
} |
} |
|
#region -- etc cache -- |
|
static readonly SHA1CryptoServiceProvider HashProvider = new SHA1CryptoServiceProvider(); |
|
void ConvertToHash(ref string s) |
{ |
s = BitConverter.ToString(HashProvider.ComputeHash(Encoding.Unicode.GetBytes(s))); |
} |
|
public void SaveContent(string url, CacheType type, string content) |
{ |
try |
{ |
ConvertToHash(ref url); |
|
string dir = Path.Combine(cache, type.ToString()) + Path.DirectorySeparatorChar; |
|
// precrete dir |
if(!Directory.Exists(dir)) |
{ |
Directory.CreateDirectory(dir); |
} |
|
string file = dir + url + ".txt"; |
|
using(StreamWriter writer = new StreamWriter(file, false, Encoding.UTF8)) |
{ |
writer.Write(content); |
} |
} |
catch(Exception ex) |
{ |
Debug.WriteLine("SaveContent: " + ex); |
} |
} |
|
public string GetContent(string url, CacheType type, TimeSpan stayInCache) |
{ |
string ret = null; |
|
try |
{ |
ConvertToHash(ref url); |
|
string dir = Path.Combine(cache, type.ToString()) + Path.DirectorySeparatorChar; |
string file = dir + url + ".txt"; |
|
if(File.Exists(file)) |
{ |
var writeTime = File.GetLastWriteTime(file); |
if (DateTime.Now - writeTime < stayInCache) |
{ |
using (StreamReader r = new StreamReader(file, Encoding.UTF8)) |
{ |
ret = r.ReadToEnd(); |
} |
} |
else |
{ |
File.Delete(file); |
} |
} |
} |
catch(Exception ex) |
{ |
ret = null; |
Debug.WriteLine("GetContent: " + ex); |
} |
|
return ret; |
} |
|
public string GetContent(string url, CacheType type) |
{ |
return GetContent(url, type, TimeSpan.FromDays(88)); |
} |
|
#endregion |
} |
|
internal enum CacheType |
{ |
GeocoderCache, |
PlacemarkCache, |
RouteCache, |
UrlCache, |
DirectionsCache, |
} |
} |