示例#1
0
        public static bool TryFormat(this char value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                if (buffer.Length < 2)
                {
                    bytesWritten = 0;
                    return false;
                }
                buffer[0] = (byte)value;
                buffer[1] = (byte)(value >> 8);
                bytesWritten = 2;
                return true;
            }

            if (buffer.Length < 1)
            {
                bytesWritten = 0;
                return false;
            }

            // fast path for ASCII
            if (value <= 127)
            {
                buffer[0] = (byte)value;
                bytesWritten = 1;
                return true;
            }

            // TODO: This can be directly encoded to SpanByte. There is no conversion between spans yet
            var encoded = new Utf8EncodedCodePoint(value);
            bytesWritten = encoded.Length;
            if (buffer.Length < bytesWritten)
            {
                bytesWritten = 0;
                return false;
            }

            buffer[0] = encoded.Byte0;
            if(bytesWritten > 1)
            {
                buffer[1] = encoded.Byte1;
            }
            if(bytesWritten > 2)
            {
                buffer[2] = encoded.Byte2;
            }
            if(bytesWritten > 3)
            {
                buffer[3] = encoded.Byte3;
            }
            return true;
        }
        public static bool TryEncode(this char value, Span<byte> buffer, out int bytesWritten, TextEncoding encoding = TextEncoding.Utf8)
        {
            if (encoding == TextEncoding.Utf16)
            {
                if (buffer.Length < 2)
                {
                    bytesWritten = 0;
                    return false;
                }
                buffer[0] = (byte)value;
                buffer[1] = (byte)(value >> 8);
                bytesWritten = 2;
                return true;
            }

            if (encoding == TextEncoding.Utf8) {
                if (buffer.Length < 1) {
                    bytesWritten = 0;
                    return false;
                }

                // fast path for ASCII
                if (value <= 127) {
                    buffer[0] = (byte)value;
                    bytesWritten = 1;
                    return true;
                }

                // TODO: This can be directly encoded to SpanByte. There is no conversion between spans yet
                var encoded = new Utf8EncodedCodePoint(value);
                bytesWritten = encoded.Length;
                if (buffer.Length < bytesWritten) {
                    bytesWritten = 0;
                    return false;
                }

                buffer[0] = encoded.Byte0;
                if (bytesWritten > 1) {
                    buffer[1] = encoded.Byte1;
                }
                if (bytesWritten > 2) {
                    buffer[2] = encoded.Byte2;
                }
                if (bytesWritten > 3) {
                    buffer[3] = encoded.Byte3;
                }
                return true;
            }

            throw new NotImplementedException();
        }
示例#3
0
        public override bool TryEncodeChar(char value, Span <byte> buffer, out int bytesWritten)
        {
            if (buffer.Length < 1)
            {
                bytesWritten = 0;
                return(false);
            }

            // fast path for ASCII
            if (value <= 127)
            {
                buffer[0]    = (byte)value;
                bytesWritten = 1;
                return(true);
            }

            // TODO: This can be directly encoded to SpanByte. There is no conversion between spans yet
            var encoded = new Utf8EncodedCodePoint(value);

            bytesWritten = encoded.Length;
            if (buffer.Length < bytesWritten)
            {
                bytesWritten = 0;
                return(false);
            }

            buffer[0] = encoded.Byte0;
            if (bytesWritten > 1)
            {
                buffer[1] = encoded.Byte1;
            }
            if (bytesWritten > 2)
            {
                buffer[2] = encoded.Byte2;
            }
            if (bytesWritten > 3)
            {
                buffer[3] = encoded.Byte3;
            }
            return(true);
        }
