private static unsafe void EncodeCore(this TextEncoder encoder, TextWriter output, char *value, int valueLength) { Debug.Assert(encoder != null && value != null & output != null); Debug.Assert(valueLength >= 0); int bufferLength = encoder.MaxOutputCharactersPerInputCharacter; char *buffer = stackalloc char[bufferLength]; char firstChar = *value; char secondChar = firstChar; bool wasSurrogatePair = false; int charsWritten; // this loop processes character pairs (in case they are surrogates). // there is an if block below to process single last character. for (int secondCharIndex = 1; secondCharIndex < valueLength; secondCharIndex++) { if (!wasSurrogatePair) { firstChar = secondChar; } else { firstChar = value[secondCharIndex - 1]; } secondChar = value[secondCharIndex]; if (!encoder.Encodes(firstChar)) { wasSurrogatePair = false; output.Write(firstChar); } else { int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, secondChar, out wasSurrogatePair); if (!encoder.TryEncodeUnicodeScalar(nextScalar, buffer, bufferLength, out charsWritten)) { throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly."); } output.Write(buffer, charsWritten); if (wasSurrogatePair) { secondCharIndex++; } } } if (!wasSurrogatePair) { firstChar = value[valueLength - 1]; int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, null, out wasSurrogatePair); if (!encoder.TryEncodeUnicodeScalar(nextScalar, buffer, bufferLength, out charsWritten)) { throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly."); } output.Write(buffer, charsWritten); } }
public static string Encode(this TextEncoder encoder, string value) { if (value == null) { return(value); } unsafe { fixed(char *valuePointer = value) { int firstCharacterToEncode = encoder.FindFirstCharacterToEncode(valuePointer, value.Length); if (firstCharacterToEncode == -1) { return(value); } int bufferSize = encoder.MaxOutputCharsPerInputChar * value.Length; char *wholebuffer = stackalloc char[bufferSize]; char *buffer = wholebuffer; int totalWritten = 0; if (firstCharacterToEncode > 0) { int bytesToCopy = firstCharacterToEncode + firstCharacterToEncode; Buffer.MemoryCopy(valuePointer, buffer, bytesToCopy, bytesToCopy); totalWritten += firstCharacterToEncode; bufferSize -= firstCharacterToEncode; buffer += firstCharacterToEncode; } int valueIndex = firstCharacterToEncode; char firstChar = value[valueIndex]; char secondChar = firstChar; bool wasSurrogatePair = false; int charsWritten; // this loop processes character pairs (in case they are surrogates). // there is an if block below to process single last character. for (int secondCharIndex = valueIndex + 1; secondCharIndex < value.Length; secondCharIndex++) { if (!wasSurrogatePair) { firstChar = secondChar; } else { firstChar = value[secondCharIndex - 1]; } secondChar = value[secondCharIndex]; if (!encoder.Encodes(firstChar)) { wasSurrogatePair = false; *buffer = firstChar; buffer++; bufferSize--; totalWritten++; } else { int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, secondChar, out wasSurrogatePair); if (!encoder.TryEncodeUnicodeScalar(nextScalar, buffer, bufferSize, out charsWritten)) { throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly."); } buffer += charsWritten; bufferSize -= charsWritten; totalWritten += charsWritten; if (wasSurrogatePair) { secondCharIndex++; } } } if (!wasSurrogatePair) { firstChar = value[value.Length - 1]; int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, null, out wasSurrogatePair); if (!encoder.TryEncodeUnicodeScalar(nextScalar, buffer, bufferSize, out charsWritten)) { throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly."); } buffer += charsWritten; bufferSize -= charsWritten; totalWritten += charsWritten; } var result = new String(wholebuffer, 0, totalWritten); return(result); } } }