Re: [Mono-dev] [Patch] AssemblyName ctor (with corrections)

2005-09-16 Thread Carlos Alberto Cortez
Hey Paolo,

Thanks for the comments.

Carlos.

El mié, 14-09-2005 a las 20:45 +0200, Paolo Molaro escribió:
 On 09/01/05 Carlos Alberto Cortez wrote:
  Index: AssemblyName.cs
  ===
  --- AssemblyName.cs (revisión: 48811)
  +++ AssemblyName.cs (copia de trabajo)
  @@ -37,6 +37,7 @@
   using System.Text;
   using System.Runtime.InteropServices;
   using System.Runtime.CompilerServices;
  +using System.IO;
   
   using Mono.Security;
   
  @@ -80,12 +81,23 @@
  versioncompat = 
  AssemblyVersionCompatibility.SameMachine;
  }
   
  -#if NET_2_0
  +#if NET_2_0 || BOOTSTRAP_NET_2_0
  +   [MethodImpl (MethodImplOptions.InternalCall)]
  +   static extern bool ParseName (AssemblyName aname, string 
  assemblyName);
  +   
  public AssemblyName (string assemblyName)
  {
  -   name = assemblyName;
  +   if (assemblyName == null)
  +   throw new ArgumentNullException 
  (assemblyName);
  +   if (assemblyName.Length  1)
  +   throw new ArgumentException (assemblyName 
  cannot have zero length.);
  +   
  +   if (!ParseName (this, assemblyName))
  +   throw new FileLoadException (The assembly name 
  is invalid.);
 
 Is a FileLoadException really ok? Do you have tests for this?
 
  Index: assembly.c
  ===
  --- assembly.c  (revisión: 48811)
  +++ assembly.c  (copia de trabajo)
  @@ -1171,10 +1171,92 @@
  g_free ((void *) aname-hash_value);
   }
   
  +static gint 
  +to_int32_le (gchar bytes [], gint offset)
  +{
  +   return (bytes [offset+3]  24) | (bytes [offset+2]  16) | (bytes 
  [offset+1]  8) | bytes [offset];
  +}
  +
 
 The function name looks wrong. You should likely use read32() anyway.
 
   static gboolean
  -build_assembly_name (const char *name, const char *version, const char 
  *culture, const char *token, MonoAssemblyName *aname)
  +parse_public_key (const gchar *key, const gchar** pubkey)
   {
 [...]
  +   if (key  strncmp (key, null, 4) != 0) {
  +   if (!parse_public_key (key, (const gchar**) pkey)) {
 
 Why declare parse_public_key() to take a const gchar** when it's not in
 the only place it's called?
 
  +
  +   if (!g_ascii_strncasecmp (value, PublicKey=, 10)) {
  +   key = g_strstrip (value + 10);
 
 Where is key freed?
 
  +   tmp++;
  +   continue;
  +   }
  
  g_strfreev (parts);
  return FALSE;
  }
   
  -   res = build_assembly_name (dllname, version, culture, token, aname);
  +   res = build_assembly_name (dllname, version, culture, token, key, 
  aname, save_public_key);
  g_strfreev (parts);
  return res;
   }
 [...]
  Index: icall.c
  ===
  --- icall.c (revisión: 48811)
  +++ icall.c (copia de trabajo)
  @@ -4152,9 +4152,11 @@
  mono_method_desc_free (desc);
  }
   
  -   args [0] = mono_string_new (domain, name-culture);
  -   aname-cultureInfo = 
  -   mono_runtime_invoke (create_culture, NULL, args, NULL);
  +   if (name-culture) {
  +   args [0] = mono_string_new (domain, name-culture);
  +   aname-cultureInfo = 
  +   mono_runtime_invoke (create_culture, NULL, args, NULL);
 
 Put on the same line.
 
 Thanks.
 Once you'll have fixed the remaining issues, please commit.
 
 lupus
 

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor (yes, again)

2005-08-25 Thread Paolo Molaro
On 08/24/05 Carlos Alberto Cortez wrote:
 The attached patches contain some changes to runtime functions to
 support the new AssemblyName ctor. They also add an internal call for
 this ctor.
 
 I added a pair of new fields to MonoAssemblyName (is_persistent and
 is_version_defined) to define if the public_key was parsed (should be
 freed) or is persistent (image metadata). The second is used for
 avoiding creating the version if it was not defined (I need it to
 mimic .Net behavior).
 
 Comments?
 
 PD - The run rests fine with the patches.

 Index: assembly.c
 ===
 --- assembly.c(revisión: 48811)
 +++ assembly.c(copia de trabajo)
 @@ -449,6 +449,7 @@
  
   mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
  
 + aname-is_persistent = TRUE;
   aname-hash_len = 0;
   aname-hash_value = NULL;
   aname-name = mono_metadata_string_heap (image, cols 
 [MONO_ASSEMBLY_NAME]);
 @@ -458,6 +459,7 @@
   aname-minor = cols [MONO_ASSEMBLY_MINOR_VERSION];
   aname-build = cols [MONO_ASSEMBLY_BUILD_NUMBER];
   aname-revision = cols [MONO_ASSEMBLY_REV_NUMBER];
 + aname-is_version_defined = TRUE;
   aname-hash_alg = cols [MONO_ASSEMBLY_HASH_ALG];
   if (cols [MONO_ASSEMBLY_PUBLIC_KEY]) {
   gchar* token = g_malloc (8);
 @@ -1169,23 +1171,35 @@
   g_free ((void *) aname-name);
   g_free ((void *) aname-culture);
   g_free ((void *) aname-hash_value);
 +
 + if (!aname-is_persistent)
 + g_free ((void *) aname-public_key);
  }
  
  static gboolean
 -build_assembly_name (const char *name, const char *version, const char 
 *culture, const char *token, MonoAssemblyName *aname)
 +build_assembly_name (const char *name, const char *version, const char 
 *culture, const char *token, const char *key, MonoAssemblyName *aname)
  {
   gint major, minor, build, revision;
  
   memset (aname, 0, sizeof (MonoAssemblyName));
  
   if (version) {
 - if (sscanf (version, %u.%u.%u.%u, major, minor, build, 
 revision) != 4)
 + gchar **tmp, **parts = g_strsplit (version, ., 4);
 +
 + tmp = parts;
 + major = *tmp ? atoi (*tmp++) : -1;

Use strtol() for proper error checking.

 + aname-major = (guint16) major;

Why the cast?

 @@ -1197,8 +1211,35 @@
   aname-culture = g_strdup (culture);
   }
   
 - if (token  strncmp (token, null, 4) != 0)
 + if (token  strncmp (token, null, 4) != 0) {
 + if (strlen (token) != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1)
 + return FALSE;
 + 
   g_strlcpy ((char*)aname-public_key_token, token, 
 MONO_PUBLIC_KEY_TOKEN_LENGTH);
 + }
 +
 + if (key  strncmp (key, null, 4) != 0) {
 + gchar *arr, *tok, *encoded;
 + int i, j;
 + 
 + if (strlen (key) != MONO_PUBLIC_KEY_LENGTH)
 + return FALSE;

Can't the length change based on the flags? Sebastien?

 + arr = g_malloc (160);
 + for (i = 0, j = 0; i  160; i++) {
 + arr [i] = g_ascii_xdigit_value (key [j++])  4;
 + arr [i] |= g_ascii_xdigit_value (key [j++]);
 + }
 + aname-public_key = (guint8*) arr;
 + 
 + // We also need to generate the key token
 + tok = g_malloc (8);

Ugh, just alloc it on the stack.

 + mono_digest_get_public_token ((guchar*) tok, aname-public_key, 
 160);
 + encoded = encode_public_tok ((guchar*) tok, 8);
 + g_strlcpy ((char*)aname-public_key_token, encoded, 
 MONO_PUBLIC_KEY_TOKEN_LENGTH);
 + g_free (tok);
 + g_free (encoded);
 + }
   
   return TRUE;
  }
 @@ -1215,7 +1256,7 @@
   return FALSE;
   }
   
 - res = build_assembly_name (name, parts[0], parts[1], parts[2], aname);
 + res = build_assembly_name (name, parts[0], parts[1], parts[2], NULL, 
 aname);
   g_strfreev (parts);
   return res;
  }
 @@ -1236,6 +1277,7 @@
   gchar *version = NULL;
   gchar *culture = NULL;
   gchar *token = NULL;
 + gchar *key = NULL;
   gboolean res;
   gchar *value;
   gchar **parts;
 @@ -1270,12 +1312,18 @@
   tmp++;
   continue;
   }
 +
 + if (!g_ascii_strncasecmp (value, PublicKey=, 10)) {
 + key = g_strstrip (value + 10);
 + tmp++;
 + continue;
 + }
   
   g_strfreev (parts);
   return FALSE;
   }
  
 - res = build_assembly_name (dllname, version, culture, token, aname);
 + res = build_assembly_name (dllname, version, culture, token, key, 
 aname);
   g_strfreev (parts);
   return res;
  }
 Index: image.h
 

