aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs')
-rw-r--r--src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
new file mode 100644
index 00000000..0ecd0096
--- /dev/null
+++ b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs
@@ -0,0 +1,83 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Bind
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.IO;
9 using System.Linq;
10 using System.Security.Cryptography;
11 using System.Text;
12
13 /// <summary>
14 /// Internal helper class used to extract embedded files.
15 /// </summary>
16 internal sealed class ExtractEmbeddedFiles
17 {
18 private Dictionary<Uri, SortedList<int, string>> filesWithEmbeddedFiles = new Dictionary<Uri, SortedList<int, string>>();
19
20 public IEnumerable<Uri> Uris { get { return this.filesWithEmbeddedFiles.Keys; } }
21
22 /// <summary>
23 /// Adds an embedded file index to track and returns the path where the embedded file will be extracted. Duplicates will return the same extract path.
24 /// </summary>
25 /// <param name="uri">Uri to file containing the embedded files.</param>
26 /// <param name="embeddedFileIndex">Index of the embedded file to extract.</param>
27 /// <param name="tempPath">Path where temporary files should be placed.</param>
28 /// <returns>The extract path for the embedded file.</returns>
29 public string AddEmbeddedFileIndex(Uri uri, int embeddedFileIndex, string tempPath)
30 {
31 string extractPath;
32 SortedList<int, string> extracts;
33
34 // If the uri to the file that contains the embedded file does not already have embedded files
35 // being extracted, create the dictionary to track that.
36 if (!filesWithEmbeddedFiles.TryGetValue(uri, out extracts))
37 {
38 extracts = new SortedList<int, string>();
39 filesWithEmbeddedFiles.Add(uri, extracts);
40 }
41
42 // If the embedded file is not already tracked in the dictionary of extracts, add it.
43 if (!extracts.TryGetValue(embeddedFileIndex, out extractPath))
44 {
45 string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(uri.LocalPath);
46 string unique = this.HashUri(uri.AbsoluteUri);
47 string extractedName = String.Format(CultureInfo.InvariantCulture, @"{0}_{1}\{2}", localFileNameWithoutExtension, unique, embeddedFileIndex);
48
49 extractPath = Path.Combine(tempPath, extractedName);
50 extracts.Add(embeddedFileIndex, extractPath);
51 }
52
53 return extractPath;
54 }
55
56 public IEnumerable<ExtractFile> GetExtractFilesForUri(Uri uri)
57 {
58 SortedList<int, string> extracts;
59 if (!filesWithEmbeddedFiles.TryGetValue(uri, out extracts))
60 {
61 extracts = new SortedList<int, string>();
62 }
63
64 return extracts.Select(e => new ExtractFile() { EmbeddedFileIndex = e.Key, OutputPath = e.Value });
65 }
66
67 private string HashUri(string uri)
68 {
69 using (SHA1 sha1 = new SHA1CryptoServiceProvider())
70 {
71 byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(uri));
72 return Convert.ToBase64String(hash).TrimEnd('=').Replace('+', '-').Replace('/', '_');
73 }
74 }
75
76 internal struct ExtractFile
77 {
78 public int EmbeddedFileIndex { get; set; }
79
80 public string OutputPath { get; set; }
81 }
82 }
83}