| File: Microsoft\Tools\ServiceModel\SvcUtil\OutputModule.cs | Web Access |
| Project: src\src\svcutilcore\src\dotnet-svcutil.xmlserializer.csproj (dotnet-svcutil.xmlserializer) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace Microsoft.Tools.ServiceModel.SvcUtil.XmlSerializer { using System; using System.Collections.Generic; using System.IO; using System.Globalization; using System.Text; internal abstract class OutputModule { protected const string defaultFilename = "output"; protected const string configFileExtension = ".config"; private readonly string _directoryPath; protected OutputModule(Options options) { _directoryPath = PathHelper.TryGetDirectoryPath(options.DirectoryArg); } protected string BuildFilePath(string filepath, string extension, string option) { return PathHelper.BuildFilePath(_directoryPath, filepath, extension, option); } protected static class PathHelper { internal static string BuildFilePath(string directoryPath, string filepath, string extension, string option) { Tool.Assert(!string.IsNullOrEmpty(filepath), "filename must have a valid value"); Tool.Assert(!string.IsNullOrEmpty(extension), "extension must have a valid value"); string outputFileWithExtension = GetFilepathWithExtension(filepath, extension); string combinedPath = Path.Combine(directoryPath, outputFileWithExtension); return TryGetFullPath(combinedPath, option); } internal static string GetFilepathWithExtension(string outputFile, string extension) { string outputFileWithExtension; if (extension != null && (!Path.HasExtension(outputFile) || !Path.GetExtension(outputFile).Equals(extension, StringComparison.OrdinalIgnoreCase))) { outputFileWithExtension = outputFile + extension; } else { outputFileWithExtension = outputFile; } return outputFileWithExtension; } internal static string TryGetDirectoryPath(string directory) { if (directory == null || directory.Length == 0) return "." + Path.DirectorySeparatorChar; else { if (!directory.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) return TryGetFullPath(directory + Path.DirectorySeparatorChar, null); else return TryGetFullPath(directory, null); } } private static string TryGetFullPath(string path, string option) { try { return Path.GetFullPath(path); } catch (PathTooLongException ptle) { if (!string.IsNullOrEmpty(option)) { throw new ToolArgumentException(SR.Format(SR.ErrPathTooLong, path, Options.Cmd.Directory, option), ptle); } else { throw new ToolArgumentException(SR.Format(SR.ErrPathTooLongDirOnly, path, Options.Cmd.Directory), ptle); } } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Tool.IsFatal(e)) throw; throw new ToolArgumentException(SR.Format(SR.ErrInvalidPath, path, option), e); } } } internal static void CreateDirectoryIfNeeded(string path) { try { string directoryPath = Path.GetDirectoryName(path); if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (Tool.IsFatal(e)) throw; throw new ToolRuntimeException(SR.Format(SR.ErrCannotCreateDirectory, path), e); } } internal static class FilenameHelper { private const string DataContractXsdBaseNamespace = "http://schemas.datacontract.org/2004/07/"; private static int s_dataContractXsdBaseNamespaceLength = DataContractXsdBaseNamespace.Length; private static readonly List<string> s_existingFileNames = new List<string>(); internal static string UniquifyFileName(string filename, string extension) { string fileNameWithExtension = PathHelper.GetFilepathWithExtension(filename, extension); if (!UniquifyFileName_NameExists(fileNameWithExtension)) { s_existingFileNames.Add(fileNameWithExtension); return filename; } for (uint i = 1; i < uint.MaxValue; i++) { string uniqueFileName = filename + i.ToString(NumberFormatInfo.InvariantInfo); string uniqueFileNameWithExtension = PathHelper.GetFilepathWithExtension(uniqueFileName, extension); if (!UniquifyFileName_NameExists(uniqueFileNameWithExtension)) { s_existingFileNames.Add(uniqueFileNameWithExtension); return uniqueFileName; } } throw new ToolRuntimeException(SR.Format(SR.ErrUnableToUniquifyFilename, fileNameWithExtension), null); } private static bool UniquifyFileName_NameExists(string fileName) { for (int i = 0; i < s_existingFileNames.Count; i++) { if (String.Compare(fileName, s_existingFileNames[i], StringComparison.OrdinalIgnoreCase) == 0) return true; } return false; } internal static string FilenameFromUri(string ns) { StringBuilder fileNameBuilder = new StringBuilder(); if (string.IsNullOrEmpty(ns)) FilenameFromUri_Add(fileNameBuilder, "noNamespace"); else { Uri nsUri = null; if (Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out nsUri)) { if (nsUri.IsAbsoluteUri) { string absoluteUriString = nsUri.AbsoluteUri; if (absoluteUriString.StartsWith(DataContractXsdBaseNamespace, StringComparison.Ordinal)) { int length = absoluteUriString.Length - s_dataContractXsdBaseNamespaceLength; if (absoluteUriString.EndsWith("/", StringComparison.Ordinal)) length--; if (length > 0) { FilenameFromUri_Add(fileNameBuilder, absoluteUriString.Substring(s_dataContractXsdBaseNamespaceLength, length).Replace('/', '.')); } else { FilenameFromUri_Add(fileNameBuilder, "schema"); } } else { FilenameFromUri_Add(fileNameBuilder, nsUri.Host); string absolutePath = nsUri.AbsolutePath; if (absolutePath.EndsWith("/", StringComparison.Ordinal)) absolutePath = absolutePath.Substring(0, absolutePath.Length - 1); FilenameFromUri_Add(fileNameBuilder, absolutePath.Replace('/', '.')); } } else { FilenameFromUri_Add(fileNameBuilder, nsUri.OriginalString.Replace('/', '.')); } } } string filename = fileNameBuilder.ToString(); return filename; } private static void FilenameFromUri_Add(StringBuilder path, string segment) { if (segment != null) { char[] chars = segment.ToCharArray(); for (int i = 0; i < chars.Length; i++) { char c = chars[i]; if (Array.IndexOf(Path.GetInvalidFileNameChars(), c) == -1) path.Append(c); } } } } } }