Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #978 from KrzysztofCwalina/EncodingCleanup
Browse files Browse the repository at this point in the history
Encoding cleanup
  • Loading branch information
KrzysztofCwalina authored Nov 15, 2016
2 parents b92e9fa + d0b33e6 commit ee72feb
Show file tree
Hide file tree
Showing 25 changed files with 449 additions and 863 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private static EncodingData CreateEncoding(string localeId, Stream resourceStrea

byte[] idBytes = new byte[maxIdLength];
int idByteCount;
if (!localeId.TryFormat(new Span<byte>(idBytes), EncodingData.InvariantUtf8, out idByteCount))
if (!localeId.TryFormat(new Span<byte>(idBytes), EncodingData.TextEncoding.Utf8, out idByteCount))
{
throw new Exception("bad locale id");
}
Expand Down Expand Up @@ -92,7 +92,7 @@ private static EncodingData CreateEncoding(string localeId, Stream resourceStrea
Array.Copy(data, stringStart, utf16digitsAndSymbols[stringIndex], 0, stringLength);
}

return new EncodingData(utf16digitsAndSymbols, EncodingData.Encoding.Utf16);
return new EncodingData(utf16digitsAndSymbols, EncodingData.TextEncoding.Utf16);
}

static ushort ReadUInt16At(byte[] data, int ushortIndex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static void Append<TFormatter>(this TFormatter formatter, string whole, int inde
for (int i = 0; i < count; i++)
{
int bytesWritten;
while (!whole[i+index].TryFormat(buffer, formatter.Encoding, out bytesWritten))
while (!whole[i+index].TryFormat(buffer, formatter.Encoding.Encoding, out bytesWritten))
{
Debug.Assert(false, "this should never happen"); // because I pre-resized the buffer to 4 bytes per char at the top of this method.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static class IOutputExtensions
return true;
}

public static void Append<TFormatter>(this TFormatter formatter, string value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static void Append<TFormatter>(this TFormatter formatter, string value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
if (value.Length < 256) {
while (!formatter.TryAppend(value, encoding)) {
Expand All @@ -47,61 +47,61 @@ public static void Append<TFormatter>(this TFormatter formatter, string value, E
}
}

public static bool TryAppend<TFormatter>(this TFormatter formatter, string value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static bool TryAppend<TFormatter>(this TFormatter formatter, string value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, encoding == EncodingData.Encoding.Utf8 ? EncodingData.InvariantUtf8 : EncodingData.InvariantUtf16, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
return true;
}

public static void Append<TFormatter>(this TFormatter formatter, ReadOnlySpan<char> value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static void Append<TFormatter>(this TFormatter formatter, ReadOnlySpan<char> value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
while (!formatter.TryAppend(value, encoding)) {
formatter.Enlarge();
}
}

public static bool TryAppend<TFormatter>(this TFormatter formatter, ReadOnlySpan<char> value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static bool TryAppend<TFormatter>(this TFormatter formatter, ReadOnlySpan<char> value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, encoding==EncodingData.Encoding.Utf8?EncodingData.InvariantUtf8:EncodingData.InvariantUtf16, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
return true;
}

public static void Append<TFormatter>(this TFormatter formatter, char value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static void Append<TFormatter>(this TFormatter formatter, char value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
while (!formatter.TryAppend(value, encoding)) {
formatter.Enlarge();
}
}

public static bool TryAppend<TFormatter>(this TFormatter formatter, char value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static bool TryAppend<TFormatter>(this TFormatter formatter, char value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, encoding == EncodingData.Encoding.Utf8 ? EncodingData.InvariantUtf8 : EncodingData.InvariantUtf16, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
return true;
}

public static void Append<TFormatter>(this TFormatter formatter, Utf8String value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static void Append<TFormatter>(this TFormatter formatter, Utf8String value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
while (!formatter.TryAppend(value, encoding)) {
formatter.Enlarge();
}
}

public static bool TryAppend<TFormatter>(this TFormatter formatter, Utf8String value, EncodingData.Encoding encoding) where TFormatter : IOutput
public static bool TryAppend<TFormatter>(this TFormatter formatter, Utf8String value, EncodingData.TextEncoding encoding) where TFormatter : IOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, encoding == EncodingData.Encoding.Utf8 ? EncodingData.InvariantUtf8 : EncodingData.InvariantUtf16, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public static void Append<TFormatter>(this TFormatter formatter, char value) whe
public static bool TryAppend<TFormatter>(this TFormatter formatter, char value) where TFormatter : ITextOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, formatter.Encoding, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, formatter.Encoding.Encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
Expand All @@ -188,7 +188,7 @@ public static void Append<TFormatter>(this TFormatter formatter, ReadOnlySpan<ch
public static bool TryAppend<TFormatter>(this TFormatter formatter, ReadOnlySpan<char> value) where TFormatter : ITextOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, formatter.Encoding, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, formatter.Encoding.Encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
Expand Down Expand Up @@ -220,7 +220,7 @@ public static void Append<TFormatter>(this TFormatter formatter, string value) w
public static bool TryAppend<TFormatter>(this TFormatter formatter, string value) where TFormatter : ITextOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, formatter.Encoding, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, formatter.Encoding.Encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
Expand All @@ -237,7 +237,7 @@ public static void Append<TFormatter>(this TFormatter formatter, Utf8String valu
public static bool TryAppend<TFormatter>(this TFormatter formatter, Utf8String value) where TFormatter : ITextOutput
{
int bytesWritten;
if (!value.TryFormat(formatter.Buffer, formatter.Encoding, out bytesWritten)) {
if (!value.TryFormat(formatter.Buffer, formatter.Encoding.Encoding, out bytesWritten)) {
return false;
}
formatter.Advance(bytesWritten);
Expand Down
2 changes: 1 addition & 1 deletion src/System.Text.Http/System/Text/Http/HttpHeaderBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void UpdateValue(string newValue)
}

int bytesWritten;
newValue.TryFormat(_bytes, _encoding, out bytesWritten);
newValue.TryFormat(_bytes, _encoding.Encoding, out bytesWritten);

_bytes.SetFromRestOfSpanToEmpty(newValue.Length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData form
{
written = 0;
int justWritten;
if(!'{'.TryFormat(buffer, formattingData, out justWritten)){
if(!'{'.TryFormat(buffer, formattingData.Encoding, out justWritten)){
return false;
}
written += justWritten;
Expand All @@ -182,7 +182,7 @@ public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData form
if(firstProperty) { firstProperty = false; }
else
{
if (!','.TryFormat(buffer.Slice(written), formattingData, out justWritten))
if (!','.TryFormat(buffer.Slice(written), formattingData.Encoding, out justWritten))
{
return false;
}
Expand All @@ -194,7 +194,7 @@ public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData form
written = 0; return false;
}
written += justWritten;
if (!':'.TryFormat(buffer.Slice(written), formattingData, out justWritten))
if (!':'.TryFormat(buffer.Slice(written), formattingData.Encoding, out justWritten))
{
return false;
}
Expand All @@ -206,7 +206,7 @@ public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData form
written += justWritten;
}

if (!'}'.TryFormat(buffer.Slice(written), formattingData, out justWritten)){
if (!'}'.TryFormat(buffer.Slice(written), formattingData.Encoding, out justWritten)){
written = 0; return false;
}
written += justWritten;
Expand Down Expand Up @@ -268,11 +268,11 @@ public bool TryFormat(Span<byte> buffer, Format.Parsed format, EncodingData form
case JsonReader.JsonValueType.Object:
return _object.TryFormat(buffer, format, formattingData, out written);
case JsonReader.JsonValueType.Null:
return "null".TryFormat(buffer, formattingData, out written);
return "null".TryFormat(buffer, formattingData.Encoding, out written);
case JsonReader.JsonValueType.True:
return "true".TryFormat(buffer, formattingData, out written);
return "true".TryFormat(buffer, formattingData.Encoding, out written);
case JsonReader.JsonValueType.False:
return "false".TryFormat(buffer, formattingData, out written);
return "false".TryFormat(buffer, formattingData.Encoding, out written);
default:
throw new NotImplementedException();
}
Expand Down Expand Up @@ -348,7 +348,7 @@ public static bool TryFormatQuotedString(this Utf8String str, Span<byte> buffer,
written = 0;
int justWritten;

if (!'"'.TryFormat(buffer, formattingData, out justWritten))
if (!'"'.TryFormat(buffer, formattingData.Encoding, out justWritten))
{
return false;
}
Expand All @@ -360,7 +360,7 @@ public static bool TryFormatQuotedString(this Utf8String str, Span<byte> buffer,
}
written += justWritten;

if (!'"'.TryFormat(buffer.Slice(written), formattingData, out justWritten))
if (!'"'.TryFormat(buffer.Slice(written), formattingData.Encoding, out justWritten))
{
return false;
}
Expand Down
44 changes: 26 additions & 18 deletions src/System.Text.Primitives/System/Text/EncodingData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ public struct EncodingData : IEquatable<EncodingData>
{
private static EncodingData s_invariantUtf16;
private static EncodingData s_invariantUtf8;

private byte[][] _digitsAndSymbols; // this could be flattened into a single array
private TrieNode[] _parsingTrie;
private Encoding _encoding;
private ParsingTrieNode[] _parsingTrie;
private TextEncoding _encoding;

public enum Encoding : byte
public enum TextEncoding : byte
{
Utf16 = 0,
Utf8 = 1,
Ascii,
}

// The parsing trie is structured as an array, which means that there are two types of
Expand All @@ -40,25 +42,38 @@ public enum Encoding : byte
// The index is formatted as such: 0xAABBCCDD, where AA = the min value,
// BB = the index of the min value relative to the current node (1-indexed),
// CC = the max value, and DD = the max value's index in the same coord-system as BB.
public struct TrieNode
internal struct ParsingTrieNode
{
public byte valueOrNumChildren;
public int index;
}

// TODO: make these private once bin file generator is used
public EncodingData(byte[][] digitsAndSymbols, TrieNode[] parsingTrie, Encoding encoding)
// this should be removed after CreateParsingTire is implemented
public EncodingData(byte[][] digitsAndSymbols, TextEncoding encoding, Tuple<byte, int>[] parsingTrie)
{
_digitsAndSymbols = digitsAndSymbols;
_encoding = encoding;
_parsingTrie = parsingTrie;

var tire = new ParsingTrieNode[parsingTrie.Length];
for(int i=0; i<parsingTrie.Length; i++) {
tire[i] = new ParsingTrieNode() { valueOrNumChildren = parsingTrie[i].Item1, index = parsingTrie[i].Item2 };
}

_parsingTrie = tire;
}

public EncodingData(byte[][] digitsAndSymbols, Encoding encoding)
public EncodingData(byte[][] digitsAndSymbols, TextEncoding encoding)
{
_digitsAndSymbols = digitsAndSymbols;
_encoding = encoding;
_parsingTrie = null;
_parsingTrie = CreateParsingTire(_digitsAndSymbols);
}

private ParsingTrieNode[] CreateParsingTire(byte[][] _digitsAndSymbols)
{
// TODO: this needs to be implemented;
return null;
}

// This binary search implementation returns an int representing either:
Expand Down Expand Up @@ -128,7 +143,7 @@ static EncodingData()
new byte[] { 101, 0, }, // e
};

s_invariantUtf16 = new EncodingData(utf16digitsAndSymbols, Encoding.Utf16);
s_invariantUtf16 = new EncodingData(utf16digitsAndSymbols, TextEncoding.Utf16);

var utf8digitsAndSymbols = new byte[][] {
new byte[] { 48, },
Expand All @@ -151,7 +166,7 @@ static EncodingData()
new byte[] { 101, }, // e
};

s_invariantUtf8 = new EncodingData(utf8digitsAndSymbols, Encoding.Utf8);
s_invariantUtf8 = new EncodingData(utf8digitsAndSymbols, TextEncoding.Utf8);
}

public static EncodingData InvariantUtf16
Expand Down Expand Up @@ -348,14 +363,7 @@ public bool IsInvariantUtf8
get { return _digitsAndSymbols == s_invariantUtf8._digitsAndSymbols; }
}

public bool IsUtf16
{
get { return _encoding == Encoding.Utf16; }
}
public bool IsUtf8
{
get { return _encoding == Encoding.Utf8; }
}
public TextEncoding Encoding => _encoding;

public static bool operator==(EncodingData left, EncodingData right)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static bool TryFormatNumber(double value, bool isSingle, Span<byte> buffe
// TODO: the lines below need to be replaced with properly implemented algorithm
// the problem is the algorithm is complex, so I am commiting a stub for now
var hack = value.ToString(format.Symbol.ToString());
return hack.TryFormat(buffer, formattingData, out bytesWritten);
return hack.TryFormat(buffer, formattingData.Encoding, out bytesWritten);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ internal static bool TryFormatUInt64(ulong value, byte numberOfBytes, Span<byte>
format.Symbol = 'G';
}

if (format.IsHexadecimal && formattingData.IsUtf16) {
if (format.IsHexadecimal && formattingData.IsInvariantUtf16) {
return TryFormatHexadecimalInvariantCultureUtf16(value, buffer, format, out bytesWritten);
}

if (format.IsHexadecimal && formattingData.IsUtf8) {
if (format.IsHexadecimal && formattingData.IsInvariantUtf8) {
return TryFormatHexadecimalInvariantCultureUtf8(value, buffer, format, out bytesWritten);
}

Expand Down
Loading

0 comments on commit ee72feb

Please sign in to comment.