Re: [Mono-dev] [Patch] AssemblyName ctor (yes, again)

2005-08-25 Thread Sebastien Pouliot
On Thu, 2005-25-08 at 15:42 +0200, Paolo Molaro wrote:
  @@ -1197,8 +1211,35 @@
  aname-culture = g_strdup (culture);
  }
  
  -   if (token  strncmp (token, null, 4) != 0)
  +   if (token  strncmp (token, null, 4) != 0) {
  +   if (strlen (token) != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1)
  +   return FALSE;
  +   
  g_strlcpy ((char*)aname-public_key_token, token, 
  MONO_PUBLIC_KEY_TOKEN_LENGTH);
  +   }
  +
  +   if (key  strncmp (key, null, 4) != 0) {
  +   gchar *arr, *tok, *encoded;
  +   int i, j;
  +   
  +   if (strlen (key) != MONO_PUBLIC_KEY_LENGTH)
  +   return FALSE;
 
 Can't the length change based on the flags? Sebastien?

The structure is a CryptoAPI blob who's size change only if the key
length change.

However strongnames can now be bigger than 1024 bits (on 2.0). We don't
support that (yet) and we'll have to change some assumptions in the code
to do so. Anyway we better start now...

Note: but this shouldn't affect the public key tokens
-- 
Sebastien

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor (yes, again)

2005-08-25 Thread Carlos Alberto Cortez
 
 This break the ABI: is_version_defined is not needed since you can check
 the fields anyway.
 is_persistent can go away some other way (for example by always having
 public_key allocated, but it would be better to find another which
 doesn't make us waste memory).

No, you can't check the fields. If Version is defined as 0.0.0.0, or
if the user didn't specified version, it happens the same. Then
Version is created for AssemblyName calling the new ctor, even when it
wasn't specified (not compatible with .Net).

However, since it could break api, as you mentioned maybe we should
find other way to do it (and also change the persistent flag).

Carlos.
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-23 Thread Carlos Alberto Cortez
Hey,

I didn't take the choice of using the internal call (unamnaged code)
since I thought it was not optimal (Paolo's told me that was not true).
About the other point, I hadn't thought about it (using the same
function to provide the same behavior for all the possible uses).

So I will be using the internal call and will see if we need changes
there.

Thanks for the reply,
Carlos.



___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-22 Thread Carlos Alberto Cortez
Hey Paolo,

We have mono_assembly_name_parse, which receives a MonoString* and a
MonoAssemblyName*. The problem I find is that every time a
System.Reflection.AssemblyName were created using the described ctor, we
should also create a MonoAssemblyName (not needed).

With the managed ctor, we also avoid calling the internal call.

What do you think?

Carlos.

El sáb, 20-08-2005 a las 12:27 +0200, Paolo Molaro escribió:
 On 08/19/05 Carlos Alberto Cortez wrote:
  The patch attached implements the new AssemblyName ctor without using
  internal calls. Could anybody review it?
 
 And the advantage of this is?
 The runtime needs and does have a function to do the parsing of the
 string, so just use an icall to use that.
 
 lupus
 

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-20 Thread Andreas Nahr

There is a case-insensitive ordinal compare in .Net 2.0 that you should use.
If you use InvariantCulture you get a linguistic comparison based on the 
invariant culture.
However these strings don't look like any natural language text that needs 
natural language processing.
It will also construct the whole ICU4C and possibly ICU libraries, which is 
extremely costly.


I really whish MS would have made two string classes in the first place: 
String and LanguageString


Andreas

- Original Message - 
From: Carlos Alberto Cortez [EMAIL PROTECTED]

To: Andreas Nahr [EMAIL PROTECTED]
Cc: Mono Devel mono-devel-list@lists.ximian.com
Sent: Saturday, August 20, 2005 12:34 AM
Subject: Re: [Mono-dev] [Patch] AssemblyName ctor



Hello again,

comments below:



+ if (String.Compare (parts [i], 0, Version=, 0, 8, true,
CultureInfo.InvariantCulture) == 0)
This is most likely incorrect and needs to use an ordinal comparison, no
InvariantCulture (used more than one time)


I'm not sure that's correct. I tested in .Net and we requiere
insensitive comparison, not ordinal ones (as far I understood). So I
think I'll keep it this way.

Carlos.




___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-19 Thread Ben Maurer
 Hey,

 The patch attached implements the new AssemblyName ctor without using
 internal calls. Could anybody review it?

+int GetCharNumericValue (char c)
+{
+if (c = (char)0x30  c = (char)0x3B)
+return c - 0x30; // 0-9
+if (c = (char)0x61  c = (char)0x66)
+return c - 0x57; // a-f

1) Why not use '0' rather than (char)0x30
2) What about uppercase hex?

+} catch {
+throw new FileLoadException (The
assembly name is invalid.);
+}

