public static Rune FromString(string value, ref int index)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            if (index >= value.Length)
            {
                throw new ArgumentOutOfRangeException("index", "Index is out of range of string.");
            }

            char c = value[index++];

            if (Utf16.IsLeadingSurrogate(c))
            {
                if (index >= value.Length)
                {
                    throw new ArgumentOutOfRangeException("index", "Index is out of range of string.");
                }

                char d = value[index++];

                return(Rune.FromUtf16(c, d));
            }
            else
            {
                return(Rune.FromUtf16(c));
            }
        }
        public static Rune FromUtf16(ushort[] array, ref int index)
        {
            if (index >= array.Length)
            {
                throw new ArgumentOutOfRangeException("index", "Index out of bounds.");
            }

            var value = array[index++];

            if (Utf16.IsLeadingSurrogate(value))
            {
                if (index >= array.Length)
                {
                    throw new ArgumentOutOfRangeException("index", "Need two items to process surrogate pair.");
                }

                var trailing = array[index++];

                return(FromUtf16(value, trailing));
            }
            else
            {
                return(new Rune(value));
            }
        }
        public static Rune FromUtf16(byte[] array, ref int index, ByteOrder endianness = ByteOrder.LittleEndian)
        {
            var decoder = new Utf16.ByteDecoder(endianness);

            if (index + 2 > array.Length)
            {
                throw new ArgumentOutOfRangeException("index", "Need at least 2 bytes to process Utf16");
            }

            decoder.Process(array[index++]);
            var result = decoder.Process(array[index++]);

            if (result == null)
            {
                if (index + 2 > array.Length)
                {
                    throw new ArgumentOutOfRangeException("index", "Need 4 bytes to process Utf16 surrogate pair");
                }

                decoder.Process(array[index++]);
                result = decoder.Process(array[index++]);

                if (result == null)
                {
                    throw new RuneException(Utf16.MissingTrailingSurrogateMessage());
                }
            }

            return(new Rune(result.GetValueOrDefault()));
        }
Example #4
0
        public void TestNonBasic()
        {
            uint code;

            Assert.AreEqual(2, Utf16.ToCode(out code, 0xD834, 0xDD1E));
            Assert.AreEqual((uint)0x1D11E, code);
        }
        public static Rune FromUtf16(ushort leadingSurrogate, ushort trailingSurrogate)
        {
            uint utf32;

            utf32 = Utf16.ToUtf32(leadingSurrogate, trailingSurrogate);

            return(new Rune(utf32));
        }
Example #6
0
        public void TestLatinCharacter()
        {
            uint code;

            Assert.AreEqual(1, Utf16.ToCode(out code, 0x7A));
            Assert.AreEqual((uint)0x7A, code);

            Assert.AreEqual(1, Utf16.ToCode(out code, 0x7A, 0xABCD), "Trail is ignored");
            Assert.AreEqual((uint)0x7A, code);
        }
Example #7
0
        public void TestHighSingleComponent()
        {
            uint code;

            Assert.AreEqual(1, Utf16.ToCode(out code, 0x6C34));
            Assert.AreEqual((uint)0x6C34, code);

            Assert.AreEqual(1, Utf16.ToCode(out code, 0x6C34, 0xABCD), "Trail is ignored");
            Assert.AreEqual((uint)0x6C34, code);
        }
Example #8
0
        public void TestHighSingleComponent()
        {
            ushort lead, trail;

            Assert.AreEqual(1, Utf16.FromCode(0x6c34, out lead, out trail));

            Assert.AreEqual(0x6c34, lead);
            Assert.AreEqual(0, trail);

            Assert.AreEqual("\u6C34", Utf16.FromCode(0x6C34));
        }
Example #9
0
        public void TestNonBasic()
        {
            ushort lead, trail;

            Assert.AreEqual(2, Utf16.FromCode(0x1D11E, out lead, out trail));

            Assert.AreEqual(0xD834, lead);
            Assert.AreEqual(0xDD1E, trail);

            Assert.AreEqual("\uD834\uDD1E", Utf16.FromCode(0x1D11E));
        }