示例#4
0
        public static bool TryFormat(this string value, Span<byte> buffer, Format.Parsed format, EncodingData formattingData, out int bytesWritten)
        {

            if (formattingData.IsUtf16)
            {
                var valueBytes = value.Length << 1;
                if (valueBytes > buffer.Length)
                {
                    bytesWritten = 0;
                    return false;
                }

                unsafe
                {
                    fixed (char* pCharacters = value)
                    {
                        byte* pBytes = (byte*)pCharacters;
                        buffer.Set(pBytes, valueBytes);
                    }
                }

                bytesWritten = valueBytes;
                return true;
            }

                
            var avaliableBytes = buffer.Length;
            bytesWritten = 0;
            for (int i = 0; i < value.Length; i++)
            {
                var c = value[i];

                var codepoint = (ushort)c;
                if (codepoint <= 0x7f) // this if block just optimizes for ascii
                {
                    if (bytesWritten + 1 > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return false;
                    }
                    buffer[bytesWritten++] = (byte)codepoint;
                }
                else
                {
                    Utf8EncodedCodePoint encoded;
                    if (!char.IsSurrogate(c))
                        encoded = new Utf8EncodedCodePoint(c);
                    else
                    {
                        if (++i >= value.Length)
                            throw new ArgumentException("Invalid surrogate pair.", nameof(value));
                        char lowSurrogate = value[i];
                        encoded = new Utf8EncodedCodePoint(c, lowSurrogate);
                    }
                            

                    if (bytesWritten + encoded.Length > avaliableBytes)
                    {
                        bytesWritten = 0;
                        return false;
                    }

                    buffer[bytesWritten] = encoded.Byte0;
                    if (encoded.Length > 1)
                    {
                        buffer[bytesWritten + 1] = encoded.Byte1;

                        if (encoded.Length > 2)
                        {
                            buffer[bytesWritten + 2] = encoded.Byte2;

                            if (encoded.Length > 3)
                            {
                                buffer[bytesWritten + 3] = encoded.Byte3;
                            }
                        }
                    }

                    bytesWritten += encoded.Length;
                }
            }
            return true;
        }
示例#5
0
 public void Utf8EncodedCodePointFromChar7()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\uFFFF');
     Assert.Equal(3, ecp.Length);
     Assert.Equal(0xEF, ecp.Byte0);
     Assert.Equal(0xBF, ecp.Byte1);
     Assert.Equal(0xBF, ecp.Byte2);
 }
示例#6
0
 public void Utf8EncodedCodePointFromChar6()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u1FA9');
     Assert.Equal(3, ecp.Length);
     Assert.Equal(0xE1, ecp.Byte0);
     Assert.Equal(0xBE, ecp.Byte1);
     Assert.Equal(0xA9, ecp.Byte2);
 }
示例#7
0
 public void Utf8EncodedCodePointFromChar5()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u0800');
     Assert.Equal(3, ecp.Length);
     Assert.Equal(0xE0, ecp.Byte0);
     Assert.Equal(0xA0, ecp.Byte1);
     Assert.Equal(0x80, ecp.Byte2);
 }
示例#8
0
 public void Utf8EncodedCodePointFromChar4()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u07FF');
     Assert.Equal(2, ecp.Length);
     Assert.Equal(0xDF, ecp.Byte0);
     Assert.Equal(0xBF, ecp.Byte1);
 }
示例#9
0
 public void Utf8EncodedCodePointFromChar3()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u01ED');
     Assert.Equal(2, ecp.Length);
     Assert.Equal(0xC7, ecp.Byte0);
     Assert.Equal(0xAD, ecp.Byte1);
 }
示例#10
0
 public void Utf8EncodedCodePointFromChar2()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u0080');
     Assert.Equal(2, ecp.Length);
     Assert.Equal(0xC2, ecp.Byte0);
     Assert.Equal(0x80, ecp.Byte1);
 }
示例#11
0
 public void Utf8EncodedCodePointFromChar1()
 {
     Utf8EncodedCodePoint ecp = new Utf8EncodedCodePoint('\u007F');
     Assert.Equal(1, ecp.Length);
     Assert.Equal(0x7F, ecp.Byte0);
 }
