PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/XAct.UI/XAct.UI.Web/UI/Web/Tools/MimeTools.cs

https://bitbucket.org/xact/cs.ff.xact.lib
C# | 300 lines | 231 code | 19 blank | 50 comment | 29 complexity | 259d25e10d3882ae80d2a22eb8bb9ff4 MD5 | raw file
  1. namespace XAct.UI.Web.Tools
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Runtime.InteropServices;
  7. using System.Xml.Serialization;
  8. using Microsoft.Win32;
  9. /// <summary>
  10. /// Class of Static Helper functions for common Mime operations.
  11. /// </summary>
  12. public static class MimeTools
  13. {
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. /// <param name="pBC"></param>
  18. /// <param name="pwzUrl"></param>
  19. /// <param name="pBuffer"></param>
  20. /// <param name="cbSize"></param>
  21. /// <param name="pwzMimeProposed"></param>
  22. /// <param name="dwMimeFlags"></param>
  23. /// <param name="ppwzMimeOut"></param>
  24. /// <param name="dwReserved"></param>
  25. /// <returns></returns>
  26. /// <internal>
  27. /// Src: http://msdn.microsoft.com/en-us/library/ms775147(v=vs.85).aspx
  28. /// </internal>
  29. [DllImport("urlmon.dll", CharSet = CharSet.Auto)]
  30. internal static extern int FindMimeFromData(
  31. IntPtr pBC,
  32. [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
  33. IntPtr pBuffer,
  34. int cbSize,
  35. [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
  36. int dwMimeFlags,
  37. [MarshalAs(UnmanagedType.LPWStr)] out string ppwzMimeOut,
  38. int dwReserved);
  39. /// <summary>
  40. /// Get MimeType for given FileName.
  41. /// Accepts either fullname ('file.png') or extension('.png')
  42. /// </summary>
  43. /// <remarks>
  44. /// <para>
  45. /// Relies on UnSafe calls to underlying API.
  46. /// </para>
  47. /// </remarks>
  48. /// <param name = "filename"></param>
  49. /// <returns></returns>
  50. public static string GetMimeType(string filename)
  51. {
  52. string mimeType = null;
  53. FindMimeFromData(IntPtr.Zero, filename, IntPtr.Zero, 0, null, 0, out mimeType, 0);
  54. return mimeType ?? "application/x-unknown";
  55. }
  56. }
  57. /// <summary>
  58. /// TODOC
  59. /// </summary>
  60. public sealed class MimeExtensionHelper
  61. {
  62. private MimeExtensionHelper()
  63. {
  64. }
  65. /// <summary>Finds extension associated with specified mime type</summary>
  66. /// <param name="mimeType">mime type you search extension for, e.g.: "application/octet-stream"</param>
  67. /// <returns>most used extension, associated with provided type, e.g.: ".bin"</returns>
  68. public static string FindExtension(string mimeType)
  69. {
  70. return ExtensionTypes.GetExtension(mimeType);
  71. }
  72. /// <summary>Finds mime type using provided extension and/or file's binary content.</summary>
  73. /// <param name="file">Full file path</param>
  74. /// <param name="verifyFromContent">Should the file's content be examined to verify founded value.</param>
  75. /// <returns>mime type of file, e.g.: "application/octet-stream"</returns>
  76. public static string FindMime(string file, bool verifyFromContent)
  77. {
  78. string extension = Path.GetExtension(file);
  79. string mimeType = string.Empty;
  80. try
  81. {
  82. if (!String.IsNullOrEmpty(extension))
  83. {
  84. mimeType = ExtensionTypes.GetMimeType(extension);
  85. }
  86. if (verifyFromContent
  87. || (String.IsNullOrEmpty(mimeType) && File.Exists(file)))
  88. {
  89. mimeType = FindMimeByContent(file, mimeType);
  90. }
  91. }
  92. catch
  93. {
  94. }
  95. return (mimeType ?? string.Empty).Trim(); //"application/octet-stream"
  96. }
  97. /// <summary>Finds mime type for file using it's binary data.</summary>
  98. /// <param name="file">Full path to file.</param>
  99. /// <param name="proposedType">Optional. Expected file's type.</param>
  100. /// <returns>mime type, e.g.: "application/octet-stream"</returns>
  101. public static string FindMimeByContent(string file
  102. , string proposedType)
  103. {
  104. FileInfo fi = new FileInfo(file);
  105. if (!fi.Exists)
  106. {
  107. throw new FileNotFoundException(file);
  108. }
  109. byte[] buf = new byte[Math.Min(4096L, fi.Length)];
  110. using (FileStream fs = File.OpenRead(file))
  111. {
  112. fs.Read(buf, 0, buf.Length);
  113. }
  114. return FindMimeByData(buf, proposedType);
  115. }
  116. /// <summary>Finds mime type for binary data.</summary>
  117. /// <param name="dataBytes">Binary data to examine.</param>
  118. /// <param name="mimeProposed">Optional. Expected mime type.</param>
  119. /// <returns>mime type, e.g.: "application/octet-stream"</returns>
  120. public static string FindMimeByData(byte[] dataBytes, string mimeProposed)
  121. {
  122. if (dataBytes == null || dataBytes.Length == 0)
  123. {
  124. throw new ArgumentNullException("dataBytes");
  125. }
  126. string mimeRet = String.Empty;
  127. IntPtr outPtr = IntPtr.Zero;
  128. if (!String.IsNullOrEmpty(mimeProposed))
  129. {
  130. mimeRet = mimeProposed;
  131. }
  132. int result = FindMimeFromData(IntPtr.Zero
  133. , null
  134. , dataBytes
  135. , dataBytes.Length
  136. , String.IsNullOrEmpty(mimeProposed) ? null : mimeProposed
  137. , 0
  138. , out outPtr
  139. , 0);
  140. if (result != 0)
  141. {
  142. throw Marshal.GetExceptionForHR(result);
  143. }
  144. if (outPtr != null && outPtr != IntPtr.Zero)
  145. {
  146. mimeRet = Marshal.PtrToStringUni(outPtr);
  147. Marshal.FreeCoTaskMem(outPtr);
  148. }
  149. return mimeRet;
  150. }
  151. [DllImport("urlmon.dll"
  152. , CharSet = CharSet.Unicode
  153. , ExactSpelling = true
  154. , SetLastError = true)]
  155. private static extern Int32 FindMimeFromData(IntPtr pBC
  156. , [MarshalAs(UnmanagedType.LPWStr)] String pwzUrl
  157. ,
  158. [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1,
  159. SizeParamIndex = 3)] Byte[] pBuffer
  160. , Int32 cbSize
  161. , [MarshalAs(UnmanagedType.LPWStr)] String pwzMimeProposed
  162. , Int32 dwMimeFlags
  163. , out IntPtr ppwzMimeOut
  164. , Int32 dwReserved);
  165. private static MimeTypeCollection _extensionTypes;
  166. private static MimeTypeCollection ExtensionTypes
  167. {
  168. get
  169. {
  170. if (_extensionTypes == null)
  171. {
  172. _extensionTypes = new MimeTypeCollection();
  173. }
  174. return _extensionTypes;
  175. }
  176. }
  177. //[Serializable]
  178. //[XmlRoot(ElementName = "mimeTypes")]
  179. private class MimeTypeCollection : List<MimeTypeCollection.mimeTypeInfo>
  180. {
  181. private SortedList<string, string> _extensions;
  182. private SortedList<string, List<string>> _mimes;
  183. private void Init()
  184. {
  185. if (_extensions == null || _mimes == null
  186. || _extensions.Count == 0 || _mimes.Count == 0)
  187. {
  188. _extensions = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);
  189. _mimes = new SortedList<string, List<string>>(StringComparer.OrdinalIgnoreCase);
  190. foreach (mimeTypeInfo mime in this)
  191. {
  192. _mimes.Add(mime.MimeType, new List<string>(mime.Extensions));
  193. foreach (string ext in mime.Extensions)
  194. {
  195. if (!_extensions.ContainsKey(ext))
  196. {
  197. _extensions.Add(ext, mime.MimeType);
  198. }
  199. }
  200. }
  201. }
  202. }
  203. public String GetExtension(string type)
  204. {
  205. Init();
  206. return _mimes.ContainsKey(type) ? _mimes[type][0] : string.Empty;
  207. }
  208. public String GetMimeType(string extension)
  209. {
  210. Init();
  211. return _extensions.ContainsKey(extension) ? _extensions[extension] : string.Empty;
  212. }
  213. public MimeTypeCollection()
  214. {
  215. this.Add(new mimeTypeInfo("application/applixware", new List<string>(new[] {".aw"})));
  216. this.Add(new mimeTypeInfo("application/atom+xml", new List<string>(new[] {".atom"})));
  217. // ... Whole list from apache's site
  218. this.Add(new mimeTypeInfo("x-x509-ca-cert", new List<string>(new[] {".cer"})));
  219. try
  220. {
  221. using (RegistryKey classesRoot = Registry.ClassesRoot)
  222. {
  223. using (RegistryKey typeKey = classesRoot.OpenSubKey(@"MIME\Database\Content Type"))
  224. {
  225. string[] subKeyNames = typeKey.GetSubKeyNames();
  226. string extension = string.Empty;
  227. foreach (string keyname in subKeyNames)
  228. {
  229. string trimmed = (keyname ?? string.Empty).Trim();
  230. if (string.IsNullOrEmpty(trimmed))
  231. {
  232. continue;
  233. }
  234. if (!String.IsNullOrEmpty(GetExtension(trimmed)))
  235. {
  236. continue;
  237. }
  238. string subKey = "MIME\\Database\\Content Type\\" + trimmed;
  239. using (RegistryKey curKey = classesRoot.OpenSubKey(subKey))
  240. {
  241. extension = (curKey.GetValue("Extension") as string ?? string.Empty).Trim();
  242. if (extension.Length > 0)
  243. {
  244. this.Add(new mimeTypeInfo(trimmed
  245. , new List<string>(new[] {extension})));
  246. }
  247. }
  248. }
  249. }
  250. }
  251. }
  252. catch (Exception ex)
  253. {
  254. string s = ex.ToString();
  255. }
  256. }
  257. //[Serializable]
  258. public class mimeTypeInfo
  259. {
  260. [XmlAttribute(AttributeName = "mimeType")]
  261. public String MimeType { get; set; }
  262. [XmlElement("extension")]
  263. public List<String> Extensions { get; set; }
  264. public mimeTypeInfo(string mimeType, List<string> extensions)
  265. {
  266. MimeType = mimeType;
  267. Extensions = extensions;
  268. }
  269. public mimeTypeInfo()
  270. {
  271. }
  272. }
  273. }
  274. }
  275. }