2 * string-icalls.c: String internal calls for the corlib
5 * Patrik Torstensson (patrik.torstensson@labs2.com)
6 * Duncan Mak (duncan@ximian.com)
8 * (C) 2001 Ximian, Inc.
15 #include <mono/metadata/string-icalls.h>
16 #include <mono/metadata/class-internals.h>
17 #include <mono/metadata/appdomain.h>
18 #include <mono/metadata/tabledefs.h>
19 #include <mono/metadata/loader.h>
20 #include <mono/metadata/object.h>
21 #include <mono/metadata/exception.h>
22 #include <mono/metadata/debug-helpers.h>
24 /* Internal helper methods */
27 string_icall_is_in_array (MonoArray *chars, gint32 arraylength, gunichar2 chr);
29 /* This function is redirected to String.CreateString ()
30 by mono_marshal_get_native_wrapper () */
32 ves_icall_System_String_ctor_RedirectToCreateString (void)
34 g_assert_not_reached ();
38 ves_icall_System_String_InternalJoin (MonoString *separator, MonoArray * value, gint32 sindex, gint32 count)
53 insert = mono_string_chars(separator);
54 insertlen = mono_string_length(separator);
57 for (pos = sindex; pos != sindex + count; pos++) {
58 current = mono_array_get (value, MonoString *, pos);
60 length += mono_string_length (current);
62 if (pos < sindex + count - 1)
66 ret = mono_string_new_size( mono_domain_get (), length);
67 dest = mono_string_chars(ret);
70 for (pos = sindex; pos != sindex + count; pos++) {
71 current = mono_array_get (value, MonoString *, pos);
72 if (current != NULL) {
73 src = mono_string_chars (current);
74 srclen = mono_string_length (current);
76 memcpy (dest + destpos, src, srclen * sizeof(gunichar2));
80 if (pos < sindex + count - 1) {
81 memcpy(dest + destpos, insert, insertlen * sizeof(gunichar2));
90 ves_icall_System_String_InternalCopyTo (MonoString *me, gint32 sindex, MonoArray *dest, gint32 dindex, gint32 count)
92 gunichar2 *destptr = (gunichar2 *) mono_array_addr(dest, gunichar2, dindex);
93 gunichar2 *src = mono_string_chars(me);
97 memcpy(destptr, src + sindex, sizeof(gunichar2) * count);
101 ves_icall_System_String_InternalSplit (MonoString *me, MonoArray *separator, gint32 count)
106 gint32 arrsize, srcsize, splitsize;
107 gint32 i, lastpos, arrpos;
109 gunichar2 *tmpstrptr;
115 src = mono_string_chars(me);
116 srcsize = mono_string_length(me);
117 arrsize = mono_array_length(separator);
119 cmpchar = mono_array_get(separator, gunichar2, 0);
122 for (i = 0; i != srcsize && splitsize < count; i++) {
123 if (string_icall_is_in_array(separator, arrsize, src[i]))
130 /* if no split chars found return the string */
131 if (splitsize == 0) {
132 retarr = mono_array_new(mono_domain_get(), mono_get_string_class (), 1);
133 mono_array_setref (retarr, 0, me);
138 if (splitsize != count)
141 retarr = mono_array_new(mono_domain_get(), mono_get_string_class (), splitsize);
142 for (i = 0; i != srcsize && arrpos != count; i++) {
143 if (string_icall_is_in_array(separator, arrsize, src[i])) {
144 if (arrpos == count - 1)
145 tmpstrsize = srcsize - lastpos;
147 tmpstrsize = i - lastpos;
149 tmpstr = mono_string_new_size( mono_domain_get (), tmpstrsize);
150 tmpstrptr = mono_string_chars(tmpstr);
152 memcpy(tmpstrptr, src + lastpos, tmpstrsize * sizeof(gunichar2));
153 mono_array_setref (retarr, arrpos, tmpstr);
159 if (arrpos < count) {
160 tmpstrsize = srcsize - lastpos;
161 tmpstr = mono_string_new_size( mono_domain_get (), tmpstrsize);
162 tmpstrptr = mono_string_chars(tmpstr);
164 memcpy(tmpstrptr, src + lastpos, tmpstrsize * sizeof(gunichar2));
165 mono_array_setref (retarr, arrpos, tmpstr);
172 string_icall_is_in_array (MonoArray *chars, gint32 arraylength, gunichar2 chr)
177 for (arrpos = 0; arrpos != arraylength; arrpos++) {
178 cmpchar = mono_array_get(chars, gunichar2, arrpos);
187 ves_icall_System_String_InternalTrim (MonoString *me, MonoArray *chars, gint32 typ)
190 gunichar2 *src, *dest;
191 gint32 srclen, newlen, arrlen;
192 gint32 i, lenfirst, lenlast;
196 srclen = mono_string_length(me);
197 src = mono_string_chars(me);
198 arrlen = mono_array_length(chars);
203 if (0 == typ || 1 == typ) {
204 for (i = 0; i != srclen; i++) {
205 if (string_icall_is_in_array(chars, arrlen, src[i]))
212 if (0 == typ || 2 == typ) {
213 for (i = srclen - 1; i > lenfirst - 1; i--) {
214 if (string_icall_is_in_array(chars, arrlen, src[i]))
221 newlen = srclen - lenfirst - lenlast;
222 if (newlen == srclen)
225 ret = mono_string_new_size( mono_domain_get (), newlen);
226 dest = mono_string_chars(ret);
228 memcpy(dest, src + lenfirst, newlen *sizeof(gunichar2));
234 ves_icall_System_String_InternalLastIndexOfAny (MonoString *me, MonoArray *anyOf, gint32 sindex, gint32 count)
243 arraysize = mono_array_length(anyOf);
244 src = mono_string_chars(me);
246 for (pos = sindex; pos > sindex - count; pos--) {
247 for (loop = 0; loop != arraysize; loop++)
248 if ( src [pos] == mono_array_get(anyOf, gunichar2, loop) )
256 ves_icall_System_String_InternalPad (MonoString *me, gint32 width, gunichar2 chr, MonoBoolean right)
267 srclen = mono_string_length(me);
268 src = mono_string_chars(me);
270 ret = mono_string_new_size( mono_domain_get (), width);
271 dest = mono_string_chars(ret);
272 fillcount = width - srclen;
275 memcpy(dest, src, srclen * sizeof(gunichar2));
276 for (i = srclen; i != width; i++)
283 for (i = 0; i != fillcount; i++)
286 memcpy(dest + fillcount, src, srclen * sizeof(gunichar2));
292 ves_icall_System_String_InternalAllocateStr (gint32 length)
296 return mono_string_new_size(mono_domain_get (), length);
300 ves_icall_System_String_InternalStrcpy_Str (MonoString *dest, gint32 destPos, MonoString *src)
307 srcptr = mono_string_chars (src);
308 destptr = mono_string_chars (dest);
310 g_memmove (destptr + destPos, srcptr, mono_string_length(src) * sizeof(gunichar2));
314 ves_icall_System_String_InternalStrcpy_StrN (MonoString *dest, gint32 destPos, MonoString *src, gint32 startPos, gint32 count)
321 srcptr = mono_string_chars (src);
322 destptr = mono_string_chars (dest);
323 g_memmove (destptr + destPos, srcptr + startPos, count * sizeof(gunichar2));
327 ves_icall_System_String_InternalStrcpy_Chars (MonoString *dest, gint32 destPos, MonoArray *src)
334 srcptr = mono_array_addr (src, gunichar2, 0);
335 destptr = mono_string_chars (dest);
337 g_memmove (destptr + destPos, srcptr, mono_array_length (src) * sizeof(gunichar2));
341 ves_icall_System_String_InternalStrcpy_CharsN (MonoString *dest, gint32 destPos, MonoArray *src, gint32 startPos, gint32 count)
348 srcptr = mono_array_addr (src, gunichar2, 0);
349 destptr = mono_string_chars (dest);
351 g_memmove (destptr + destPos, srcptr + startPos, count * sizeof(gunichar2));
355 ves_icall_System_String_InternalIntern (MonoString *str)
359 return mono_string_intern(str);
363 ves_icall_System_String_InternalIsInterned (MonoString *str)
367 return mono_string_is_interned(str);
371 ves_icall_System_String_get_Chars (MonoString *me, gint32 idx)
375 if ((idx < 0) || (idx >= mono_string_length (me)))
376 mono_raise_exception (mono_get_exception_index_out_of_range ());
377 return mono_string_chars(me)[idx];