示例#1
0
        public static CharacterEncodingResult GetLengthOfConvertedStringUtf32ToUtf8(out int length,
                                                                                    ReadOnlySpan <uint> source, int sourceLength)
        {
            UnsafeHelpers.SkipParamInit(out length);
            Span <byte> buffer = stackalloc byte[0x20];

            Assert.SdkRequires(0 <= sourceLength, $"{nameof(sourceLength)} must not be negative.");
            Assert.SdkRequires(sourceLength <= source.Length);

            int totalLength = 0;

            source = source.Slice(0, sourceLength);

            while (source.Length > 0)
            {
                CharacterEncodingResult result =
                    ConvertStringUtf32ToUtf8Impl(out int writtenCount, out int readCount, buffer, source);

                if (result == CharacterEncodingResult.InvalidFormat)
                {
                    return(CharacterEncodingResult.InvalidFormat);
                }

                totalLength += writtenCount;
                source       = source.Slice(readCount);
            }

            Assert.SdkAssert(0 <= totalLength);

            length = totalLength;
            return(CharacterEncodingResult.Success);
        }
示例#2
0
 [InlineData('\uDFFF', CharacterEncodingResult.InvalidFormat)]      // standalone low surrogate
 public void Utf16ToUtf8_WithOnlyStandaloneSurrogates(char charValue, CharacterEncodingResult expectedEncodingResult)
 {
     Utf16ToUtf8_String_Test_Core(
         utf16Input: new[] { charValue },
         destinationSize: 0,
         expectedEncodingResult: expectedEncodingResult,
         expectedUtf8Transcoding: Span <byte> .Empty);
 }
示例#3
0
        public static Result CheckCharacterCountForWindows(ReadOnlySpan <byte> path, int maxNameLength, int maxPathLength)
        {
            Assert.SdkRequiresNotNull(path);

            ReadOnlySpan <byte> currentChar = path;
            int currentNameLength           = 0;
            int currentPathLength           = 0;

            while (currentChar.Length > 1 && currentChar[0] != 0)
            {
                int utf16CodeUnitCount = GetCodePointByteLength(currentChar[0]) < 4 ? 1 : 2;

                int utf8Buffer = 0;
                CharacterEncodingResult result =
                    PickOutCharacterFromUtf8String(SpanHelpers.AsByteSpan(ref utf8Buffer), ref currentChar);

                if (result != CharacterEncodingResult.Success)
                {
                    return(ResultFs.InvalidPathFormat.Log());
                }

                result = ConvertCharacterUtf8ToUtf32(out uint pathChar, SpanHelpers.AsReadOnlyByteSpan(in utf8Buffer));

                if (result != CharacterEncodingResult.Success)
                {
                    return(ResultFs.InvalidPathFormat.Log());
                }

                currentNameLength += utf16CodeUnitCount;
                currentPathLength += utf16CodeUnitCount;

                if (pathChar == '/' || pathChar == '\\')
                {
                    currentNameLength = 0;
                }

                if (maxNameLength > 0 && currentNameLength > maxNameLength)
                {
                    return(ResultFs.TooLongPath.Log());
                }

                if (maxPathLength > 0 && currentPathLength > maxPathLength)
                {
                    return(ResultFs.TooLongPath.Log());
                }
            }

            return(Result.Success);
        }
示例#4
0
        public static CharacterEncodingResult ConvertStringUtf32ToUtf8(Span <byte> destination,
                                                                       ReadOnlySpan <uint> source)
        {
            int sourceLength = GetLengthOfUtf32(source);

            Assert.SdkAssert(0 <= sourceLength);

            CharacterEncodingResult result = ConvertStringUtf32ToUtf8Impl(out int writtenCount, out _,
                                                                          destination.Slice(0, destination.Length - 1), source.Slice(0, sourceLength));

            if (result == CharacterEncodingResult.Success)
            {
                destination[writtenCount] = 0;
            }

            return(result);
        }
示例#5
0
        public static CharacterEncodingResult ConvertStringUtf8ToUtf16Native(Span <ushort> destination,
                                                                             ReadOnlySpan <byte> source)
        {
            int length = StringUtils.GetLength(source);

            Assert.SdkAssert(0 <= length);

            CharacterEncodingResult result = ConvertStringUtf8ToUtf16Impl(out int writtenCount, out _,
                                                                          destination.Slice(0, destination.Length - 1), source.Slice(0, length));

            if (result == CharacterEncodingResult.Success)
            {
                destination[writtenCount] = 0;
            }

            return(result);
        }
示例#6
0
        [InlineData("EDA080", CharacterEncodingResult.InsufficientLength, "")]             // [ ED A0 ... ] is surrogate
        public void Utf8ToUtf16_WithSmallInvalidBuffers(string utf8HexInput, CharacterEncodingResult expectedEncodingResult, string expectedUtf16Transcoding)
        {
            Utf8ToUtf16_String_Test_Core(
                utf8Input: DecodeHex(utf8HexInput),
                destinationSize: expectedUtf16Transcoding.Length,
                expectedEncodingResult: expectedEncodingResult,
                expectedUtf16Transcoding: expectedUtf16Transcoding);

            // Now try the tests again with a larger buffer.
            // This ensures that the sequence is seen as invalid when not hitting the destination length check.

            Utf8ToUtf16_String_Test_Core(
                utf8Input: DecodeHex(utf8HexInput),
                destinationSize: expectedUtf16Transcoding.Length + 16,
                expectedEncodingResult: CharacterEncodingResult.InvalidFormat,
                expectedUtf16Transcoding: expectedUtf16Transcoding);
        }
示例#7
0
        public static CharacterEncodingResult ConvertCharacterUtf16NativeToUtf8(Span <byte> destination,
                                                                                ReadOnlySpan <ushort> source)
        {
            if (destination.Length < 4)
            {
                return(CharacterEncodingResult.InsufficientLength);
            }

            if (source.Length < 1)
            {
                return(CharacterEncodingResult.InvalidFormat);
            }

            Span <ushort> bufferSrc = stackalloc ushort[3];
            Span <byte>   bufferDst = stackalloc byte[5];

            bufferSrc[0] = source[0];
            bufferSrc[1] = 0;
            bufferSrc[2] = 0;

            // Read more code units if needed
            if (source[0] >= 0xD800 && source[0] < 0xE000)
            {
                if (source.Length < 2)
                {
                    return(CharacterEncodingResult.InvalidFormat);
                }

                bufferSrc[1] = source[1];
            }

            bufferDst.Clear();

            CharacterEncodingResult result = ConvertStringUtf16NativeToUtf8(bufferDst, bufferSrc);

            destination[0] = bufferDst[0];
            destination[1] = bufferDst[1];
            destination[2] = bufferDst[2];
            destination[3] = bufferDst[3];

            return(result);
        }