/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.util;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

/**
 * Collection of string handling utilities
 */
@Internal
public class StringUtil {
    protected static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
    //arbitrarily selected; may need to increase
    private static final int MAX_RECORD_LENGTH = 10000000;

    public static final Charset UTF16LE = StandardCharsets.UTF_16LE;
    public static final Charset UTF8 = StandardCharsets.UTF_8;
    public static final Charset WIN_1252 = Charset.forName("cp1252");
    public static final Charset BIG5 = Charset.forName("Big5");

    private static Map<Integer, Integer> msCodepointToUnicode;

    private StringUtil() {
        // no instances of this class
    }

    /**
     * Given a byte array of 16-bit unicode characters in Little Endian
     * format (most important byte last), return a Java String representation
     * of it.
     * <p>
     * { 0x16, 0x00 } -0x16
     *
     * @param string the byte array to be converted
     * @param offset the initial offset into the
     *               byte array. it is assumed that string[ offset ] and string[ offset +
     *               1 ] contain the first 16-bit unicode character
     * @param len    the length of the final string
     * @return the converted string, never <code>null</code>.
     * @throws ArrayIndexOutOfBoundsException if offset is out of bounds for
     *                                        the byte array (i.e., is negative or is greater than or equal to
     *                                        string.length)
     * @throws IllegalArgumentException       if len is too large (i.e.,
     *                                        there is not enough data in string to create a String of that
     *                                        length)
     */
    public static String getFromUnicodeLE(
            final byte[] string,
            final int offset,
            final int len)
            throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
        if ((offset < 0) || (offset >= string.length)) {
            throw new ArrayIndexOutOfBoundsException("Illegal offset " + offset + " (String data is of length " + string.length + ")");
        }
        if ((len < 0) || (((string.length - offset) / 2) < len)) {
            throw new IllegalArgumentException("Illegal length " + len);
        }