Example #10
0
        public void TestFromLatinCharacter()
        {
            ushort lead, trail;

            Assert.AreEqual(1, Utf16.FromCode(0x7a, out lead, out trail));

            Assert.AreEqual(0x7a, lead);
            Assert.AreEqual(0, trail);

            Assert.AreEqual("\u007A", Utf16.FromCode(0x7A));
        }
Example #11
0
File: Rune.cs Project: BaisilG/Core
        /// <summary>
        /// Attempts to create a <see cref="Rune"/> from the provided input value.
        /// </summary>
        public static Boolean TryCreate(Char ch, out Rune result)
        {
            UInt32 extendedValue = ch;

            if (!Utf16.IsSurrogate(extendedValue))
            {
                result = new Rune(extendedValue);
                return(true);
            }
            else
            {
                result = default;
                return(false);
            }
        }
Example #12
0
 public static bool TryFormat(DateTimeOffset value, Span <byte> buffer, out int bytesWritten, ParsedFormat format = default, SymbolTable symbolTable = null)
 {
     if (symbolTable == null || symbolTable == SymbolTable.InvariantUtf8)
     {
         return(Utf8.TryFormat(value, buffer, out bytesWritten, format));
     }
     else if (symbolTable == SymbolTable.InvariantUtf16)
     {
         return(Utf16.TryFormat(value, buffer, out bytesWritten, format));
     }
     else
     {
         throw new NotSupportedException();
     }
 }
