Rewrite Uri.EscapeString (dotnet/corefx#41772)
* Rewrite Uri.EscapeString
Several public methods (Uri.EscapeDataString, Uri.EscapeUriString) and a bunch of internal call sites rely on the internal EscapeString helper. This helper has several issues with it:
- It uses unsafe code.
- It unnecessarily requires and copies through a char[] to get to a string when a string is the required result.
- It has a lot of complexity around the handling of unicode.
This PR rewrites it to utilize Span, Rune, and other newer features in a way that enables it to be both safe and efficient. Most inputs ends up being faster, and for very long inputs, it's much, much faster. The use of ValueStringBuilder also results in less memory allocation, in some cases significantly.
The use of Rune also fixes two arguable bugs in the existing implementation around invalid Unicode sequences, which is why a couple tests were tweaked:
- Some but not all invalid unicode patterns result in replacement characters being used: a few invalid sequences (e.g. just a high surrogate) result in an exception. We should be standardized on using replacement characters for all such invalid sequences.
- Some patterns with invalid unicode patterns actually result in unnecessary encoding, e.g. `Uri.EscapeDataString("\uD800\uD800a")` results in `a` being encoded.
* Address PR feedback
* Add comment about RFC 3986
Commit migrated from https://github.com/dotnet/corefx/commit/
75b4e8b12815949813d83b771d5d6ed9279f924c