示例#12
0
        public static bool TryFormat(this string value, Span<byte> buffer, Format.Parsed format, FormattingData formattingData, out int bytesWritten)
        {
            if (formattingData.IsUtf16)
            {
                var valueBytes = value.Length << 1;
                if (valueBytes > buffer.Length)
                {
                    bytesWritten = 0;
                    return false;
                }

                unsafe
                {
                    fixed (char* pCharacters = value)
                    {
                        byte* pBytes = (byte*)pCharacters;
                        buffer.Set(pBytes, valueBytes);
                    }
                }

                bytesWritten = valueBytes;
                return true;
            }

            GCHandle handle;
            var byteSpan = buffer.Pin(out handle);
            try {

                var avaliableBytes = byteSpan.Length;
                bytesWritten = 0;
                for (int i = 0; i < value.Length; i++)
                {
                    var c = value[i];

                    var codepoint = (ushort)c;
                    if (codepoint <= 0x7f) // this if block just optimizes for ascii
                    {
                        if (bytesWritten + 1 > avaliableBytes)
                        {
                            bytesWritten = 0;
                            return false;
                        }
                        byteSpan[bytesWritten++] = (byte)codepoint;
                    }
                    else
                    {
                        var encoded = new Utf8EncodedCodePoint(c);

                        if (bytesWritten + encoded.Length > avaliableBytes)
                        {
                            bytesWritten = 0;
                            return false;
                        }

                        byteSpan[bytesWritten] = encoded.Byte0;
                        if (encoded.Length > 1)
                        {
                            byteSpan[bytesWritten + 1] = encoded.Byte1;

                            if (encoded.Length > 2)
                            {
                                byteSpan[bytesWritten + 2] = encoded.Byte2;

                                if (encoded.Length > 3)
                                {
                                    byteSpan[bytesWritten + 3] = encoded.Byte3;
                                }
                            }
                        }

                        bytesWritten += encoded.Length;
                    }
                }
                return true;
            }
            finally
            {
                handle.Free();
            }
        }
        public static bool TryEncode(this ReadOnlySpan<char> value, Span<byte> buffer, out int bytesWritten, TextEncoding encoding = TextEncoding.Utf8)
        {
            if (encoding == TextEncoding.Utf16) {
                var valueBytes = value.Cast<char, byte>();
                if (buffer.Length < valueBytes.Length) {
                    bytesWritten = 0;
                    return false;
                }
                valueBytes.CopyTo(buffer);
                bytesWritten = valueBytes.Length;
                return true;
            }

            if (encoding == TextEncoding.Utf8) {
                var avaliableBytes = buffer.Length;
                bytesWritten = 0;
                for (int i = 0; i < value.Length; i++) {
                    var c = value[i];

                    var codepoint = (ushort)c;
                    if (codepoint <= 0x7f) // this if block just optimizes for ascii
                    {
                        if (bytesWritten + 1 > avaliableBytes) {
                            bytesWritten = 0;
                            return false;
                        }
                        buffer[bytesWritten++] = (byte)codepoint;
                    }
                    else {
                        Utf8EncodedCodePoint encoded;
                        if (!char.IsSurrogate(c))
                            encoded = new Utf8EncodedCodePoint(c);
                        else {
                            if (++i >= value.Length)
                                throw new ArgumentException("Invalid surrogate pair.", nameof(value));
                            char lowSurrogate = value[i];
                            encoded = new Utf8EncodedCodePoint(c, lowSurrogate);
                        }


                        if (bytesWritten + encoded.Length > avaliableBytes) {
                            bytesWritten = 0;
                            return false;
                        }

                        buffer[bytesWritten] = encoded.Byte0;
                        if (encoded.Length > 1) {
                            buffer[bytesWritten + 1] = encoded.Byte1;

                            if (encoded.Length > 2) {
                                buffer[bytesWritten + 2] = encoded.Byte2;

                                if (encoded.Length > 3) {
                                    buffer[bytesWritten + 3] = encoded.Byte3;
                                }
                            }
                        }

                        bytesWritten += encoded.Length;
                    }
                }
                return true;
            }

            throw new NotSupportedException();
        }