Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

136 lines
6.4 KiB
C#

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity
{
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Security;
using System.Security.Permissions;
#if !SILVERLIGHT
#endif
/// <summary>
/// Various utilities for dealing with embedded resources
/// </summary>
public static class ResourceUtilities
{
#if !SILVERLIGHT
/// <summary>
/// Extracts the specified compressed resource to a given directory
/// </summary>
/// <param name="outputDirectory"> Output directory </param>
/// <param name="assembly"> Assembly that contains the resource </param>
/// <param name="resourceName"> Partial resource name </param>
/// <remarks>
/// The method prefixes the actual resource with unqualified assembly name + '.Resources.' (
/// so you should put all your resources under 'Resources' directory within a project)
/// and appends '.gz' to it. You should use gzip to produce compressed files.
/// </remarks>
[SecuritySafeCritical]
// Calling File.Create demands FileIOPermission (Write flag) for the file path to which the resource is extracted.
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "gz",
Justification = ".gz is GZIP file extension")]
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times",
Justification = "Bogus warning, object will be disposed once.")]
public static void ExtractCompressedResourceToDirectory(string outputDirectory, Assembly assembly, string resourceName)
{
ValidateCommonArguments(outputDirectory, assembly, resourceName);
var fullResourceName = new AssemblyName(assembly.FullName).Name + ".Resources." + resourceName + ".gz";
using (var compressedInputStream = assembly.GetManifestResourceStream(fullResourceName))
{
if (compressedInputStream == null)
{
throw new IOException("Embedded resource " + fullResourceName + " not found in " + assembly.FullName);
}
using (var decompressedInputStream = new GZipStream(compressedInputStream, CompressionMode.Decompress))
{
using (Stream outputStream = File.Create(Path.Combine(outputDirectory, resourceName)))
{
IOHelpers.CopyStream(decompressedInputStream, outputStream);
}
}
}
}
#endif
/// <summary>
/// Copies the named embedded resources from given assembly into the current directory.
/// </summary>
/// <param name="assembly"> The assembly. </param>
/// <param name="prefix"> The prefix to use for each name. </param>
/// <param name="overwrite"> if set to <c>true</c> then an existing file of the same name name will be overwritten. </param>
/// <param name="names"> The resource names, which will become the file names. </param>
public static void CopyEmbeddedResourcesToCurrentDir(
Assembly assembly, string prefix, bool overwrite,
params string[] names)
{
foreach (var name in names)
{
using (var sourceStream = assembly.GetManifestResourceStream(prefix + name))
{
Debug.Assert(sourceStream != null, "Could not create stream for embedded resource " + prefix + name);
var destinationPath = Path.Combine(@".\", name);
if (!File.Exists(destinationPath) || overwrite)
{
using (
var destinationStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write))
{
var sourceBuffer = new byte[sourceStream.Length];
sourceStream.Read(sourceBuffer, 0, sourceBuffer.Length);
destinationStream.Write(sourceBuffer, 0, sourceBuffer.Length);
}
}
}
}
}
/// <summary>
/// Builds a resource manager for the given assembly.
/// </summary>
/// <param name="assembly"> The assembly to build the resource manager for. </param>
/// <returns> The resource manager. </returns>
public static ResourceManager BuildResourceManager(Assembly assembly)
{
ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly");
return new ResourceManager(FindSingleResourceTable(assembly), assembly);
}
private static void ValidateCommonArguments(string outputDirectory, Assembly assembly, string resourceName)
{
ExceptionHelpers.CheckArgumentNotNull(outputDirectory, "outputDirectory");
ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly");
ExceptionHelpers.CheckArgumentNotNull(resourceName, "resourceName");
if (!Directory.Exists(outputDirectory))
{
throw new IOException("Output directory '" + outputDirectory + "' does not exist.");
}
}
private static string FindSingleResourceTable(Assembly assembly)
{
var resources = assembly.GetManifestResourceNames().Where(r => r.EndsWith(".resources", StringComparison.Ordinal));
if (resources.Count() != 1)
{
throw new NotSupportedException(
"The supplied assembly does not contain exactly one resource table, if the assembly contains multiple tables call the overload that specifies which table to use.");
}
var resource = resources.Single();
// Need to trim the ".resources" off the end
return resource.Substring(0, resource.Length - 10);
}
}
}