> On Sun, 2002-04-21 at 11:40, Duncan Mak wrote: > > > > Yeah, I'm working on these. I should be done soon. > > > > Attached is a patch for the 4 missing string constructors in > string-icall.c > > /* unsafe public String (char *value); */ > MonoString * > mono_string_Internal_ctor_charp (gpointer dummy, gunichar2 *value) > > /* unsafe public String (char *value, int startIndex, int length); */ > MonoString * > mono_string_Internal_ctor_charp_int_int (gpointer dummy, gunichar2 > *value, gint32 sindex, gint32 length) > > /* unsafe public String (sbyte *value); */ > MonoString * > mono_string_Internal_ctor_sbytep (gpointer dummy, gint8 *value) > > /* unsafe public String (sbyte *value, int startIndex, int length); */ > MonoString * > mono_string_Internal_ctor_sbytep_int_int (gpointer dummy, gint8 *value, > gint32 sindex, gint32 length) > > I took Dietmar's advice and simply looked at the original C# > implementation of the constructors and translated them into the C > equivalent. > > The only testing I did is to try and build them, and they built. > > I'm not an experienced C programmer, so please tell me if there is > anything wrong with the patch and I'll fix them ASAP. > > Also, Dietmar also told me to go thru the new string code and > standardize the naming of the types -- ie, gunichar2 * and guint16 * are > used interchangably right now. I'll go in and change them tomorrow > afternoon. I'll be using mono/mono/docs/internal-call as my guide. > > Duncan.> ----
>
> Index: mono/metadata/string-icalls.c
> ===================================================================
> RCS file: /cvs/public/mono/mono/metadata/string-icalls.c,v
> retrieving revision 1.4
> diff -u -b -r1.4 string-icalls.c
> --- mono/metadata/string-icalls.c 20 Apr 2002 13:49:34 -0000 1.4
> +++ mono/metadata/string-icalls.c 22 Apr 2002 01:33:03 -0000
> @@ -22,10 +22,20 @@
> MonoString *
> mono_string_Internal_ctor_charp (gpointer dummy, gunichar2 *value)
> {
> - MONO_CHECK_ARG_NULL (value);
> + int i, length;
> + MonoDomain *domain = mono_domain_get ();
> + MonoString *res;
> +
> + if (value == NULL)
> + length = 0;
> + else {
> + for (i = 0; *(value + i) != '\0'; i++);
> + length = i;
> + }
> +
> + res = mono_string_new_utf16 (domain, value, length);
>
> - g_assert_not_reached ();
> - return NULL;
> + return res;
> }
>
> MonoString *
> @@ -47,28 +57,58 @@
> MonoString *
> mono_string_Internal_ctor_charp_int_int (gpointer dummy, gunichar2 *value, gint32 sindex, gint32 length)
> {
> - MONO_CHECK_ARG_NULL (value);
> + MonoString *res;
> + gunichar2 *begin;
> + MonoDomain * domain = mono_domain_get ();
> +
> + if ((value == NULL) && (sindex != 0) && (length != 0))
why do we need a check for sindex != 0 here?
> + mono_raise_exception (mono_get_exception_argument_null ("Argument null"));
>
> - g_assert_not_reached ();
> - return NULL;
> + if ((sindex < 0) || (length < 0))
> + mono_raise_exception (mono_get_exception_argument_out_of_range ("Out of range"));
> +
> + begin = (gunichar2 *) (value + sindex);
> +
> + res = mono_string_new_utf16 (domain, begin, length);
what happens when value == NULL (lenght == 0). We should return String.Empty?
> +
> + return res;
> }
>
> MonoString *
> mono_string_Internal_ctor_sbytep (gpointer dummy, gint8 *value)
> {
> - MONO_CHECK_ARG_NULL (value);
> + int i, length;
> + MonoString *res;
> + MonoDomain *domain = mono_domain_get ();
> +
> + if (value == NULL)
> + length = 0;
> + else {
> + for (i = 0; *(value + i) != '\0'; i++);
> + length = i;
> + }
>
> - g_assert_not_reached ();
> - return NULL;
> + res = mono_string_new_utf16 (domain, (gunichar2 *) value, length);
value is not a utf16 String, instead it is utf8 (AFAIK). So we need to call mono_string_new (). I value is null we must return String.Empty (but thats not trivial to implement - simply add a fixme/g_assert_not_reached())
> +
> + return res;
> }
>
> MonoString *
> mono_string_Internal_ctor_sbytep_int_int (gpointer dummy, gint8 *value, gint32 sindex, gint32 length)
> {
> - MONO_CHECK_ARG_NULL (value);
> + MonoString *res;
> + gunichar2 *begin;
> + MonoDomain *domain = mono_domain_get ();
> +
> + if ((value == NULL) && (sindex != 0) && (length != 0))
> + mono_raise_exception (mono_get_exception_argument_null ("Argument null"));
> +
> + if ((sindex > 0) || (length < 0))
> + mono_raise_exception (mono_get_exception_argument_out_of_range ("Out of range"));
> +
> + begin = (gunichar2 *) (value + sindex);
>
> - g_assert_not_reached ();
> - return NULL;
> + res = mono_string_new_utf16 (domain, begin, length);
same as above - its not an utf16 String AFAIK. Please can you check that in the docs?
- Dietmar
