2
// AssemblyNameReference.cs
5
// Jb Evain (jbevain@gmail.com)
7
// Copyright (c) 2008 - 2010 Jb Evain
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
using System.Globalization;
31
using System.Security.Cryptography;
34
namespace Mono.Cecil {
36
public class AssemblyNameReference : IMetadataScope {
43
byte [] public_key_token;
44
AssemblyHashAlgorithm hash_algorithm;
47
internal MetadataToken token;
59
public string Culture {
60
get { return culture; }
67
public Version Version {
68
get { return version; }
75
public AssemblyAttributes Attributes {
76
get { return (AssemblyAttributes) attributes; }
77
set { attributes = (uint) value; }
80
public bool HasPublicKey {
81
get { return attributes.GetAttributes ((uint) AssemblyAttributes.PublicKey); }
82
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.PublicKey, value); }
85
public bool IsSideBySideCompatible {
86
get { return attributes.GetAttributes ((uint) AssemblyAttributes.SideBySideCompatible); }
87
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.SideBySideCompatible, value); }
90
public bool IsRetargetable {
91
get { return attributes.GetAttributes ((uint) AssemblyAttributes.Retargetable); }
92
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.Retargetable, value); }
95
public byte [] PublicKey {
96
get { return public_key; }
99
HasPublicKey = !public_key.IsNullOrEmpty ();
100
public_key_token = Empty<byte>.Array;
105
public byte [] PublicKeyToken {
107
if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) {
108
var hash = HashPublicKey ();
109
// we need the last 8 bytes in reverse order
110
public_key_token = new byte [8];
111
Array.Copy (hash, (hash.Length - 8), public_key_token, 0, 8);
112
Array.Reverse (public_key_token, 0, 8);
114
return public_key_token;
117
public_key_token = value;
122
byte [] HashPublicKey ()
124
HashAlgorithm algorithm;
126
switch (hash_algorithm) {
127
case AssemblyHashAlgorithm.Reserved:
129
throw new NotSupportedException ();
131
algorithm = MD5.Create ();
135
// None default to SHA1
137
algorithm = new SHA1Managed ();
140
algorithm = SHA1.Create ();
146
return algorithm.ComputeHash (public_key);
149
public virtual MetadataScopeType MetadataScopeType {
150
get { return MetadataScopeType.AssemblyNameReference; }
153
public string FullName {
155
if (full_name != null)
158
const string sep = ", ";
160
var builder = new StringBuilder ();
161
builder.Append (name);
162
if (version != null) {
163
builder.Append (sep);
164
builder.Append ("Version=");
165
builder.Append (version.ToString ());
167
builder.Append (sep);
168
builder.Append ("Culture=");
169
builder.Append (string.IsNullOrEmpty (culture) ? "neutral" : culture);
170
builder.Append (sep);
171
builder.Append ("PublicKeyToken=");
173
if (this.PublicKeyToken != null && public_key_token.Length > 0) {
174
for (int i = 0 ; i < public_key_token.Length ; i++) {
175
builder.Append (public_key_token [i].ToString ("x2"));
178
builder.Append ("null");
180
return full_name = builder.ToString ();
184
public static AssemblyNameReference Parse (string fullName)
186
if (fullName == null)
187
throw new ArgumentNullException ("fullName");
188
if (fullName.Length == 0)
189
throw new ArgumentException ("Name can not be empty");
191
var name = new AssemblyNameReference ();
192
var tokens = fullName.Split (',');
193
for (int i = 0; i < tokens.Length; i++) {
194
var token = tokens [i].Trim ();
201
var parts = token.Split ('=');
202
if (parts.Length != 2)
203
throw new ArgumentException ("Malformed name");
207
name.Version = new Version (parts [1]);
210
name.Culture = parts [1];
212
case "PublicKeyToken":
213
string pk_token = parts [1];
214
if (pk_token == "null")
217
name.PublicKeyToken = new byte [pk_token.Length / 2];
218
for (int j = 0; j < name.PublicKeyToken.Length; j++) {
219
name.PublicKeyToken [j] = Byte.Parse (pk_token.Substring (j * 2, 2), NumberStyles.HexNumber);
228
public AssemblyHashAlgorithm HashAlgorithm {
229
get { return hash_algorithm; }
230
set { hash_algorithm = value; }
233
public virtual byte [] Hash {
235
set { hash = value; }
238
public MetadataToken MetadataToken {
239
get { return token; }
240
set { token = value; }
243
internal AssemblyNameReference ()
247
public AssemblyNameReference (string name, Version version)
250
throw new ArgumentNullException ("name");
253
this.version = version;
254
this.hash_algorithm = AssemblyHashAlgorithm.None;
255
this.token = new MetadataToken (TokenType.AssemblyRef);
258
public override string ToString ()
260
return this.FullName;