It might be helpful to say catch (Exception e) { throw FileLoadException
(..., e) }, so that the developer gets a possibly helpful message.

+for (int i = 0; i  parts.Length; i++) {

foreach (string s in parts);

+  if (String.Compare (parts [i], 0, Version=, 0, 8, true,
CultureInfo.InvariantCulture) == 0)
+version = new Version
(parts [i].Substring (8, parts [i].Length - 8));

If Version= (or any other thing) occurs twice, what happens?

NUnit tests?

-- Ben


___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-19 Thread Carlos Alberto Cortez
Hello again,

comments below:


 + if (String.Compare (parts [i], 0, Version=, 0, 8, true, 
 CultureInfo.InvariantCulture) == 0)
 This is most likely incorrect and needs to use an ordinal comparison, no 
 InvariantCulture (used more than one time)

I'm not sure that's correct. I tested in .Net and we requiere
insensitive comparison, not ordinal ones (as far I understood). So I
think I'll keep it this way.

Carlos.

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


Re: [Mono-dev] [Patch] AssemblyName ctor

2005-08-19 Thread Kornél Pál

Look at this one:
http://msdn2.microsoft.com/library/k13t5kxe(en-us,vs.80).aspx

This is ordinal and case-insensitive all in one. It requires .NET 2.0 but
the constructor is 2.0-only so this is not a problem.

String.Compare with ignore case matches a lot of cases that are considered
equal for linguistic reasons but should not be considered equal for
case-insensitive ordinal comparsion.

Kornél

- Original Message -
From: Carlos Alberto Cortez [EMAIL PROTECTED]
To: Andreas Nahr [EMAIL PROTECTED]
Cc: Mono Devel mono-devel-list@lists.ximian.com
Sent: Saturday, August 20, 2005 12:34 AM
Subject: Re: [Mono-dev] [Patch] AssemblyName ctor



Hello again,

comments below:



+ if (String.Compare (parts [i], 0, Version=, 0, 8, true,
CultureInfo.InvariantCulture) == 0)
This is most likely incorrect and needs to use an ordinal comparison, no
InvariantCulture (used more than one time)


I'm not sure that's correct. I tested in .Net and we requiere
insensitive comparison, not ordinal ones (as far I understood). So I
think I'll keep it this way.

Carlos.

___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list



___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[Mono-dev] [Patch] AssemblyName ctor (fixed)

2005-08-19 Thread Carlos Alberto Cortez
Hey,

The attached patch contains the latest suggestions of both Kornel and
Ben. Maybe the only thing to be noted is that I kept the hexadecimal
notation when comparing chars, since the same is used in
Char.GetNumericalValue ().

New tests are also attached, and run fine under .Net 2.0

Carlos.
Index: AssemblyName.cs
===
--- AssemblyName.cs	(revisión: 48583)
+++ AssemblyName.cs	(copia de trabajo)
@@ -37,6 +37,8 @@
 using System.Text;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
+using System.IO;
+using System.Collections.Generic;
 
 using Mono.Security;
 
@@ -73,7 +75,6 @@
 		int processor_architecture;
 #endif
 #endregion
-		
 		public AssemblyName ()
 		{
 			// defaults
@@ -81,11 +82,102 @@
 		}
 
 #if NET_2_0
+		const string exceptionMessage = The assembly name is invalid.;
+		
 		public AssemblyName (string assemblyName)
 		{
-			name = assemblyName;
+			string [] parts;
+
+			if (assemblyName == null)
+throw new ArgumentNullException (assemblyName);
+			if (assemblyName.Length  1)
+throw new ArgumentException (assemblyName cannot have zero length, assemblyName);
+			
+			parts = assemblyName.Split (',');
+			name = parts [0].Trim ();
+			if (name.Length  1)
+throw new FileLoadException (exceptionMessage);
+
+			IComparerstring comparer = StringComparer.OrdinalIgnoreCase;
+			for (int i = 1; i  parts.Length; i++) {
+if (parts [i].IndexOf ('=')  0)
+	throw new FileLoadException (exceptionMessage);
+
+string [] values = parts [i].Split ('=');
+values [0] = values [0].Trim ();
+values [1] = values [1].Trim ();
+if (values [0].Length  1 || values [1].Length  1)
+	throw new FileLoadException (exceptionMessage);
+
+if (comparer.Compare (values [0], Version) == 0) {
+	if (version != null)
+		throw new FileLoadException (exceptionMessage);
+	try {
+		version = new Version (values [1]);
+	} catch (ArgumentException) {
+		throw new FileLoadException (exceptionMessage);
+	} catch (FormatException) {
+		throw new FileLoadException (exceptionMessage);
+	}
+} else if (comparer.Compare (values [0], Culture) == 0) {
+	if (cultureinfo != null)
+		throw new FileLoadException (exceptionMessage);
+	if (comparer.Compare (values [1], neutral) == 0)
+		values [1] = ;
+	cultureinfo = new CultureInfo (values [1]);
+} else if (comparer.Compare (values [0], PublicKeyToken) == 0) {
+	if (keyToken != null)
+		throw new FileLoadException (exceptionMessage);
+	ParsePublicKeyToken (values [1]);
+} else if (comparer.Compare (values [0], PublicKey) == 0) {
+	if (publicKey != null)
+		throw new FileLoadException (exceptionMessage);
+	ParsePublicKey (values [1]);
+} else
+	throw new FileLoadException (exceptionMessage);
+			}
+			
 		}
 
+		void ParsePublicKeyToken (string kToken)
+		{
+			if (kToken.Length != 16)
+throw new FileLoadException (exceptionMessage);
+
+			keyToken = new byte [8];
+			for (int i = 0, j = 0; i  8; i++) {
+keyToken [i] = (byte) (GetCharNumericValue (kToken [j++])  4);
+keyToken [i] |= (byte) GetCharNumericValue (kToken [j++]);
+			}
+		}
+
+		void ParsePublicKey (string key)
+		{
+			if (key.Length != 320)
+throw new FileLoadException (exceptionMessage);
+			
+			publicKey = new byte [160];
+			for (int i = 0, j = 0; i  160; i++) {
+publicKey [i] = (byte) (GetCharNumericValue (key [j++])  4);
+publicKey [i] |= (byte) GetCharNumericValue (key [j++]);
+			}
+			flags = AssemblyNameFlags.PublicKey;
+		}
+
+		int GetCharNumericValue (char c)
+		{
+			if (c = (char)0x30  c = (char)0x3B)
+return c - 0x30; // 0-9
+			if (c = (char)0x41  c = (char)0x46)
+return c - 0x37; // A-F
+			if (c = (char)0x61  c = (char)0x66)
+return c - 0x57; // a-f
+
+			throw new FileLoadException (exceptionMessage);
+		}
+#endif
+		
+#if NET_2_0
 		[MonoTODO]
 		public ProcessorArchitecture ProcessorArchitecture {
 			get {
Index: AssemblyNameTest.cs
===
--- AssemblyNameTest.cs	(revisión: 48583)
+++ AssemblyNameTest.cs	(copia de trabajo)
@@ -531,6 +531,228 @@
 		}
 		return tokenString;
 	}
+
+#if NET_2_0
+	[Test]
+	public void Ctor1 ()
+	{
+		const string assemblyName = TestAssembly;
+		AssemblyName an = new AssemblyName (assemblyName);
+		Assert.IsNotNull (an.Name, Ctor1#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor1#2);
+	}
+
+	[Test]
+	public void Ctor2 ()
+	{
+		const string assemblyName = TestAssembly;
+		const string assemblyVersion = 1.2.3.4;
+		AssemblyName an = new AssemblyName (assemblyName + , Version= + assemblyVersion);
+		Assert.IsNotNull (an.Name, Ctor2#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor2#2);
+		Assert.IsNotNull (an.Version, Ctor2#3);
+		Assert.AreEqual (an.Version, new Version (assemblyVersion), Ctor2#4);
+	}
+
+	[Test]
+	public void Ctor3 ()
+	{
+		const 

Re: [Mono-dev] [Patch] AssemblyName ctor (correction)

2005-08-12 Thread Paolo Molaro
On 08/09/05 Carlos Alberto Cortez wrote:
 +static void
 +ves_icall_System_Reflection_AssemblyName_InternalParseKeyToken 
 (MonoReflectionAssemblyName *aname, MonoString *key_token)
 +{
 + char *p, *token;
 + int i, j;
 +
 + token = mono_string_to_utf8 (key_token);
 + aname-keyToken = mono_array_new (mono_domain_get (), 
 mono_defaults.byte_class, 8);
 + p = mono_array_addr (aname-keyToken, char, 0);
 + for (i = 0, j = 0; i  8; i++) {
 + *p = g_ascii_xdigit_value (token [j++])  4;
 + *p |= g_ascii_xdigit_value (token [j++]);
 + p++;
 + }
 +
 + g_free (token);

I see no need to implement either of the two methods as internal calls.
Use C# code.

lupus

-- 
-
[EMAIL PROTECTED] debian/rules
[EMAIL PROTECTED] Monkeys do it better
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[Mono-dev] [Patch] AssemblyName ctor

2005-08-09 Thread Carlos Alberto Cortez
hey,

Currently the AssemblyName (string) ctor is not implemented to receive
the long format assembly name (such MyAssembly, Version=1.2,...). The
attached patch adds support for it.

Some tests are also attached.

Carlos.
Index: icall.c
===
--- icall.c	(revisión: 48211)
+++ icall.c	(copia de trabajo)
@@ -3730,6 +3730,44 @@
 	return result;
 }
 
+static void
+ves_icall_System_Reflection_AssemblyName_InternalParseKeyToken (MonoReflectionAssemblyName *aname, MonoString *key_token)
+{
+	char *p, *token;
+	int i, j;
+
+	token = mono_string_to_utf8 (key_token);
+	aname-keyToken = mono_array_new (mono_domain_get (), mono_defaults.byte_class, 8);
+	p = mono_array_addr (aname-keyToken, char, 0);
+	for (i = 0, j = 0; i  8; i++) {
+		*p = g_ascii_xdigit_value (token [j++])  4;
+		*p |= g_ascii_xdigit_value (token [j++]);
+		p++;
+	}
+
+	g_free (token);
+}
+
+static void
+ves_icall_System_Reflection_AssemblyName_InternalParseKey (MonoReflectionAssemblyName *aname, MonoString *public_key)
+{
+	char *p, *key;
+	int pkey_len, i, j;
+
+	key = mono_string_to_utf8 (public_key);
+	pkey_len = mono_string_length (public_key) / 2; // Format used in .Net
+
+	aname-publicKey = mono_array_new (mono_domain_get (), mono_defaults.byte_class, pkey_len);
+	p = mono_array_addr (aname-publicKey, char, 0);
+	for (i = 0, j = 0; i  pkey_len; i++) {
+		*p = g_ascii_xdigit_value (key [j++])  4;
+		*p |= g_ascii_xdigit_value (key [j++]);
+		p++;
+	}
+
+	g_free (key);
+}
+
 typedef struct {
 	MonoArray *res;
 	int idx;
@@ -6510,6 +6548,11 @@
 	{load_with_partial_name, ves_icall_System_Reflection_Assembly_load_with_partial_name}
 };
 
+static const IcallEntry assembly_name_icalls [] = {
+	{InternalParseKey, ves_icall_System_Reflection_AssemblyName_InternalParseKey},
+	{InternalParseKeyToken, ves_icall_System_Reflection_AssemblyName_InternalParseKeyToken}
+};
+
 static const IcallEntry methodbase_icalls [] = {
 	{GetCurrentMethod, ves_icall_GetCurrentMethod},
 	{GetMethodBodyInternal, ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal},
@@ -7046,6 +7089,7 @@
 	{System.Net.Sockets.SocketException, socketex_icalls, G_N_ELEMENTS (socketex_icalls)},
 	{System.Object, object_icalls, G_N_ELEMENTS (object_icalls)},
 	{System.Reflection.Assembly, assembly_icalls, G_N_ELEMENTS (assembly_icalls)},
+	{System.Reflection.AssemblyName, assembly_name_icalls, G_N_ELEMENTS (assembly_name_icalls)},
 	{System.Reflection.Emit.AssemblyBuilder, assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
 	{System.Reflection.Emit.CustomAttributeBuilder, customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
 	{System.Reflection.Emit.DynamicMethod, dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
___
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[Mono-dev] [Patch] AssemblyName ctor (correction)

2005-08-09 Thread Carlos Alberto Cortez
In the last message some attachments were missing. 
All of them are now correctly attached.
Index: AssemblyName.cs
===
--- AssemblyName.cs	(revisión: 48211)
+++ AssemblyName.cs	(copia de trabajo)
@@ -37,6 +37,7 @@
 using System.Text;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
+using System.IO;
 
 using Mono.Security;
 
@@ -73,6 +74,7 @@
 		int processor_architecture;
 #endif
 #endregion
+		static readonly char [] delimiter = {','};
 		
 		public AssemblyName ()
 		{
@@ -83,9 +85,64 @@
 #if NET_2_0
 		public AssemblyName (string assemblyName)
 		{
-			name = assemblyName;
+			string [] parts;
+
+			if (assemblyName == null)
+throw new ArgumentNullException (assemblyName);
+			if (assemblyName == )
+throw new ArgumentException (assemblyName cannot have zero length, assemblyName);
+			
+			// Remove white spaces, to mimic .Net behavior
+			assemblyName = assemblyName.Replace ( , );
+			parts = assemblyName.Split (delimiter);
+			if (parts [0] == )
+throw new FileLoadException (The assembly name is invalid.);
+
+			name = parts [0];
+			for (int i = 0; i  parts.Length; i++) {
+try {
+	if (String.Compare (parts [i], 0, Version=, 0, 8, true, CultureInfo.InvariantCulture) == 0)
+		version = new Version (parts [i].Substring (8, parts [i].Length - 8));
+	else if (String.Compare (parts [i], 0, Culture=, 0, 8, true, CultureInfo.InvariantCulture) == 0) {
+		string culture = parts [i].Substring (8, parts [i].Length - 8);
+		if (String.Compare (culture, neutral, true, CultureInfo.InvariantCulture) == 0)
+			culture = ;
+		cultureinfo = new CultureInfo (culture);
+	}
+	else if (String.Compare (parts [i], 0, PublicKeyToken=, 0, 15, true, CultureInfo.InvariantCulture) == 0)
+		ParseKeyToken (parts [i].Substring (15, parts [i].Length - 15));
+	else if (String.Compare (parts [i], 0, PublicKey=, 0, 10, true, CultureInfo.InvariantCulture) == 0)
+		ParseKey (parts [i].Substring (10, parts [i].Length - 10));
+} catch {
+	throw new FileLoadException (The assembly name is invalid.);
+}
+			}
+			
 		}
 
+		[MethodImpl (MethodImplOptions.InternalCall)]
+		extern void InternalParseKeyToken (string keyToken);
+		
+		void ParseKeyToken (string kToken)
+		{
+			if (kToken.Length != 16)
+throw new Exception ();
+
+			InternalParseKeyToken (kToken);
+		}
+
+		[MethodImpl (MethodImplOptions.InternalCall)]
+		extern void InternalParseKey (string key);
+		
+		void ParseKey (string key)
+		{
+			if (key.Length != 320)
+throw new Exception ();
+			
+			flags = AssemblyNameFlags.PublicKey;
+			InternalParseKey (key);
+		}
+
 		[MonoTODO]
 		public ProcessorArchitecture ProcessorArchitecture {
 			get {
Index: AssemblyNameTest.cs
===
--- AssemblyNameTest.cs	(revisión: 48211)
+++ AssemblyNameTest.cs	(copia de trabajo)
@@ -19,6 +19,7 @@
 using System.Globalization;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.Security;
+using System.Text;
 
 namespace MonoTests.System.Reflection {
 
@@ -531,6 +532,73 @@
 		}
 		return tokenString;
 	}
+
+#if NET_2_0
+	[Test]
+	public void Ctor1 ()
+	{
+		const string assemblyName = TestAssembly;
+		AssemblyName an = new AssemblyName (assemblyName);
+		Assert.IsNotNull (an.Name, Ctor1#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor1#2);
+	}
+
+	[Test]
+	public void Ctor2 ()
+	{
+		const string assemblyName = TestAssembly;
+		const string assemblyVersion = 1.2;
+		AssemblyName an = new AssemblyName (assemblyName + , Version= + assemblyVersion);
+		Assert.IsNotNull (an.Name, Ctor2#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor2#2);
+		Assert.IsNotNull (an.Version, Ctor2#3);
+		Assert.AreEqual (an.Version, new Version (assemblyVersion), Ctor2#4);
+	}
+
+	[Test]
+	public void Ctor3 ()
+	{
+		const string assemblyName = TestAssembly;
+		const string assemblyCulture = en-US;
+		AssemblyName an = new AssemblyName (assemblyName + , Culture= + assemblyCulture);
+		Assert.IsNotNull (an.Name, Ctor3#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor3#2);
+		Assert.IsNotNull (an.CultureInfo, Ctor3#3);
+		Assert.AreEqual (an.CultureInfo, new CultureInfo (assemblyCulture), Ctor3#4);
+	}
+
+	[Test]
+	public void Ctor4 ()
+	{
+		const string assemblyName = TestAssembly;
+		byte [] assemblyKeyToken;
+		AssemblyName an = new AssemblyName (assemblyName + , PublicKeyToken= + GetTokenString (token));
+		Assert.IsNotNull (an.Name, Ctor4#1);
+		Assert.AreEqual (an.Name, assemblyName, Ctor4#2);
+		Assert.IsNotNull (assemblyKeyToken = an.GetPublicKeyToken (), Ctor4#3);
+		Assert.AreEqual (assemblyKeyToken, token, Ctor4#4);
+	}
+
+	[Test]
+	public void Ctor5 ()
+	{
+		const string assemblyName = TestAssembly;
+		const string assemblyCulture = neutral;
+		const string assemblyVersion = 1.2.3.4;
+		byte [] assemblyKeyToken;
+
+		AssemblyName an = new