@@ -0,0 +1,3151 @@
+/*%0A* Licensed to the Apache Software Foundation (ASF) under one or more%0A* contributor license agreements.  See the NOTICE file distributed with%0A* this work for additional information regarding copyright ownership.%0A* The ASF licenses this file to You under the Apache License, Version 2.0%0A* (the %22License%22); you may not use this file except in compliance with%0A* the License.  You may obtain a copy of the License at%0A*%0A*     http://www.apache.org/licenses/LICENSE-2.0%0A*%0A* Unless required by applicable law or agreed to in writing, software%0A* distributed under the License is distributed on an %22AS IS%22 BASIS,%0A* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A* See the License for the specific language governing permissions and%0A* limitations under the License.%0A*/%0Apackage org.apache.jackrabbit.oak.plugins.document.util;%0A%0Aimport static org.junit.Assert.assertArrayEquals;%0Aimport static org.junit.Assert.assertEquals;%0Aimport static org.junit.Assert.fail;%0A%0Aimport java.io.IOException;%0Aimport java.nio.charset.StandardCharsets;%0Aimport java.util.UUID;%0A%0Aimport org.junit.Test;%0A%0Apublic class UTF8EncoderTest %7B%0A%0A    private static char%5B%5D SURROGATE_PAIR = Character.toChars(0x1f4a9);%0A%0A    @Test%0A    public void encodeValid() throws IOException %7B%0A%0A        // a a-umlaut euro plane-1-char%0A        String test = %22a %5Cu00E4 %5Cu20ac %22 + new String(SURROGATE_PAIR);%0A%0A        byte%5B%5D withStringClass = test.getBytes(StandardCharsets.UTF_8);%0A        byte%5B%5D withUtilsClass = UTF8Encoder.encodeAsByteArray(test);%0A        assertArrayEquals(withStringClass, withUtilsClass);%0A        assertEquals(test, new String(withUtilsClass, StandardCharsets.UTF_8));%0A    %7D%0A%0A    @Test%0A    public void encodeInValid() %7B%0A%0A        // a a-umlaut euro plane-1-char, second char in surrogate pair missing%0A        String test = %22a %5Cu00E4 %5Cu20ac %22 + SURROGATE_PAIR%5B0%5D;%0A%0A        try %7B%0A            UTF8Encoder.encodeAsByteArray(test);%0A            fail(%22expected encoding to fail%22);%0A        %7D catch (IOException expected) %7B%0A            // expected%0A        %7D%0A    %7D%0A%0A    @Test%0A    public void encodeMultiThreaded() throws InterruptedException %7B%0A%0A        int tc = 20;%0A%0A        Thread%5B%5D threads = new Thread%5Btc%5D;%0A%0A        for (int i = 0; i %3C tc; i++) %7B%0A            threads%5Bi%5D = new Thread(new Runnable() %7B%0A                @Override%0A                public void run() %7B%0A                    // encode and decode 100 random UUID strings%0A                    for (int j = 0; j %3C 100; j++) %7B%0A                        String test = UUID.randomUUID().toString();%0A                        String roundtripped = null;%0A                        try %7B%0A                            byte%5B%5D bytes = UTF8Encoder.encodeAsByteArray(test);%0A                            roundtripped = new String(bytes, StandardCharsets.UTF_8);%0A                        %7D catch (IOException exignored) %7B%0A                        %7D%0A                        assertEquals(test, roundtripped);%0A                    %7D%0A%0A                %7D%0A            %7D);%0A        %7D%0A        for (int i = 0; i %3C tc; i++) %7B%0A            threads%5Bi%5D.start();%0A        %7D%0A        for (int i = 0; i %3C tc; i++) %7B%0A            threads%5Bi%5D.join();%0A        %7D%0A    %7D%0A%7D%0A

Create charset encoding utility that detects malformed input