diff --git a/DashTools.CodeGenerator/App.config b/DashTools.CodeGenerator/App.config
new file mode 100644
index 0000000..44e1a77
--- /dev/null
+++ b/DashTools.CodeGenerator/App.config
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DashTools.CodeGenerator/ClassWalker.cs b/DashTools.CodeGenerator/ClassWalker.cs
new file mode 100644
index 0000000..3ea4c2f
--- /dev/null
+++ b/DashTools.CodeGenerator/ClassWalker.cs
@@ -0,0 +1,33 @@
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace DashTools.CodeGenerator
+{
+ public class ClassWalker : CSharpSyntaxWalker
+ {
+ public ClassWalker(SyntaxWalkerDepth depth = SyntaxWalkerDepth.Node)
+ : base(depth)
+ {
+ }
+
+ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
+
+ {
+ var token = SyntaxFactory.Identifier(
+ node.Identifier.LeadingTrivia,
+ node.Identifier.Kind(),
+ node.Identifier.ValueText.Replace("type", ""),
+ node.Identifier.ValueText.Replace("type", ""),
+ node.Identifier.TrailingTrivia);
+ var changed = node.WithIdentifier(token);
+
+ base.VisitClassDeclaration(node);
+ }
+ }
+}
diff --git a/DashTools.CodeGenerator/DashTools.CodeGenerator.csproj b/DashTools.CodeGenerator/DashTools.CodeGenerator.csproj
new file mode 100644
index 0000000..f6e9f5d
--- /dev/null
+++ b/DashTools.CodeGenerator/DashTools.CodeGenerator.csproj
@@ -0,0 +1,243 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5B0225A5-45AE-4A44-9BC7-BF60825DFDF4}
+ Exe
+ Properties
+ DashTools.CodeGenerator
+ DashTools.CodeGenerator
+ v4.6.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Microsoft.Build.15.5.180\lib\net46\Microsoft.Build.dll
+ True
+
+
+ ..\packages\Microsoft.Build.Framework.15.5.180\lib\net46\Microsoft.Build.Framework.dll
+ True
+
+
+ ..\packages\Microsoft.Build.Tasks.Core.15.5.180\lib\net46\Microsoft.Build.Tasks.Core.dll
+ True
+
+
+ ..\packages\Microsoft.Build.Utilities.Core.15.5.180\lib\net46\Microsoft.Build.Utilities.Core.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.Common.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.CSharp.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.VisualBasic.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.2.6.1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.6.1\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll
+ True
+
+
+ ..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.6.1\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll
+ True
+
+
+
+ ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll
+ True
+
+
+ ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
+ True
+
+
+
+ ..\packages\System.Composition.AttributedModel.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll
+ True
+
+
+ ..\packages\System.Composition.Convention.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll
+ True
+
+
+ ..\packages\System.Composition.Hosting.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll
+ True
+
+
+ ..\packages\System.Composition.Runtime.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll
+ True
+
+
+ ..\packages\System.Composition.TypedParts.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll
+ True
+
+
+ ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll
+ True
+
+
+
+ ..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll
+ True
+
+
+ ..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll
+ True
+
+
+ ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll
+ True
+
+
+ ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll
+ True
+
+
+ ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll
+ True
+
+
+
+ ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll
+ True
+
+
+ ..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll
+ True
+
+
+ ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
+ True
+
+
+ ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll
+ True
+
+
+ ..\packages\System.Runtime.InteropServices.4.3.0\lib\net462\System.Runtime.InteropServices.dll
+ True
+
+
+ ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
+ True
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll
+ True
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+ True
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll
+ True
+
+
+ ..\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll
+ True
+
+
+ ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll
+ True
+
+
+ ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll
+ True
+
+
+
+
+
+
+
+
+ ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll
+ True
+
+
+ ..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll
+ True
+
+
+ ..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll
+ True
+
+
+ ..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d517b927-7afc-42ad-a410-27354f3217c2}
+ DashTools
+
+
+
+
+
\ No newline at end of file
diff --git a/DashTools.CodeGenerator/MoveNamespacesToUsingsRewriter.cs b/DashTools.CodeGenerator/MoveNamespacesToUsingsRewriter.cs
new file mode 100644
index 0000000..24eddec
--- /dev/null
+++ b/DashTools.CodeGenerator/MoveNamespacesToUsingsRewriter.cs
@@ -0,0 +1,137 @@
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace DashTools.CodeGenerator
+{
+ public class MoveNamespacesToUsingsRewriter : CSharpSyntaxRewriter
+ {
+ private List namespacesToAdd = null;
+
+ public MoveNamespacesToUsingsRewriter(bool visitIntoStructuredTrivia = false)
+ : base(visitIntoStructuredTrivia)
+ {
+ }
+
+ public override SyntaxNode Visit(SyntaxNode node)
+ {
+ if (namespacesToAdd == null)
+ {
+ var finder = new UsingDirectivesFinder();
+ finder.Visit(node);
+ var existingUsingDirectives = finder.ExistingUsingDirectives.ToList();
+ namespacesToAdd = finder
+ .NamespacesInQualifiedNames
+ .Where(e => !existingUsingDirectives.Any(ee => ee.ToFullString() == e.ToFullString()))
+ .ToList();
+ }
+
+ node = base.Visit(node);
+
+ return node;
+ }
+
+ public override SyntaxNode VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
+ {
+ var usingsToAdd = namespacesToAdd
+ .Select(e => e.WithLeadingTrivia(SyntaxFactory.Whitespace(" ")))
+ .Select(e => SyntaxFactory.UsingDirective(e).WithLeadingTrivia(SyntaxFactory.Tab))
+ .Select(e => e.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed));
+ var newUsings = node.Usings.AddRange(usingsToAdd);
+
+ return (base.VisitNamespaceDeclaration(node) as NamespaceDeclarationSyntax)
+ .WithUsings(new SyntaxList(newUsings));
+ }
+
+ public override SyntaxNode VisitAttribute(AttributeSyntax node)
+ {
+ node = base.VisitAttribute(node) as AttributeSyntax;
+
+ if (node.Name is QualifiedNameSyntax)
+ {
+ var qualifiedName = node.Name as QualifiedNameSyntax;
+ var simpleName = qualifiedName.Right;
+ node = node.WithName(simpleName);
+ }
+
+ return node;
+ }
+
+ public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
+ {
+ node = base.VisitPropertyDeclaration(node) as PropertyDeclarationSyntax;
+
+ var type = GetTypeWithoutNamespaces(node.Type).WithTriviaFrom(node.Type);
+ node = node
+ .WithType(type)
+ .WithTriviaFrom(node);
+
+ return node;
+ }
+
+ public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node)
+ {
+ node = base.VisitFieldDeclaration(node) as FieldDeclarationSyntax;
+
+ var type = GetTypeWithoutNamespaces(node.Declaration.Type)
+ .WithTriviaFrom(node.Declaration.Type);
+ var declaration = node.Declaration
+ .WithType(type)
+ .WithTriviaFrom(node.Declaration);
+ node = node.WithDeclaration(declaration);
+
+ return node;
+ }
+
+ public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
+ {
+ node = base.VisitMethodDeclaration(node) as MethodDeclarationSyntax;
+
+ node = node.WithReturnType(GetTypeWithoutNamespaces(node.ReturnType))
+ .WithLeadingTrivia(node.ReturnType.GetLeadingTrivia())
+ .WithTrailingTrivia(node.ReturnType.GetTrailingTrivia());
+
+
+ var parameters = node.ParameterList.Parameters;
+ for (int i = 0; i < parameters.Count; i++)
+ {
+ var arg = parameters[i];
+ parameters = parameters.Replace(
+ arg,
+ arg.WithType(GetTypeWithoutNamespaces(arg.Type))
+ .WithLeadingTrivia(arg.Type.GetLeadingTrivia())
+ .WithTrailingTrivia(arg.Type.GetTrailingTrivia())
+ );
+ }
+ node = node.WithParameterList(
+ node.ParameterList
+ .WithParameters(parameters)
+ .WithLeadingTrivia(node.ParameterList.GetLeadingTrivia())
+ .WithTrailingTrivia(node.ParameterList.GetTrailingTrivia())
+ );
+
+ return node;
+ }
+
+ private TypeSyntax GetTypeWithoutNamespaces(T type)
+ where T : TypeSyntax
+ {
+ QualifiedNameSyntax qualifiedName = null;
+ if (type is QualifiedNameSyntax)
+ {
+ qualifiedName = type as QualifiedNameSyntax;
+ }
+ else if (type is ArrayTypeSyntax && (type as ArrayTypeSyntax).ElementType is QualifiedNameSyntax)
+ {
+ qualifiedName = (type as ArrayTypeSyntax).ElementType as QualifiedNameSyntax;
+ }
+
+ return qualifiedName?.Right as TypeSyntax ?? type;
+ }
+ }
+}
diff --git a/DashTools.CodeGenerator/MpdCodeRefactorer.cs b/DashTools.CodeGenerator/MpdCodeRefactorer.cs
new file mode 100644
index 0000000..60d742f
--- /dev/null
+++ b/DashTools.CodeGenerator/MpdCodeRefactorer.cs
@@ -0,0 +1,87 @@
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System.Diagnostics;
+using Microsoft.CodeAnalysis.Rename;
+
+namespace DashTools.CodeGenerator
+{
+ public class MpdCodeRefactorer : CSharpSyntaxRewriter
+ {
+ private readonly SemanticModel semanticModel;
+
+ public RenameSymbolInfo Refactoring { get; private set; }
+
+ public MpdCodeRefactorer(SemanticModel semanticModel, bool visitIntoStructuredTrivia = false)
+ : base(visitIntoStructuredTrivia)
+ {
+ this.semanticModel = semanticModel;
+ }
+
+ public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
+ {
+ string className = node.Identifier.ValueText;
+ if (className.EndsWith("type"))
+ {
+ className = className.Replace("type", "");
+
+ Refactoring = new RenameSymbolInfo
+ {
+ Symbol = semanticModel.GetDeclaredSymbol(node),
+ NewName = className,
+ Comment = "Remove \"type\" suffix from class name"
+ };
+ }
+
+ return Refactoring == null
+ ? base.VisitClassDeclaration(node)
+ : node;
+ }
+
+ public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
+ {
+ string name = node.Identifier.ValueText;
+ if (name.Substring(0, 1) != name.Substring(0, 1).ToUpper())
+ {
+ name = name.Substring(0, 1).ToUpper() + name.Substring(1);
+
+ Refactoring = new RenameSymbolInfo
+ {
+ Symbol = semanticModel.GetDeclaredSymbol(node),
+ NewName = name,
+ Comment = "Capitalize property name's 1st letter"
+ };
+ }
+
+ return base.VisitPropertyDeclaration(node);
+ }
+
+ public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node)
+ {
+ foreach (var variable in node.Declaration.Variables)
+ {
+ string fieldName = variable.Identifier.ValueText;
+ if (fieldName.EndsWith("Field"))
+ {
+ fieldName = fieldName.Substring(0, fieldName.Length - "Field".Length);
+
+ Refactoring = new RenameSymbolInfo
+ {
+ Symbol = semanticModel.GetDeclaredSymbol(variable),
+ NewName = fieldName,
+ Comment = "Remove \"Field\" suffix from field name"
+ };
+ }
+ }
+
+ return Refactoring == null
+ ? base.VisitFieldDeclaration(node)
+ : node;
+ }
+ }
+}
diff --git a/DashTools.CodeGenerator/Program.cs b/DashTools.CodeGenerator/Program.cs
new file mode 100644
index 0000000..e66555a
--- /dev/null
+++ b/DashTools.CodeGenerator/Program.cs
@@ -0,0 +1,184 @@
+using Microsoft.Build.Tasks;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Editing;
+using Microsoft.CodeAnalysis.MSBuild;
+using Microsoft.CodeAnalysis.Rename;
+using Microsoft.CodeAnalysis.Text;
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+
+namespace DashTools.CodeGenerator
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ try
+ {
+ MainAsync().Wait();
+ }
+ catch (Exception ex)
+ {
+ Console.Write(ex);
+ }
+
+ Console.WriteLine();
+ Console.WriteLine("Press to exit");
+ Console.ReadLine();
+ }
+
+ private static async Task MainAsync()
+ {
+ string filePath = await GenerateCodeForMpdSchema();
+ string refactoredFilePath = await RefactorMpdCodeAsync(filePath);
+
+ return;
+
+
+
+ //var workspace = MSBuildWorkspace.Create();
+ //var solution = await workspace.OpenSolutionAsync("../../../SharpDashTools.sln");
+ //var project = solution.Projects.Single(p => p.AssemblyName == typeof(Qoollo.MpegDash.MpdDownloader).Assembly.GetName().Name);
+ //var document = project.Documents.Single(d => d.Name == "MpdSchema.cs");
+ //var syntaxTree = await document.GetSyntaxRootAsync();
+
+ //var walker = new ClassWalker();
+ //walker.Visit(syntaxTree);
+
+ //var rewriter = new MpdCodeRefactorer();
+ //var changed = rewriter.Visit(syntaxTree);
+ //File.WriteAllText(document.FilePath + "test.cs", changed.ToFullString());
+
+ //var generator = SyntaxGenerator.GetGenerator(workspace, LanguageNames.CSharp);
+ }
+
+ private static async Task GenerateCodeForMpdSchema()
+ {
+ var schemaFiles = await DownloadMpdSchemaAsync();
+
+ string result = GenerateCodeForMpdSchema(schemaFiles);
+
+ foreach (var file in schemaFiles)
+ File.Delete(file);
+
+ return result;
+ }
+
+ private static async Task DownloadMpdSchemaAsync()
+ {
+ const string xsdUrl = "https://github.com/Dash-Industry-Forum/Conformance-and-reference-source/raw/master/conformance/MPDValidator/schemas/DASH-MPD.xsd";
+ const string xsdFile = "DASH-MPD.xsd";
+
+ const string xlinkUrl = "https://github.com/Dash-Industry-Forum/Conformance-and-reference-source/raw/master/conformance/MPDValidator/schemas/xlink.xsd";
+ const string xlinkFile = "xlink.xsd";
+
+ var webClient = new WebClient();
+ await webClient.DownloadFileTaskAsync(xsdUrl, xsdFile);
+ await webClient.DownloadFileTaskAsync(xlinkUrl, xlinkFile);
+
+ return new[] { xsdFile, xlinkFile };
+ }
+
+ private static string GenerateCodeForMpdSchema(IEnumerable xsdFiles)
+ {
+ const string xsdExePath = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe";
+ if (!File.Exists(xsdExePath))
+ throw new InvalidOperationException("xsd.exe not found at " + xsdExePath);
+
+ const string newFileName = "MpdSchema.cs";
+ if (File.Exists(newFileName))
+ File.Delete(newFileName);
+
+ var process = Process.Start(xsdExePath, string.Join(" ", xsdFiles) + " /c /n:Qoollo.MpegDash");
+ if (!process.WaitForExit(20000))
+ throw new TimeoutException("XSD -> C# code generation takes too long. Something's wrong.");
+
+ string fileName = string.Join("_", xsdFiles.Select(e => Path.GetFileNameWithoutExtension(e))) + ".cs";
+ if (!File.Exists(fileName))
+ throw new Exception("XSD -> C# code generation succeeded, but file " + fileName + " was not found");
+
+ File.Move(fileName, newFileName);
+
+ return newFileName;
+ }
+
+ private static async Task RefactorMpdCodeAsync(string filePath)
+ {
+ var workspace = new AdhocWorkspace();
+ var projectId = ProjectId.CreateNewId();
+ var versionStamp = VersionStamp.Create();
+ var projectInfo = ProjectInfo.Create(projectId, versionStamp, "test", "test", LanguageNames.CSharp);
+ projectInfo = projectInfo.WithMetadataReferences(
+ new []
+ {
+ typeof(int),
+ typeof(object),
+ typeof(GeneratedCodeAttribute),
+ typeof(XmlTypeAttribute)
+ }
+ .Select(e => e.Assembly.Location)
+ .Select(e => MetadataReference.CreateFromFile(e))
+ );
+ var project = workspace.AddProject(projectInfo);
+
+ var sourceText = SourceText.From(File.ReadAllText(filePath));
+ var document = workspace.AddDocument(project.Id, "NewFile.cs", sourceText);
+ var syntaxRoot = await document.GetSyntaxRootAsync();
+
+
+ var semanticModel = await document.GetSemanticModelAsync();
+ var diagnostics = semanticModel.GetDiagnostics();
+
+ var rewriters = new CSharpSyntaxRewriter[]
+ {
+ new MoveNamespacesToUsingsRewriter(),
+ new RemoveAttributeSuffixRewriter()
+ };
+ foreach (var rewriter in rewriters)
+ {
+ syntaxRoot = rewriter.Visit(syntaxRoot);
+
+ workspace.TryApplyChanges(workspace.CurrentSolution.WithDocumentSyntaxRoot(document.Id, syntaxRoot));
+ document = workspace.CurrentSolution.GetDocument(document.Id);
+ syntaxRoot = await document.GetSyntaxRootAsync();
+ semanticModel = await document.GetSemanticModelAsync();
+ }
+
+ var refactorer = new MpdCodeRefactorer(semanticModel);
+ syntaxRoot = await document.GetSyntaxRootAsync();
+ syntaxRoot = refactorer.Visit(syntaxRoot);
+ while (refactorer.Refactoring != null)
+ {
+ diagnostics = semanticModel.GetDiagnostics();
+
+ var solution = await Renamer.RenameSymbolAsync(workspace.CurrentSolution, refactorer.Refactoring.Symbol, refactorer.Refactoring.NewName, workspace.Options);
+ if (!workspace.TryApplyChanges(solution))
+ {
+ throw new InvalidOperationException("Failed to apply changes after rename");
+ }
+ Console.WriteLine("Applied refactoring:\n\t{0}", refactorer.Refactoring);
+
+ document = workspace.CurrentSolution.GetDocument(document.Id);
+ syntaxRoot = await document.GetSyntaxRootAsync();
+ semanticModel = await document.GetSemanticModelAsync();
+ refactorer = new MpdCodeRefactorer(semanticModel);
+ refactorer.Visit(syntaxRoot);
+ }
+
+ const string newFileName = "NewFileRefactored.cs";
+ File.WriteAllText(newFileName, syntaxRoot.ToFullString());
+
+ return newFileName;
+ }
+
+ }
+}
diff --git a/DashTools.CodeGenerator/Properties/AssemblyInfo.cs b/DashTools.CodeGenerator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4a145b2
--- /dev/null
+++ b/DashTools.CodeGenerator/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DashTools.CodeGenerator")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DashTools.CodeGenerator")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5b0225a5-45ae-4a44-9bc7-bf60825dfdf4")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DashTools.CodeGenerator/RemoveAttributeSuffixRewriter.cs b/DashTools.CodeGenerator/RemoveAttributeSuffixRewriter.cs
new file mode 100644
index 0000000..0fece2c
--- /dev/null
+++ b/DashTools.CodeGenerator/RemoveAttributeSuffixRewriter.cs
@@ -0,0 +1,64 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DashTools.CodeGenerator
+{
+ public class RemoveAttributeSuffixRewriter : CSharpSyntaxRewriter
+ {
+ public RemoveAttributeSuffixRewriter(bool visitIntoStructuredTrivia = false)
+ : base(visitIntoStructuredTrivia)
+ {
+ }
+
+ public override SyntaxNode VisitAttribute(AttributeSyntax node)
+ {
+ node = base.VisitAttribute(node) as AttributeSyntax;
+
+ if (node.Name is QualifiedNameSyntax)
+ {
+ var qualifiedName = node.Name as QualifiedNameSyntax;
+ var newRight = RemoveTrailingAttributeFromName(qualifiedName.Right);
+ var newQualifiedName = qualifiedName.WithRight(newRight);
+ node = node.WithName(newQualifiedName);
+ }
+ else if (node.Name is SimpleNameSyntax)
+ {
+ var newName = RemoveTrailingAttributeFromName(node.Name as SimpleNameSyntax);
+ node = node.WithName(newName);
+ }
+ else if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+
+ return node;
+ }
+
+ private SimpleNameSyntax RemoveTrailingAttributeFromName(SimpleNameSyntax simpleName)
+ {
+ string attributeName = simpleName.Identifier.ValueText;
+ if (attributeName.EndsWith("Attribute"))
+ {
+ attributeName = attributeName.Substring(0, attributeName.Length - "Attribute".Length);
+
+ var identifier = SyntaxFactory.Identifier(
+ simpleName.Identifier.LeadingTrivia,
+ simpleName.Identifier.Kind(),
+ attributeName,
+ attributeName,
+ simpleName.Identifier.TrailingTrivia
+ );
+ simpleName = simpleName.WithIdentifier(identifier);
+ }
+
+ return simpleName;
+ }
+ }
+}
diff --git a/DashTools.CodeGenerator/RenameSymbolInfo.cs b/DashTools.CodeGenerator/RenameSymbolInfo.cs
new file mode 100644
index 0000000..7544f22
--- /dev/null
+++ b/DashTools.CodeGenerator/RenameSymbolInfo.cs
@@ -0,0 +1,18 @@
+using Microsoft.CodeAnalysis;
+
+namespace DashTools.CodeGenerator
+{
+ public class RenameSymbolInfo
+ {
+ public ISymbol Symbol { get; set; }
+
+ public string NewName { get; set; }
+
+ public string Comment { get; set; }
+
+ public override string ToString()
+ {
+ return $"{Comment}.\n\tOld name: {Symbol.Name}.\n\tNew name: {NewName}.";
+ }
+ }
+}
\ No newline at end of file
diff --git a/DashTools.CodeGenerator/UsingDirectivesFinder.cs b/DashTools.CodeGenerator/UsingDirectivesFinder.cs
new file mode 100644
index 0000000..c98fd08
--- /dev/null
+++ b/DashTools.CodeGenerator/UsingDirectivesFinder.cs
@@ -0,0 +1,104 @@
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace DashTools.CodeGenerator
+{
+ public class UsingDirectivesFinder : CSharpSyntaxWalker
+ {
+ public IEnumerable ExistingUsingDirectives
+ {
+ get { return existingUsingDirectives; }
+ }
+ private readonly List existingUsingDirectives = new List();
+
+ public IEnumerable NamespacesInQualifiedNames
+ {
+ get { return namespacesInQualifiedNames; }
+ }
+ private readonly List namespacesInQualifiedNames = new List();
+
+ public override void VisitUsingDirective(UsingDirectiveSyntax node)
+ {
+ base.VisitUsingDirective(node);
+
+ if (!existingUsingDirectives.Any(e => e.ToFullString() == node.Name.ToFullString()))
+ existingUsingDirectives.Add(node.Name);
+ }
+
+ public override void VisitAttribute(AttributeSyntax node)
+ {
+ base.VisitAttribute(node);
+
+ if (node.Name is QualifiedNameSyntax)
+ {
+ var qualifiedName = node.Name as QualifiedNameSyntax;
+ if (!namespacesInQualifiedNames.Any(e => e.ToFullString() == qualifiedName.Left.ToFullString()))
+ {
+ namespacesInQualifiedNames.Add(qualifiedName.Left);
+ }
+ }
+ }
+
+ public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
+ {
+ base.VisitPropertyDeclaration(node);
+
+ ProcessType(node.Type);
+ }
+
+ public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
+ {
+ base.VisitFieldDeclaration(node);
+
+ ProcessType(node.Declaration.Type);
+ }
+
+ public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
+ {
+ base.VisitMethodDeclaration(node);
+
+ ProcessType(node.ReturnType);
+
+ foreach (var arg in node.ParameterList.Parameters)
+ {
+ ProcessType(arg.Type);
+ }
+ }
+
+ private void ProcessType(TypeSyntax type)
+ {
+ var qualifiedNames = new List();
+
+ if (type is IdentifierNameSyntax)
+ {
+ // (type as IdentifierNameSyntax).Identifier
+ }
+ else if (type is ArrayTypeSyntax)
+ {
+ var elementType = (type as ArrayTypeSyntax).ElementType;
+ if (elementType is QualifiedNameSyntax)
+ {
+ qualifiedNames.Add(elementType as QualifiedNameSyntax);
+ }
+ }
+ else if (type is QualifiedNameSyntax)
+ {
+ qualifiedNames.Add(type as QualifiedNameSyntax);
+ }
+
+ foreach (var qualifiedName in qualifiedNames)
+ {
+ if (!namespacesInQualifiedNames.Any(e => e.ToFullString() == qualifiedName.Left.ToFullString()))
+ {
+ namespacesInQualifiedNames.Add(qualifiedName.Left);
+ }
+ }
+ }
+
+ }
+}
diff --git a/DashTools.CodeGenerator/packages.config b/DashTools.CodeGenerator/packages.config
new file mode 100644
index 0000000..bb7ca56
--- /dev/null
+++ b/DashTools.CodeGenerator/packages.config
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DashTools.Samples/Program.cs b/DashTools.Samples/Program.cs
index 73df624..fe443ae 100644
--- a/DashTools.Samples/Program.cs
+++ b/DashTools.Samples/Program.cs
@@ -11,6 +11,16 @@ namespace Qoollo.MpegDash.Samples
{
class Program
{
+ private static readonly string[] mpdFiles = new string[]
+ {
+ "http://ncplusgo.s43-po.live.e56-po.insyscd.net/out/u/eskatvsd.mpd",
+ "http://dash.edgesuite.net/envivio/EnvivioDash3/manifest.mpd",
+ "http://dash.edgesuite.net/dash264/TestCases/1a/netflix/exMPD_BIP_TC1.mpd",
+ "http://10.5.5.7/q/p/userapi/streams/32/mpd",
+ "http://10.5.7.207/userapi/streams/30/mpd",
+ "http://10.5.7.207/userapi/streams/11/mpd?start_time=1458816642&stop_time=1458819642",
+ };
+
static void Main(string[] args)
{
Task.Run(async () =>
@@ -22,11 +32,9 @@ static void Main(string[] args)
static async Task MainAsync(string[] args)
{
string dir = "envivio";
- string mpdUrl = "http://10.5.5.7/q/p/userapi/streams/32/mpd";
- //"http://10.5.7.207/userapi/streams/30/mpd";
- //"http://10.5.7.207/userapi/streams/11/mpd?start_time=1458816642&stop_time=1458819642";
- //"http://dash.edgesuite.net/envivio/EnvivioDash3/manifest.mpd";
- //"http://dash.edgesuite.net/dash264/TestCases/1a/netflix/exMPD_BIP_TC1.mpd";
+ string mpdUrl = mpdFiles[0];
+ var from = TimeSpan.Zero;
+ var to = TimeSpan.MaxValue;
var stopwatch = Stopwatch.StartNew();
var downloader = new MpdDownloader(new Uri(mpdUrl), dir);
@@ -39,7 +47,7 @@ static async Task MainAsync(string[] args)
// ? new Mp4InitFile(Path.Combine("envivio", Path.GetFileName(f)))
// : new Mp4File(Path.Combine("envivio", Path.GetFileName(f))))
// .ToArray();
- await downloader.Download(trackRepresentation, TimeSpan.FromMinutes(60), TimeSpan.FromMinutes(60 + 60 * 6 / 6));
+ await downloader.Download(trackRepresentation, from, to);
var downloadTime = stopwatch.Elapsed - prepareTime;
var ffmpeg = new FFMpegConverter();
diff --git a/DashTools/DashTools.csproj b/DashTools/DashTools.csproj
index e77fcdb..77779c6 100644
--- a/DashTools/DashTools.csproj
+++ b/DashTools/DashTools.csproj
@@ -40,6 +40,8 @@
+
+
@@ -54,16 +56,23 @@
+
+
+
+
+
+
+