Exemplo n.º 1
0
        private static void AppendStringInternal(this IWriter writer, string value, int startIndex, int endIndex)
        {
            for (var i = startIndex; i <= endIndex;)
            {
                UnicodeCodePoint codePoint;
                int encodedChars;
                var success = Utf16LittleEndianEncoder.TryDecodeCodePointFromString(value, i, out codePoint, out encodedChars);
                if (!success)
                {
                    throw new ArgumentException();
                }
                i += encodedChars;

                int encodedBytes;
                success = Utf8Encoder.TryEncodeCodePoint(
                    codePoint,
                    writer.GetFreeBuffer(MaxUtf8CodePointBytes).ToSpan(),
                    out encodedBytes);
                Debug.Assert(success);
                writer.CommitBytes(encodedBytes);
            }
        }
Exemplo n.º 2
0
        // TODO: This should return Utf16CodeUnits which should wrap byte[]/Span<byte>, same for other encoders
        private static byte[] GetUtf8BytesFromString(string s)
        {
            int len = 0;

            for (int i = 0; i < s.Length; /* intentionally no increment */)
            {
                UnicodeCodePoint codePoint;
                int encodedChars;
                if (!Utf16LittleEndianEncoder.TryDecodeCodePointFromString(s, i, out codePoint, out encodedChars))
                {
                    throw new ArgumentException("s", "Invalid surrogate pair in the string.");
                }

                if (encodedChars <= 0)
                {
                    // TODO: Fix exception type
                    throw new Exception("internal error");
                }

                int encodedBytes = Utf8Encoder.GetNumberOfEncodedBytes(codePoint);
                if (encodedBytes == 0)
                {
                    // TODO: Fix exception type
                    throw new Exception("Internal error: Utf16Decoder somehow got CodePoint out of range");
                }
                len += encodedBytes;

                i += encodedChars;
            }

            byte[] bytes = new byte[len];
            unsafe
            {
                fixed(byte *array_pinned = bytes)
                {
                    Span <byte> p = new Span <byte>(array_pinned, len);

                    for (int i = 0; i < s.Length; /* intentionally no increment */)
                    {
                        UnicodeCodePoint codePoint;
                        int encodedChars;
                        if (Utf16LittleEndianEncoder.TryDecodeCodePointFromString(s, i, out codePoint, out encodedChars))
                        {
                            i += encodedChars;
                            int encodedBytes;
                            if (Utf8Encoder.TryEncodeCodePoint(codePoint, p, out encodedBytes))
                            {
                                p = p.Slice(encodedBytes);
                            }
                            else
                            {
                                // TODO: Fix exception type
                                throw new Exception("Internal error: Utf16Decoder somehow got CodePoint out of range or the buffer is too small");
                            }
                        }
                        else
                        {
                            // TODO: Fix exception type
                            throw new Exception("Internal error: we did pre-validation of the string, nothing should go wrong");
                        }
                    }
                }
            }

            return(bytes);
        }