        return new String(string, offset, len * 2, UTF16LE);
    }

    /**
     * Given a byte array of 16-bit unicode characters in little endian
     * format (most important byte last), return a Java String representation
     * of it.
     * <p>
     * { 0x16, 0x00 } -0x16
     *
     * @param string the byte array to be converted
     * @return the converted string, never <code>null</code>
     */
    public static String getFromUnicodeLE(byte[] string) {
        if (string.length == 0) {
            return "";
        }
        return getFromUnicodeLE(string, 0, string.length / 2);
    }

    /**
     * Convert String to 16-bit unicode characters in little endian format
     *
     * @param string the string
     * @return the byte array of 16-bit unicode characters
     */
    public static byte[] getToUnicodeLE(String string) {
        return string.getBytes(UTF16LE);
    }

    /**
     * Read 8 bit data (in ISO-8859-1 codepage) into a (unicode) Java
     * String and return.
     * (In Excel terms, read compressed 8 bit unicode as a string)
     *
     * @param string byte array to read
     * @param offset offset to read byte array
     * @param len    length to read byte array
     * @return String generated String instance by reading byte array
     */
    public static String getFromCompressedUnicode(
            final byte[] string,
            final int offset,
            final int len) {
        int len_to_use = Math.min(len, string.length - offset);
        return new String(string, offset, len_to_use, ISO_8859_1);
    }

    public static String readCompressedUnicode(LittleEndianInput in, int nChars) {
        byte[] buf = IOUtils.safelyAllocate(nChars, MAX_RECORD_LENGTH);
        in.readFully(buf);
        return new String(buf, ISO_8859_1);
    }

    /**
     * InputStream <tt>in</tt> is expected to contain:
     * <ol>
     * <li>ushort nChars</li>
     * <li>byte is16BitFlag</li>
     * <li>byte[]/char[] characterData</li>
     * </ol>
     * For this encoding, the is16BitFlag is always present even if nChars==0.
     * <p>
     * This structure is also known as a XLUnicodeString.
     */
    public static String readUnicodeString(LittleEndianInput in) {

        int nChars = in.readUShort();
        byte flag = in.readByte();
        if ((flag & 0x01) == 0) {
            return readCompressedUnicode(in, nChars);
        }
        return readUnicodeLE(in, nChars);
    }

    /**
     * InputStream <tt>in</tt> is expected to contain:
     * <ol>
     * <li>byte is16BitFlag</li>
     * <li>byte[]/char[] characterData</li>
     * </ol>
     * For this encoding, the is16BitFlag is always present even if nChars==0.
     * <br>
     * This method should be used when the nChars field is <em>not</em> stored
     * as a ushort immediately before the is16BitFlag. Otherwise, {@link
     * #readUnicodeString(LittleEndianInput)} can be used.
     */
    public static String readUnicodeString(LittleEndianInput in, int nChars) {
        byte is16Bit = in.readByte();
        if ((is16Bit & 0x01) == 0) {
            return readCompressedUnicode(in, nChars);
        }
        return readUnicodeLE(in, nChars);
    }

    /**
     * OutputStream <tt>out</tt> will get:
     * <ol>
     * <li>ushort nChars</li>
     * <li>byte is16BitFlag</li>
     * <li>byte[]/char[] characterData</li>
     * </ol>
     * For this encoding, the is16BitFlag is always present even if nChars==0.
     */
    public static void writeUnicodeString(LittleEndianOutput out, String value) {
        int nChars = value.length();
        out.writeShort(nChars);
        boolean is16Bit = hasMultibyte(value);
        out.writeByte(is16Bit ? 0x01 : 0x00);
        if (is16Bit) {
            putUnicodeLE(value, out);
        } else {
            putCompressedUnicode(value, out);
        }
    }

    /**
     * OutputStream <tt>out</tt> will get:
     * <ol>
     * <li>byte is16BitFlag</li>
     * <li>byte[]/char[] characterData</li>
     * </ol>
     * For this encoding, the is16BitFlag is always present even if nChars==0.
     * <br>
     * This method should be used when the nChars field is <em>not</em> stored
     * as a ushort immediately before the is16BitFlag. Otherwise, {@link
     * #writeUnicodeString(LittleEndianOutput, String)} can be used.
     */
    public static void writeUnicodeStringFlagAndData(LittleEndianOutput out, String value) {
        boolean is16Bit = hasMultibyte(value);
        out.writeByte(is16Bit ? 0x01 : 0x00);
        if (is16Bit) {
            putUnicodeLE(value, out);
        } else {
            putCompressedUnicode(value, out);
        }
    }

    /**
     * @return the number of bytes that would be written by {@link #writeUnicodeString(LittleEndianOutput, String)}
     */
    public static int getEncodedSize(String value) {
        int result = 2 + 1;
        result += value.length() * (StringUtil.hasMultibyte(value) ? 2 : 1);
        return result;
    }

    /**
     * Takes a unicode (java) string, and returns it as 8 bit data (in ISO-8859-1
     * codepage).
     * (In Excel terms, write compressed 8 bit unicode)
     *
     * @param input  the String containing the data to be written
     * @param output the byte array to which the data is to be written
     * @param offset an offset into the byte arrat at which the data is start
     *               when written
     */
    public static void putCompressedUnicode(String input, byte[] output, int offset) {
        byte[] bytes = input.getBytes(ISO_8859_1);
        System.arraycopy(bytes, 0, output, offset, bytes.length);
    }

    public static void putCompressedUnicode(String input, LittleEndianOutput out) {
        byte[] bytes = input.getBytes(ISO_8859_1);
        out.write(bytes);
    }

    /**
     * Takes a unicode string, and returns it as little endian (most
     * important byte last) bytes in the supplied byte array.
     * (In Excel terms, write uncompressed unicode)
     *
     * @param input  the String containing the unicode data to be written
     * @param output the byte array to hold the uncompressed unicode, should be twice the length of the String
     * @param offset the offset to start writing into the byte array
     */
    public static void putUnicodeLE(String input, byte[] output, int offset) {
        byte[] bytes = input.getBytes(UTF16LE);
        System.arraycopy(bytes, 0, output, offset, bytes.length);
    }

    public static void putUnicodeLE(String input, LittleEndianOutput out) {
        byte[] bytes = input.getBytes(UTF16LE);
        out.write(bytes);
    }

    public static String readUnicodeLE(LittleEndianInput in, int nChars) {
        byte[] bytes = IOUtils.safelyAllocate(nChars * 2, MAX_RECORD_LENGTH);
        in.readFully(bytes);
        return new String(bytes, UTF16LE);
    }

    /**
     * @return the encoding we want to use, currently hardcoded to ISO-8859-1
     */
    public static String getPreferredEncoding() {
        return ISO_8859_1.name();
    }

    /**
     * check the parameter has multibyte character
     *
     * @param value string to check
     * @return boolean result true:string has at least one multibyte character
     */
    public static boolean hasMultibyte(String value) {
        if (value == null)
            return false;
        for (char c : value.toCharArray()) {
            if (c > 0xFF) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks to see if a given String needs to be represented as Unicode
     *
     * @param value The string to look at.
     * @return true if string needs Unicode to be represented.
     */
    public static boolean isUnicodeString(final String value) {
        return !value.equals(new String(value.getBytes(ISO_8859_1), ISO_8859_1));
    }

    /**
     * Tests if the string starts with the specified prefix, ignoring case consideration.
     */
    public static boolean startsWithIgnoreCase(String haystack, String prefix) {
        return haystack.regionMatches(true, 0, prefix, 0, prefix.length());
    }

    /**
     * Tests if the string ends with the specified suffix, ignoring case consideration.
     */
    public static boolean endsWithIgnoreCase(String haystack, String suffix) {
        int length = suffix.length();
        int start = haystack.length() - length;
        return haystack.regionMatches(true, start, suffix, 0, length);
    }

    /**
     * An Iterator over an array of Strings.
     */
    public static class StringsIterator implements Iterator<String> {
        private String[] strings = {};
        private int position;

        public StringsIterator(String[] strings) {
            if (strings != null) {
                this.strings = strings.clone();
            }
        }

        public boolean hasNext() {
            return position < strings.length;
        }

        public String next() {
            int ourPos = position++;
            if (ourPos >= strings.length) {
                throw new ArrayIndexOutOfBoundsException(ourPos);
            }
            return strings[ourPos];
        }

        public void remove() {
        }
    }

    @Internal
    public static String toLowerCase(char c) {
        return Character.toString(c).toLowerCase(Locale.ROOT);
    }

    @Internal
    public static String toUpperCase(char c) {
        return Character.toString(c).toUpperCase(Locale.ROOT);
    }

    @Internal
    public static boolean isUpperCase(char c) {
        String s = Character.toString(c);
        return s.toUpperCase(Locale.ROOT).equals(s);
    }

    /**
     * Some strings may contain encoded characters of the unicode private use area.
     * Currently the characters of the symbol fonts are mapped to the corresponding
     * characters in the normal unicode range.
     *
     * @param string the original string
     * @return the string with mapped characters
     * @see <a href="http://www.alanwood.net/unicode/private_use_area.html#symbol">Private Use Area (symbol)</a>
     * @see <a href="http://www.alanwood.net/demos/symbol.html">Symbol font - Unicode alternatives for Greek and special characters in HTML</a>
     */
    public static String mapMsCodepointString(String string) {
        if (string == null || string.isEmpty()) return string;
        initMsCodepointMap();

        StringBuilder sb = new StringBuilder();
        final int length = string.length();
        for (int offset = 0; offset < length; ) {
            Integer msCodepoint = string.codePointAt(offset);
            Integer uniCodepoint = msCodepointToUnicode.get(msCodepoint);
            sb.appendCodePoint(uniCodepoint == null ? msCodepoint : uniCodepoint);
            offset += Character.charCount(msCodepoint);
        }

        return sb.toString();
    }

    public static synchronized void mapMsCodepoint(int msCodepoint, int unicodeCodepoint) {
        initMsCodepointMap();
        msCodepointToUnicode.put(msCodepoint, unicodeCodepoint);
    }

    private static synchronized void initMsCodepointMap() {
        if (msCodepointToUnicode != null) return;
        msCodepointToUnicode = new HashMap<>();
        int i = 0xF020;
        for (int ch : symbolMap_f020) {
            msCodepointToUnicode.put(i++, ch);
        }
        i = 0xf0a0;
        for (int ch : symbolMap_f0a0) {
            msCodepointToUnicode.put(i++, ch);
        }
    }

    private static final int symbolMap_f020[] = {
            ' ', // 0xf020 space
            '!', // 0xf021 exclam
            8704, // 0xf022 universal
            '#', // 0xf023 numbersign
            8707, // 0xf024 existential
            '%', // 0xf025 percent
            '&', // 0xf026 ampersand
            8717, // 0xf027 suchthat
            '(', // 0xf028 parenleft
            ')', // 0xf029 parentright
            8727, // 0xf02a asteriskmath
            '+', // 0xf02b plus
            ',', // 0xf02c comma
            8722, // 0xf02d minus sign (long -)
            '.', // 0xf02e period
            '/', // 0xf02f slash
            '0', // 0xf030 0
            '1', // 0xf031 1
            '2', // 0xf032 2
            '3', // 0xf033 3
            '4', // 0xf034 4
            '5', // 0xf035 5
            '6', // 0xf036 6
            '7', // 0xf037 7
            '8', // 0xf038 8
            '9', // 0xf039 9
            ':', // 0xf03a colon
            ';', // 0xf03b semicolon
            '<', // 0xf03c less
            '=', // 0xf03d equal
            '>', // 0xf03e greater
            '?', // 0xf03f question
            8773, // 0xf040 congruent
            913, // 0xf041 alpha (upper)
            914, // 0xf042 beta (upper)
            935, // 0xf043 chi (upper)
            916, // 0xf044 delta (upper)
            917, // 0xf045 epsilon (upper)
            934, // 0xf046 phi (upper)
            915, // 0xf047 gamma (upper)
            919, // 0xf048 eta (upper)
            921, // 0xf049 iota (upper)
            977, // 0xf04a theta1 (lower)
            922, // 0xf04b kappa (upper)
            923, // 0xf04c lambda (upper)
            924, // 0xf04d mu (upper)
            925, // 0xf04e nu (upper)
            927, // 0xf04f omicron (upper)
            928, // 0xf050 pi (upper)
            920, // 0xf051 theta (upper)
            929, // 0xf052 rho (upper)
            931, // 0xf053 sigma (upper)
            932, // 0xf054 tau (upper)
            933, // 0xf055 upsilon (upper)
            962, // 0xf056 simga1 (lower)
            937, // 0xf057 omega (upper)
            926, // 0xf058 xi (upper)
            936, // 0xf059 psi (upper)
            918, // 0xf05a zeta (upper)
            '[', // 0xf05b bracketleft
            8765, // 0xf05c therefore
            ']', // 0xf05d bracketright
            8869, // 0xf05e perpendicular
            '_', // 0xf05f underscore
            ' ', // 0xf060 radicalex (doesn't exist in unicode)
            945, // 0xf061 alpha (lower)
            946, // 0xf062 beta (lower)
            967, // 0xf063 chi (lower)
            948, // 0xf064 delta (lower)
            949, // 0xf065 epsilon (lower)
            966, // 0xf066 phi (lower)
            947, // 0xf067 gamma (lower)
            951, // 0xf068 eta (lower)
            953, // 0xf069 iota (lower)
            981, // 0xf06a phi1 (lower)
            954, // 0xf06b kappa (lower)
            955, // 0xf06c lambda (lower)
            956, // 0xf06d mu (lower)
            957, // 0xf06e nu (lower)
            959, // 0xf06f omnicron (lower)
            960, // 0xf070 pi (lower)
            952, // 0xf071 theta (lower)
            961, // 0xf072 rho (lower)
            963, // 0xf073 sigma (lower)
            964, // 0xf074 tau (lower)
            965, // 0xf075 upsilon (lower)
            982, // 0xf076 piv (lower)
            969, // 0xf077 omega (lower)
            958, // 0xf078 xi (lower)
            968, // 0xf079 psi (lower)
            950, // 0xf07a zeta (lower)
            '{', // 0xf07b braceleft
            '|', // 0xf07c bar
            '}', // 0xf07d braceright
            8764, // 0xf07e similar '~'
            ' ', // 0xf07f not defined
    };

    private static final int symbolMap_f0a0[] = {
            8364, // 0xf0a0 not defined / euro symbol
            978, // 0xf0a1 upsilon1 (upper)
            8242, // 0xf0a2 minute
            8804, // 0xf0a3 lessequal
            8260, // 0xf0a4 fraction
            8734, // 0xf0a5 infinity
            402, // 0xf0a6 florin
            9827, // 0xf0a7 club
            9830, // 0xf0a8 diamond
            9829, // 0xf0a9 heart
            9824, // 0xf0aa spade
            8596, // 0xf0ab arrowboth
            8591, // 0xf0ac arrowleft
            8593, // 0xf0ad arrowup
            8594, // 0xf0ae arrowright
            8595, // 0xf0af arrowdown
            176, // 0xf0b0 degree
            177, // 0xf0b1 plusminus
            8243, // 0xf0b2 second
            8805, // 0xf0b3 greaterequal
            215, // 0xf0b4 multiply
            181, // 0xf0b5 proportional
            8706, // 0xf0b6 partialdiff
            8729, // 0xf0b7 bullet
            247, // 0xf0b8 divide
            8800, // 0xf0b9 notequal
            8801, // 0xf0ba equivalence
            8776, // 0xf0bb approxequal
            8230, // 0xf0bc ellipsis
            9168, // 0xf0bd arrowvertex
            9135, // 0xf0be arrowhorizex
            8629, // 0xf0bf carriagereturn
            8501, // 0xf0c0 aleph
            8475, // 0xf0c1 Ifraktur
            8476, // 0xf0c2 Rfraktur
            8472, // 0xf0c3 weierstrass
            8855, // 0xf0c4 circlemultiply
            8853, // 0xf0c5 circleplus
            8709, // 0xf0c6 emptyset
            8745, // 0xf0c7 intersection
            8746, // 0xf0c8 union
            8835, // 0xf0c9 propersuperset
            8839, // 0xf0ca reflexsuperset
            8836, // 0xf0cb notsubset
            8834, // 0xf0cc propersubset
            8838, // 0xf0cd reflexsubset
            8712, // 0xf0ce element
            8713, // 0xf0cf notelement
            8736, // 0xf0d0 angle
            8711, // 0xf0d1 gradient
            174, // 0xf0d2 registerserif
            169, // 0xf0d3 copyrightserif
            8482, // 0xf0d4 trademarkserif
            8719, // 0xf0d5 product
            8730, // 0xf0d6 radical
            8901, // 0xf0d7 dotmath
            172, // 0xf0d8 logicalnot
            8743, // 0xf0d9 logicaland
            8744, // 0xf0da logicalor
            8660, // 0xf0db arrowdblboth
            8656, // 0xf0dc arrowdblleft
            8657, // 0xf0dd arrowdblup
            8658, // 0xf0de arrowdblright
            8659, // 0xf0df arrowdbldown
            9674, // 0xf0e0 lozenge
            9001, // 0xf0e1 angleleft
            174, // 0xf0e2 registersans
            169, // 0xf0e3 copyrightsans
            8482, // 0xf0e4 trademarksans
            8721, // 0xf0e5 summation
            9115, // 0xf0e6 parenlefttp
            9116, // 0xf0e7 parenleftex
            9117, // 0xf0e8 parenleftbt
            9121, // 0xf0e9 bracketlefttp
            9122, // 0xf0ea bracketleftex
            9123, // 0xf0eb bracketleftbt
            9127, // 0xf0ec bracelefttp
            9128, // 0xf0ed braceleftmid
            9129, // 0xf0ee braceleftbt
            9130, // 0xf0ef braceex
            ' ', // 0xf0f0 not defined
            9002, // 0xf0f1 angleright
            8747, // 0xf0f2 integral
            8992, // 0xf0f3 integraltp
            9134, // 0xf0f4 integralex
            8993, // 0xf0f5 integralbt
            9118, // 0xf0f6 parenrighttp
            9119, // 0xf0f7 parenrightex
            9120, // 0xf0f8 parenrightbt
            9124, // 0xf0f9 bracketrighttp
            9125, // 0xf0fa bracketrightex
            9126, // 0xf0fb bracketrightbt
            9131, // 0xf0fc bracerighttp
            9132, // 0xf0fd bracerightmid
            9133, // 0xf0fe bracerightbt
            ' ', // 0xf0ff not defined
    };


    // Could be replaced with org.apache.commons.lang3.StringUtils#join
    @Internal
    public static String join(Object[] array, String separator) {
        if (array == null || array.length == 0) return "";
        StringBuilder sb = new StringBuilder();
        sb.append(array[0]);
        for (int i = 1; i < array.length; i++) {
            sb.append(separator).append(array[i]);
        }
        return sb.toString();
    }

    @Internal
    public static String join(Object[] array) {
        if (array == null) return "";
        StringBuilder sb = new StringBuilder();
        for (Object o : array) {
            sb.append(o);
        }
        return sb.toString();
    }

    @Internal
    public static String join(String separator, Object... array) {
        return join(array, separator);
    }

    /**
     * Count number of occurrences of needle in haystack
     * Has same signature as org.apache.commons.lang3.StringUtils#countMatches
     *
     * @param haystack the CharSequence to check, may be null
     * @param needle   the character to count the quantity of
     * @return the number of occurrences, 0 if the CharSequence is null
     */
    public static int countMatches(CharSequence haystack, char needle) {
        if (haystack == null) return 0;
        int count = 0;
        final int length = haystack.length();
        for (int i = 0; i < length; i++) {
            if (haystack.charAt(i) == needle) {
                count++;
            }
        }
        return count;
    }


    /**
     * Given a byte array of 16-bit unicode characters in Little Endian
     * format (most important byte last), return a Java String representation
     * of it.
     *
     * Scans the byte array for two continous 0 bytes and returns the string before.
     * <p>
     *
     * #61881: there seem to be programs out there, which write the 0-termination also
     * at the beginning of the string. Check if the next two bytes contain a valid ascii char
     * and correct the _recdata with a '?' char
     *
     *
     * @param string the byte array to be converted
     * @param offset the initial offset into the
     *               byte array. it is assumed that string[ offset ] and string[ offset +
     *               1 ] contain the first 16-bit unicode character
     * @param len    the max. length of the final string
     * @return the converted string, never <code>null</code>.
     * @throws ArrayIndexOutOfBoundsException if offset is out of bounds for
     *                                        the byte array (i.e., is negative or is greater than or equal to
     *                                        string.length)
     * @throws IllegalArgumentException       if len is too large (i.e.,
     *                                        there is not enough data in string to create a String of that
     *                                        length)
     */
    public static String getFromUnicodeLE0Terminated(
            final byte[] string,
            final int offset,
            final int len)
            throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
        if ((offset < 0) || (offset >= string.length)) {
            throw new ArrayIndexOutOfBoundsException("Illegal offset " + offset + " (String data is of length " + string.length + ")");
        }

        if ((len < 0) || (((string.length - offset) / 2) < len)) {
            throw new IllegalArgumentException("Illegal length " + len);
        }

        final int newOffset;
        final int newMaxLen;
        final String prefix;

        // #61881 - for now we only check the first char
        if (len > 0 && string[offset] == 0 && string[offset+1] == 0) {
            newOffset = offset+2;
            prefix = "?";

            // check if the next char is garbage and limit the len if necessary
            final int cp = (len > 1) ? LittleEndian.getShort(string, offset+2) : 0;
            newMaxLen = Character.isJavaIdentifierPart(cp) ? len-1 : 0;
        } else {
            newOffset = offset;
            prefix = "";
            newMaxLen = len;
        }

        int newLen = 0;

        // loop until we find a null-terminated end
        for(; newLen < newMaxLen; newLen++) {
            if (string[newOffset + newLen * 2] == 0 && string[newOffset + newLen * 2 + 1] == 0) {
                break;
            }
        }
        newLen = Math.min(newLen, newMaxLen);

        return prefix + ((newLen == 0) ? "" : new String(string, newOffset, newLen * 2, UTF16LE));
    }

}