Example #13
0
        /// <summary>
        /// Reads plain text from the input stream.
        /// </summary>
        public static Span ReadSpan(InputBuffer buffer)
        {
            var span = new StringBuilder();

            while (true)
            {
                var text = buffer.ConsumeUntil(b => _escapeChars.Contains(b));
                span.Append(Encoding.UTF8.GetString(text, 0, text.Length));

                byte?next;
                if (buffer.At(0) == '\\' && (next = buffer.At(1)).HasValue)
                {
                    ControlWord word;
                    int         consumed;

                    if (ParseControlWord(buffer, 0, out word, out consumed))
                    {
                        if (word.Text == "u" && word.Parameter.HasValue && word.Parameter > 0)
                        {
                            // Handle unicode characters.
                            span.Append(Utf16.FromCode((uint)word.Parameter));
                            buffer.Discard(consumed + 1);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (!IsAsciiLetter(next))
                    {
                        // Handle control symbols.
                        // TODO: Translate control symbol to special character, e.g. \~ => nbsp.
                        span.Append((char)next.Value);
                        buffer.Discard(2);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            return(new Span(span.ToString()));
        }
Example #14
0
File: Rune.cs Project: BaisilG/Core
        private static Int32 ReadRuneFromString(String input, Int32 index)
        {
            if (input is null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if ((UInt32)index >= (UInt32)input !.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            // Optimistically assume input is within BMP.

            UInt32 returnValue = input[index];

            if (Utf16.IsSurrogate(returnValue))
            {
                if (!Utf16.IsHighSurrogate(returnValue))
                {
                    return(-1);
                }

                // Treat 'returnValue' as the high surrogate.
                //
                // If this becomes a hot code path, we can skip the below bounds check by reading
                // off the end of the string using unsafe code. Since strings are null-terminated,
                // we're guaranteed not to read a valid low surrogate, so we'll fail correctly if
                // the string terminates unexpectedly.

                index++;
                if ((UInt32)index >= (UInt32)input.Length)
                {
                    return(-1);                    // not an argument exception - just a "bad data" failure
                }

                UInt32 potentialLowSurrogate = input[index];
                if (!Utf16.IsLowSurrogate(potentialLowSurrogate))
                {
                    return(-1);
                }

                returnValue = Unsafe.Utf16Decode(returnValue, potentialLowSurrogate);
            }

            return((Int32)returnValue);
        }
        private static Rune[] UncheckedToRuneArray(string value, int start, int amount)
        {
            if (start < 0 || start > value.Length)
            {
                throw new ArgumentOutOfRangeException("start");
            }

            if (amount < 0 || start + amount > value.Length)
            {
                throw new ArgumentOutOfRangeException("amount");
            }


            var runes = new Rune[amount];

            int index = 0;


            var decoder = new Utf16.CharDecoder();

            bool result = true;

            for (int i = start; i < amount; i++)
            {
                var utf32 = decoder.Process(value[i]);

                if (utf32 != null)
                {
                    runes[index++] = (Rune)utf32.GetValueOrDefault();
                }
            }


            if (!result)
            {
                throw new RuneException(Utf16.MissingTrailingSurrogateMessage());
            }


            if (index < runes.Length)
            {
                Array.Resize(ref runes, index);
            }

            return(runes);
        }
Example #16
0
        public override string ToString()
        {
            string result;

            // Convert UTF32 -> UTF16
            if (value < Utf32.SupplementaryPlanePrefix)
            {
                result = ((char)value).ToString();
            }
            else
            {
                Utf16.FromUtf32(value, out ushort leading, out ushort trailing);

                result = "" + (char)leading + (char)trailing;
            }

            return(result);
        }
Example #17
0
        public static bool TryFormat(byte value, Span <byte> buffer, out int bytesWritten, ParsedFormat format = default, SymbolTable symbolTable = null)
        {
            if (format.IsDefault)
            {
                format = 'G';
            }

            if (symbolTable == null || symbolTable == SymbolTable.InvariantUtf8)
            {
                return(Utf8.TryFormat(value, buffer, out bytesWritten, format));
            }
            else if (symbolTable == SymbolTable.InvariantUtf16)
            {
                return(Utf16.TryFormat(value, buffer, out bytesWritten, format));
            }
            else
            {
                return(TryFormatUInt64(value, buffer, out bytesWritten, format, symbolTable));
            }
        }
Example #18
0
        public unsafe static byte[] ComputeKeyBytes(string key)
        {
            const int bufferLength = 128;

            byte *pBuffer = stackalloc byte[bufferLength];
            int   written, consumed;
            var   buffer = new Span <byte>(pBuffer, bufferLength);

            if (Utf16.ToUtf8(key.AsReadOnlySpan().AsBytes(), buffer, out consumed, out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            var keyBytes = new byte[64];
            var result   = Base64.Decode(buffer.Slice(0, written), keyBytes, out consumed, out written);

            if (result != TransformationStatus.Done || written != 64)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            return(keyBytes);
        }
Example #19
0
        /// <summary>
        /// Writes plain text content to the output stream.
        /// </summary>
        public void Span(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            int start, end;

            for (start = 0, end = 0; end < text.Length; ++end)
            {
                if (_escapeChars.Contains(text[end]))
                {
                    _writer.Write(text.Substring(start, end - start));

                    // Write control symbol.
                    _writer.Write('\\');
                    _writer.Write(text[end]);
                    start = end = end + 1;
                }
                else if (text[end] > 127)
                {
                    _writer.Write(text.Substring(start, end - start));

                    // Write unicode character.
                    uint code;
                    start = end = end + Utf16.ToCode(out code, text, end);
                    _writer.Write(@"\u{0}?", code);
                }
            }

            if (start < end)
            {
                _writer.Write(text.Substring(start, end - start));
            }
        }
Example #20
0
File: Rune.cs Project: BaisilG/Core
        // returns a negative number on failure
        internal static int ReadFirstRuneFromUtf16Buffer(ReadOnlySpan <char> input)
        {
            if (input.IsEmpty)
            {
                return(-1);
            }

            // Optimistically assume input is within BMP.

            uint returnValue = input[0];

            if (Utf16.IsSurrogate(returnValue))
            {
                if (!Utf16.IsHighSurrogate(returnValue))
                {
                    return(-1);
                }

                // Treat 'returnValue' as the high surrogate.

                if (1 >= (uint)input.Length)
                {
                    return(-1);                    // not an argument exception - just a "bad data" failure
                }

                uint potentialLowSurrogate = input[1];
                if (!Utf16.IsLowSurrogate(potentialLowSurrogate))
                {
                    return(-1);
                }

                returnValue = Unsafe.Utf16Decode(returnValue, potentialLowSurrogate);
            }

            return((int)returnValue);
        }
        private static IEnumerable <Rune> UncheckedToRunes(string value, int start, int amount)
        {
            if (start < 0 || start > value.Length)
            {
                throw new ArgumentOutOfRangeException("start");
            }

            if (amount < 0 || start + amount > value.Length)
            {
                throw new ArgumentOutOfRangeException("amount");
            }


            var runes = new Rune[amount];


            var decoder = new Utf16.CharDecoder();

            bool result = true;

            for (int i = start; i < amount; i++)
            {
                var utf32 = decoder.Process(value[i]);

                if (utf32 != null)
                {
                    yield return((Rune)utf32.GetValueOrDefault());
                }
            }


            if (!result)
            {
                throw new RuneException(Utf16.MissingTrailingSurrogateMessage());
            }
        }
Example #22
0
 /// <summary>
 /// Calculates the byte count needed to encode the UTF-8 bytes from the specified UTF-16 sequence.
 ///
 /// This method will consume as many of the input bytes as possible.
 /// </summary>
 /// <param name="source">A span containing a sequence of UTF-16 bytes.</param>
 /// <param name="bytesNeeded">On exit, contains the number of bytes required for encoding from the <paramref name="source"/>.</param>
 /// <returns>A <see cref="OperationStatus"/> value representing the expected state of the conversion.</returns>
 public static OperationStatus FromUtf16Length(ReadOnlySpan <byte> source, out int bytesNeeded)
 => Utf16.ToUtf8Length(source, out bytesNeeded);
        public static bool TryWrite(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten)
        {
            int written, consumed, totalWritten = 0;

            bytesWritten = 0;

            Span <byte> buffer;

            unsafe
            {
                var pBuffer = stackalloc byte[AuthenticationHeaderBufferSize];
                buffer = new Span <byte>(pBuffer, AuthenticationHeaderBufferSize);
            }

            s_type.CopyTo(buffer);
            totalWritten += s_type.Length;
            var bufferSlice = buffer.Slice(totalWritten);

            if (Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            totalWritten += written;
            bufferSlice   = buffer.Slice(totalWritten);

            s_ver.CopyTo(bufferSlice);
            totalWritten += s_ver.Length;

            bufferSlice = buffer.Slice(totalWritten);

            if (Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            totalWritten += written;
            bufferSlice   = buffer.Slice(totalWritten);

            s_sig.CopyTo(bufferSlice);
            totalWritten += s_sig.Length;

            var front = buffer.Slice(0, totalWritten);

            var payload = buffer.Slice(totalWritten);

            totalWritten = 0;

            if (verb.Equals("GET", StringComparison.Ordinal) || verb.Equals("get", StringComparison.Ordinal))
            {
                s_get.CopyTo(payload);
                totalWritten += s_get.Length;
            }
            else if (verb.Equals("POST", StringComparison.Ordinal) || verb.Equals("post", StringComparison.Ordinal))
            {
                s_post.CopyTo(payload);
                totalWritten += s_post.Length;
            }
            else if (verb.Equals("DELETE", StringComparison.Ordinal) || verb.Equals("delete", StringComparison.Ordinal))
            {
                s_delete.CopyTo(payload);
                totalWritten += s_delete.Length;
            }
            else
            {
                if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != TransformationStatus.Done)
                {
                    throw new NotImplementedException("need to resize buffer");
                }
                if (Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != TransformationStatus.Done)
                {
                    throw new NotImplementedException("need to resize buffer");
                }

                payload[written] = (byte)'\n';
                totalWritten    += written + 1;
            }

            bufferSlice = payload.Slice(totalWritten);

            if (Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            if (Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            bufferSlice[written] = (byte)'\n';
            totalWritten        += written + 1;
            bufferSlice          = payload.Slice(totalWritten);

            if (Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            bufferSlice[written] = (byte)'\n';
            totalWritten        += written + 1;
            bufferSlice          = payload.Slice(totalWritten);

            if (!Text.Formatters.Utf8.TryFormat(utc, bufferSlice, out written, 'l'))
            {
                throw new NotImplementedException("need to resize buffer");
            }
            bufferSlice[written] = (byte)'\n';
            totalWritten        += written + 1;
            bufferSlice          = payload.Slice(totalWritten);

            bufferSlice[0] = (byte)'\n';
            totalWritten  += 1;

            hash.Append(buffer.Slice(front.Length, totalWritten));
            hash.GetHash(buffer.Slice(front.Length, hash.OutputSize));
            if (!Base64.EncodeInPlace(buffer.Slice(front.Length), hash.OutputSize, out written))
            {
                throw new NotImplementedException("need to resize buffer");
            }

            var len = front.Length + written;

            if (!UrlEncoder.TryEncode(buffer.Slice(0, len), output, out bytesWritten))
            {
                bytesWritten = 0;
                return(false);
            }
            return(true);
        }
Example #24
0
 public Rune[] Stringier() => Utf16.Decode(Buffer);
Example #25
0
 public void IsFirstUnit(UInt16 unit, Boolean expected) => Assert.Equal(expected, Utf16.IsFirstUnit(unit));
Example #26
0
 public void NextUnitRange(UInt16 unit, UInt16 lowerExp, UInt16 upperExp)
 {
     Utf16.NextUnitRange(unit, out UInt16 lower, out UInt16 upper);
     Assert.Equal(lowerExp, lower);
     Assert.Equal(upperExp, upper);
 }
Example #27
0
 public void SequenceLength(UInt16 unit, Int32 expected) => Assert.Equal(expected, Utf16.SequenceLength(unit));
Example #28
0
 /// <summary>
 /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes.
 ///
 /// This method will consume as many of the input bytes as possible.
 ///
 /// On successful exit, the entire input was consumed and encoded successfully. In this case, <paramref name="bytesConsumed"/> will be
 /// equal to the length of the <paramref name="source"/> and <paramref name="bytesWritten"/> will equal the total number of bytes written to
 /// the <paramref name="destination"/>.
 /// </summary>
 /// <param name="source">A span containing a sequence of UTF-16 bytes.</param>
 /// <param name="destination">A span to write the UTF-8 bytes into.</param>
 /// <param name="bytesConsumed">On exit, contains the number of bytes that were consumed from the <paramref name="source"/>.</param>
 /// <param name="bytesWritten">On exit, contains the number of bytes written to <paramref name="destination"/></param>
 /// <returns>A <see cref="OperationStatus"/> value representing the state of the conversion.</returns>
 public static OperationStatus FromUtf16(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesConsumed, out int bytesWritten)
 => Utf16.ToUtf8(source, destination, out bytesConsumed, out bytesWritten);
Example #29
0
        public static bool TryWrite(Span <byte> output, Sha256 hash, string verb, string canonicalizedResource, DateTime utc, out int bytesWritten)
        {
            int written, consumed;

            bytesWritten = 0;

            if (verb.Equals("GET", StringComparison.Ordinal))
            {
                if (output.Length < 3)
                {
                    bytesWritten = 0;
                    return(false);
                }
                s_GET.CopyTo(output);
                bytesWritten += s_GET.Length;
            }
            else
            {
                if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), output, out consumed, out written) != TransformationStatus.Done)
                {
                    bytesWritten = 0;
                    return(false);
                }

                output[written] = (byte)'\n';
                bytesWritten   += written + 1;
            }

            var free = output.Slice(bytesWritten);

            s_emptyHeaders.CopyTo(free);
            bytesWritten += s_emptyHeaders.Length;

            free = output.Slice(bytesWritten);
            if (!Text.Formatters.Utf8.TryFormat(utc, free, out written, 'R'))
            {
                bytesWritten = 0;
                return(false);
            }
            free[written] = (byte)'\n';
            bytesWritten += written + 1;
            free          = output.Slice(bytesWritten);

            if (Utf16.ToUtf8(canonicalizedResource.AsReadOnlySpan().AsBytes(), free, out consumed, out written) != TransformationStatus.Done)
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += written;

            var formatted = output.Slice(0, bytesWritten);

            hash.Append(formatted);
            hash.GetHash(output.Slice(0, hash.OutputSize));

            if (!Base64.EncodeInPlace(output, hash.OutputSize, out written))
            {
                bytesWritten = 0;
                return(false);
            }

            bytesWritten = written;
            return(true);
        }
        // char... -> Rune...
        public static IEnumerable <Rune> ToRunes(this IEnumerable <char> chars)
        {
            var decoder = new Utf16.CharDecoder();

            return(DecodeValues(chars, decoder, Utf16.MissingTrailingSurrogateMessage()));
        }