1 //
2 // Author:
3 //   Jb Evain (jbevain@gmail.com)
4 //
5 // Copyright (c) 2008 - 2015 Jb Evain
6 // Copyright (c) 2008 - 2011 Novell, Inc.
7 //
8 // Licensed under the MIT/X11 license.
9 //
10 
11 using System;
12 using System.IO;
13 
14 using Mono.Cecil.Cil;
15 
16 namespace Mono.Cecil.Pdb {
17 
18 	public sealed class NativePdbReaderProvider : ISymbolReaderProvider {
19 
GetSymbolReader(ModuleDefinition module, string fileName)20 		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
21 		{
22 			Mixin.CheckModule (module);
23 			Mixin.CheckFileName (fileName);
24 
25 			return new NativePdbReader (Disposable.Owned (File.OpenRead (Mixin.GetPdbFileName (fileName)) as Stream));
26 		}
27 
GetSymbolReader(ModuleDefinition module, Stream symbolStream)28 		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
29 		{
30 			Mixin.CheckModule (module);
31 			Mixin.CheckStream (symbolStream);
32 
33 			return new NativePdbReader (Disposable.NotOwned (symbolStream));
34 		}
35 	}
36 
37 	public sealed class PdbReaderProvider : ISymbolReaderProvider {
38 
GetSymbolReader(ModuleDefinition module, string fileName)39 		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
40 		{
41 			Mixin.CheckModule (module);
42 			Mixin.CheckFileName (fileName);
43 
44 			if (module.HasDebugHeader) {
45 				var header = module.GetDebugHeader ();
46 				var entry = header.GetEmbeddedPortablePdbEntry ();
47 				if (entry != null)
48 					return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName);
49 			}
50 
51 			return Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName))
52 				? new PortablePdbReaderProvider ().GetSymbolReader (module, fileName)
53 				: new NativePdbReaderProvider ().GetSymbolReader (module, fileName);
54 		}
55 
GetSymbolReader(ModuleDefinition module, Stream symbolStream)56 		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
57 		{
58 			Mixin.CheckModule (module);
59 			Mixin.CheckStream (symbolStream);
60 			Mixin.CheckReadSeek (symbolStream);
61 
62 			return Mixin.IsPortablePdb (symbolStream)
63 				? new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream)
64 				: new NativePdbReaderProvider ().GetSymbolReader (module, symbolStream);
65 		}
66 	}
67 
68 #if !READ_ONLY
69 
70 	public sealed class NativePdbWriterProvider : ISymbolWriterProvider {
71 
GetSymbolWriter(ModuleDefinition module, string fileName)72 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
73 		{
74 			Mixin.CheckModule (module);
75 			Mixin.CheckFileName (fileName);
76 
77 			return new NativePdbWriter (module, CreateWriter (module, Mixin.GetPdbFileName (fileName)));
78 		}
79 
CreateWriter(ModuleDefinition module, string pdb)80 		static SymWriter CreateWriter (ModuleDefinition module, string pdb)
81 		{
82 			var writer = new SymWriter ();
83 
84 			if (File.Exists (pdb))
85 				File.Delete (pdb);
86 
87 			writer.Initialize (new ModuleMetadata (module), pdb, true);
88 
89 			return writer;
90 		}
91 
GetSymbolWriter(ModuleDefinition module, Stream symbolStream)92 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
93 		{
94 			throw new NotImplementedException ();
95 		}
96 	}
97 
98 	public sealed class PdbWriterProvider : ISymbolWriterProvider {
99 
GetSymbolWriter(ModuleDefinition module, string fileName)100 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
101 		{
102 			Mixin.CheckModule (module);
103 			Mixin.CheckFileName (fileName);
104 
105 			if (HasPortablePdbSymbols (module))
106 				return new PortablePdbWriterProvider ().GetSymbolWriter (module, fileName);
107 
108 			return new NativePdbWriterProvider ().GetSymbolWriter (module, fileName);
109 		}
110 
HasPortablePdbSymbols(ModuleDefinition module)111 		static bool HasPortablePdbSymbols (ModuleDefinition module)
112 		{
113 			return module.symbol_reader != null && module.symbol_reader is PortablePdbReader;
114 		}
115 
GetSymbolWriter(ModuleDefinition module, Stream symbolStream)116 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
117 		{
118 			Mixin.CheckModule (module);
119 			Mixin.CheckStream (symbolStream);
120 			Mixin.CheckReadSeek (symbolStream);
121 
122 			if (HasPortablePdbSymbols (module))
123 				return new PortablePdbWriterProvider ().GetSymbolWriter (module, symbolStream);
124 
125 			return new NativePdbWriterProvider ().GetSymbolWriter (module, symbolStream);
126 		}
127 	}
128 
129 #endif
130 }
131