2004-02-17 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / class / corlib / System.Reflection / AssemblyName.cs
1 //
2 // System.Reflection/AssemblyName.cs
3 //
4 // Authors:
5 //      Paolo Molaro (lupus@ximian.com)
6 //      Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
10 //
11
12 using System;
13 using System.Configuration.Assemblies;
14 using System.Globalization;
15 using System.Reflection;
16 using System.Runtime.Serialization;
17 using System.Security.Cryptography;
18 using System.Text;
19 using System.Runtime.InteropServices;
20 using System.Runtime.CompilerServices;
21
22 namespace System.Reflection {
23
24 // References:
25 // a.   Uniform Resource Identifiers (URI): Generic Syntax
26 //      http://www.ietf.org/rfc/rfc2396.txt
27
28         [Serializable]
29         public sealed class AssemblyName  : ICloneable, ISerializable, IDeserializationCallback {
30                 string name;
31                 string codebase;
32                 int major, minor, build, revision;
33                 CultureInfo cultureinfo;
34                 AssemblyNameFlags flags;
35                 AssemblyHashAlgorithm hashalg;
36                 StrongNameKeyPair keypair;
37                 byte[] publicKey;
38                 byte[] keyToken;
39                 AssemblyVersionCompatibility versioncompat;
40                 
41                 public AssemblyName ()
42                 {
43                         // defaults
44                         versioncompat = AssemblyVersionCompatibility.SameMachine;
45                 }
46
47                 internal AssemblyName (SerializationInfo si, StreamingContext sc)
48                 {
49                         name = si.GetString ("_Name");
50                         codebase = si.GetString ("_CodeBase");
51                         Version = (Version)si.GetValue ("_Version", typeof (Version));
52                 }
53
54                 public string Name {
55                         get { return name; }
56                         set { name = value; }
57                 }
58
59                 public string CodeBase {
60                         get { return codebase; }
61                         set { codebase = value; }
62                 }
63
64                 [MonoTODO("RFC 2396")]
65                 private string Escape (string url) 
66                 {
67                         // we already have code in mcs\class\System\System\Uri.cs
68                         // but Uri class ins't part of corlib !
69                         // TODO
70                         return url;
71                 }
72
73                 public string EscapedCodeBase {
74                         get { return Escape (codebase); }
75                 }
76
77                 public CultureInfo CultureInfo {
78                         get { return cultureinfo; }
79                         set { cultureinfo = value; }
80                 }
81
82                 public AssemblyNameFlags Flags {
83                         get { return flags; }
84                         set { flags = value; }
85                 }
86
87                 [MonoTODO("incomplete")]
88                 public string FullName {
89                         get {
90                                 if (name == null)
91                                         return null;
92                                 StringBuilder fname = new StringBuilder ();
93                                 fname.Append (name);
94                                 fname.Append (", Version=");
95                                 fname.Append (Version.ToString ());
96                                 fname.Append (", Culture=");
97                                 if ((cultureinfo == null) || (cultureinfo.LCID == CultureInfo.InvariantCulture.LCID))
98                                         fname.Append ("neutral");
99                                 else
100                                         fname.Append (cultureinfo.ToString ()); // ???
101                                 byte[] pub_tok = GetPublicKeyToken ();
102                                 if (pub_tok == null || pub_tok.Length == 0)
103                                         fname.Append (", PublicKeyToken=null");
104                                 else {
105                                         fname.Append (", PublicKeyToken=");
106                                         for (int i = 0; i < pub_tok.Length; i++)
107                                                 fname.Append (pub_tok[i].ToString ("x2"));
108                                 }
109                                 // TODO
110                                 return fname.ToString ();
111                         }
112                 }
113
114                 public AssemblyHashAlgorithm HashAlgorithm {
115                         get { return hashalg; }
116                         set { hashalg = value; }
117                 }
118
119                 public StrongNameKeyPair KeyPair {
120                         get { return keypair; }
121                         set { keypair = value; }
122                 }
123
124                 public Version Version {
125                         get {
126                                 if (name == null)
127                                         return null;
128                                 if (build == -1)
129                                         return new Version (major, minor);
130                                 else
131                                         if (revision == -1)
132                                                 return new Version (major, minor, build);
133                                 else
134                                         return new Version (major, minor, build, revision);
135                         }
136
137                         set {
138                                 major = value.Major;
139                                 minor = value.Minor;
140                                 build = value.Build;
141                                 revision = value.Revision;
142                         }
143                 }
144
145                 public AssemblyVersionCompatibility VersionCompatibility {
146                         get { return versioncompat; }
147                         set { versioncompat = value; }
148                 }
149                 
150                 public override string ToString ()
151                 {
152                         string name = FullName;
153                         return (name != null) ? name : base.ToString ();
154                 }
155
156                 public byte[] GetPublicKey() 
157                 {
158                         // to match MS implementation -- funny one
159                         if (publicKey != null)
160                                 return publicKey;
161                         else if (name == null)
162                                 return null;
163                         else
164                                 return new byte [0];
165                 }
166
167                 public byte[] GetPublicKeyToken() 
168                 {
169                         if (keyToken != null)
170                                 return keyToken;
171                         else if (publicKey == null)
172                                 return null;
173                         else {
174                                 HashAlgorithm ha = null;
175                                 switch (hashalg) {
176                                         case AssemblyHashAlgorithm.MD5:
177                                                 ha = MD5.Create ();
178                                                 break;
179                                         default:
180                                                 // None default to SHA1
181                                                 ha = SHA1.Create ();
182                                                 break;
183                                 }
184                                 byte[] hash = ha.ComputeHash (publicKey);
185                                 // we need the last 8 bytes in reverse order
186                                 keyToken = new byte [8];
187                                 Array.Copy (hash, (hash.Length - 8), keyToken, 0, 8);
188                                 Array.Reverse (keyToken, 0, 8);
189                                 return keyToken;
190                         }
191                 }
192
193                 public void SetPublicKey (byte[] publicKey) 
194                 {
195                         flags = AssemblyNameFlags.PublicKey;
196                         this.publicKey = publicKey;
197                 }
198
199                 public void SetPublicKeyToken (byte[] publicKeyToken) 
200                 {
201                         keyToken = publicKeyToken;
202                 }
203
204                 public void GetObjectData (SerializationInfo info, StreamingContext context)
205                 {
206                         info.AddValue ("_Name", name);
207                         info.AddValue ("_CodeBase", codebase);
208                         info.AddValue ("_Version", Version);
209                 }
210
211                 // required to implement ICloneable
212                 [MonoTODO()]
213                 public object Clone() 
214                 {
215                         return null;
216                 }
217
218                 // required to implement IDeserializationCallback
219                 [MonoTODO()]
220                 public void OnDeserialization (object sender) 
221                 {
222                 }
223
224                 public static AssemblyName GetAssemblyName (string assemblyFile) 
225                 {
226                         if (assemblyFile == null)
227                                 throw new ArgumentNullException ("assemblyFile");
228
229                         AssemblyName aname = new AssemblyName ();
230                         Assembly.InternalGetAssemblyName (assemblyFile, aname);
231                         return aname;
232                 }
233         }
234 }