private void EncodeCore(ref Writer writer, char *input, uint charsRemaining) { while (charsRemaining != 0) { int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(input, endOfString: (charsRemaining == 1)); if (UnicodeHelpers.IsSupplementaryCodePoint(nextScalar)) { // Supplementary characters should always be encoded numerically. WriteEncodedScalar(ref writer, (uint)nextScalar); // We consume two UTF-16 characters for a single supplementary character. input += 2; charsRemaining -= 2; } else { // Otherwise, this was a BMP character. input++; charsRemaining--; char c = (char)nextScalar; if (IsCharacterAllowed(c)) { writer.Write(c); } else { WriteEncodedScalar(ref writer, (uint)nextScalar); } } } }
// Writes an encoded scalar value (in the BMP) as a JavaScript-escaped character. private static void WriteEncodedSingleCharacter(ref Writer writer, uint value) { Debug.Assert(!UnicodeHelpers.IsSupplementaryCodePoint((int)value), "The incoming value should've been in the BMP."); // Encode this as 6 chars "\uFFFF". writer.Write('\\'); writer.Write('u'); writer.Write(HexUtil.IntToChar(value >> 12)); writer.Write(HexUtil.IntToChar((value >> 8) & 0xFU)); writer.Write(HexUtil.IntToChar((value >> 4) & 0xFU)); writer.Write(HexUtil.IntToChar(value & 0xFU)); }
// Writes a scalar value as an JavaScript-escaped character (or sequence of characters). private static void WriteEncodedScalarAsNumericEntity(ref Writer writer, uint value) { if (UnicodeHelpers.IsSupplementaryCodePoint((int)value)) { // Convert this back to UTF-16 and write out both characters. char leadingSurrogate, trailingSurrogate; UnicodeHelpers.GetUtf16SurrogatePairFromAstralScalarValue((int)value, out leadingSurrogate, out trailingSurrogate); WriteEncodedSingleCharacter(ref writer, leadingSurrogate); WriteEncodedSingleCharacter(ref writer, trailingSurrogate); } else { // This is only a single character. WriteEncodedSingleCharacter(ref writer, value); } }