+ internal unsafe int GetCaseInsensitiveHashCode ()
+ {
+ fixed (char * c = this) {
+ char * cc = c;
+ char * end = cc + length - 1;
+ int h = 0;
+ for (;cc < end; cc += 2) {
+ h = (h << 5) - h + Char.ToUpperInvariant (*cc);
+ h = (h << 5) - h + Char.ToUpperInvariant (cc [1]);
+ }
+ ++end;
+ if (cc < end)
+ h = (h << 5) - h + Char.ToUpperInvariant (*cc);
+ return h;
+ }
+ }
+
+ // Certain constructors are redirected to CreateString methods with
+ // matching argument list. The this pointer should not be used.
+#pragma warning disable 169
+ private unsafe String CreateString (sbyte* value)
+ {
+ if (value == null)
+ return String.Empty;
+
+ byte* bytes = (byte*) value;
+ int length = 0;
+
+ try {
+ while (bytes++ [0] != 0)
+ length++;
+ } catch (NullReferenceException) {
+ throw new ArgumentOutOfRangeException ("ptr", "Value does not refer to a valid string.");
+#if NET_2_0
+ } catch (AccessViolationException) {
+ throw new ArgumentOutOfRangeException ("ptr", "Value does not refer to a valid string.");
+#endif
+ }
+
+ return CreateString (value, 0, length, null);
+ }
+
+ private unsafe String CreateString (sbyte* value, int startIndex, int length)
+ {
+ return CreateString (value, startIndex, length, null);
+ }
+
+ private unsafe String CreateString (sbyte* value, int startIndex, int length, Encoding enc)
+ {
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length", "Non-negative number required.");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex", "Non-negative number required.");
+ if (value + startIndex < value)
+ throw new ArgumentOutOfRangeException ("startIndex", "Value, startIndex and length do not refer to a valid string.");
+
+ bool isDefaultEncoding;
+
+ if (isDefaultEncoding = (enc == null)) {
+#if NET_2_0
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ if (length == 0)
+#else
+ if (value == null || length == 0)
+#endif
+ return String.Empty;
+
+ enc = Encoding.Default;
+ }
+
+ byte [] bytes = new byte [length];
+
+ if (length != 0)
+ fixed (byte* bytePtr = bytes)
+ try {
+ memcpy (bytePtr, (byte*) (value + startIndex), length);
+ } catch (NullReferenceException) {
+#if !NET_2_0
+ if (!isDefaultEncoding)
+ throw;
+#endif
+
+ throw new ArgumentOutOfRangeException ("ptr", "Value, startIndex and length do not refer to a valid string.");
+#if NET_2_0
+ } catch (AccessViolationException) {
+ if (!isDefaultEncoding)
+ throw;
+
+ throw new ArgumentOutOfRangeException ("value", "Value, startIndex and length do not refer to a valid string.");
+#endif
+ }
+
+ // GetString () is called even when length == 0
+ return enc.GetString (bytes);
+ }
+
+ unsafe string CreateString (char *value)
+ {
+ if (value == null)
+ return string.Empty;
+ char *p = value;
+ int i = 0;
+ while (*p != 0) {
+ ++i;
+ ++p;
+ }
+ string result = InternalAllocateStr (i);
+
+ if (i != 0) {
+ fixed (char *dest = result) {
+ CharCopy (dest, value, i);
+ }
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char *value, int startIndex, int length)
+ {
+ if (length == 0)
+ return string.Empty;
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length");
+
+ string result = InternalAllocateStr (length);
+
+ fixed (char *dest = result) {
+ CharCopy (dest, value + startIndex, length);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char [] val, int startIndex, int length)
+ {
+ if (val == null)
+ throw new ArgumentNullException ("value");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException ("startIndex", "Cannot be negative.");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ("length", "Cannot be negative.");
+ if (startIndex > val.Length - length)
+ throw new ArgumentOutOfRangeException ("startIndex", "Cannot be negative, and should be less than length of string.");
+ if (length == 0)
+ return string.Empty;
+
+ string result = InternalAllocateStr (length);
+
+ fixed (char *dest = result, src = val) {
+ CharCopy (dest, src + startIndex, length);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char [] val)
+ {
+ if (val == null)
+ return string.Empty;
+ if (val.Length == 0)
+ return string.Empty;
+ string result = InternalAllocateStr (val.Length);
+
+ fixed (char *dest = result, src = val) {
+ CharCopy (dest, src, val.Length);
+ }
+ return result;
+ }
+
+ unsafe string CreateString (char c, int count)
+ {
+ if (count < 0)
+ throw new ArgumentOutOfRangeException ("count");
+ if (count == 0)
+ return string.Empty;
+ string result = InternalAllocateStr (count);
+ fixed (char *dest = result) {
+ char *p = dest;
+ char *end = p + count;
+ while (p < end) {
+ *p = c;
+ p++;
+ }
+ }
+ return result;
+ }
+#pragma warning restore 169
+