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;