/*
 * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include <wtf/unicode/UTF8Conversion.h>

#include <wtf/ASCIICType.h>
#include <wtf/text/StringHasher.h>
#include <wtf/unicode/CharacterNames.h>

namespace WTF {
namespace Unicode {

bool convertLatin1ToUTF8(const LChar** sourceStart, const LChar* sourceEnd, char** targetStart, char* targetEnd)
{
    const LChar* source;
    char* target = *targetStart;
    int i = 0;
    for (source = *sourceStart; source < sourceEnd; ++source) {
        UBool sawError = false;
        // Work around bug in either Windows compiler or old version of ICU, where passing a uint8_t to
        // U8_APPEND warns, by converting from uint8_t to a wider type.
        UChar32 character = *source;
        U8_APPEND(reinterpret_cast<uint8_t*>(target), i, targetEnd - *targetStart, character, sawError);
        if (sawError)
            return false;
    }
    *sourceStart = source;
    *targetStart = target + i;
    return true;
}

ConversionResult convertUTF16ToUTF8(const UChar** sourceStart, const UChar* sourceEnd, char** targetStart, char* targetEnd, bool strict)
{
    ConversionResult result = ConversionOK;
    const UChar* source = *sourceStart;
    char* target = *targetStart;
    UBool sawError = false;
    int i = 0;
    while (source < sourceEnd) {
        UChar32 ch;
        int j = 0;
        U16_NEXT(source, j, sourceEnd - source, ch);
        if (U_IS_SURROGATE(ch)) {
            if (source + j == sourceEnd && U_IS_SURROGATE_LEAD(ch)) {
                result = SourceExhausted;
                break;
            }
            if (strict) {
                result = SourceIllegal;
                break;
            }
            ch = replacementCharacter;
        }
        U8_APPEND(reinterpret_cast<uint8_t*>(target), i, targetEnd - target, ch, sawError);
        if (sawError) {
            result = TargetExhausted;
            break;
        }
        source += j;
    }
    *sourceStart = source;
    *targetStart = target + i;
    return result;
}

template<bool replaceInvalidSequences>
bool convertUTF8ToUTF16Impl(const char* source, const char* sourceEnd, UChar** targetStart, UChar* targetEnd, bool* sourceAllASCII)
{
    RELEASE_ASSERT(sourceEnd - source <= std::numeric_limits<int>::max());
    UBool error = false;
    UChar* target = *targetStart;
    RELEASE_ASSERT(targetEnd - target <= std::numeric_limits<int>::max());
    UChar32 orAllData = 0;
    int targetOffset = 0;
    for (int sourceOffset = 0; sourceOffset < sourceEnd - source; ) {
        UChar32 character;
        if constexpr (replaceInvalidSequences) {
            U8_NEXT_OR_FFFD(reinterpret_cast<const uint8_t*>(source), sourceOffset, sourceEnd - source, character);
        } else {
            U8_NEXT(reinterpret_cast<const uint8_t*>(source), sourceOffset, sourceEnd - source, character);
        }
        if (character < 0)
            return false;
        U16_APPEND(target, targetOffset, targetEnd - target, character, error);
        if (error)
            return false;
        orAllData |= character;
    }
    RELEASE_ASSERT(target + targetOffset <= targetEnd);
    *targetStart = target + targetOffset;
    if (sourceAllASCII)
        *sourceAllASCII = isASCII(orAllData);
    return true;
}

bool convertUTF8ToUTF16(const char* source, const char* sourceEnd, UChar** targetStart, UChar* targetEnd, bool* sourceAllASCII)
{
    return convertUTF8ToUTF16Impl<false>(source, sourceEnd, targetStart, targetEnd, sourceAllASCII);
}

bool convertUTF8ToUTF16ReplacingInvalidSequences(const char* source, const char* sourceEnd, UChar** targetStart, UChar* targetEnd, bool* sourceAllASCII)
{
    return convertUTF8ToUTF16Impl<true>(source, sourceEnd, targetStart, targetEnd, sourceAllASCII);
}

unsigned calculateStringHashAndLengthFromUTF8MaskingTop8Bits(const char* data, const char* dataEnd, unsigned& dataLength, unsigned& utf16Length)
{
    StringHasher stringHasher;
    utf16Length = 0;

    int inputOffset = 0;
    int inputLength = dataEnd - data;
    while (inputOffset < inputLength) {
        UChar32 character;
        U8_NEXT(reinterpret_cast<const uint8_t*>(data), inputOffset, inputLength, character);
        if (character < 0)
            return 0;

        if (U_IS_BMP(character)) {
            ASSERT(!U_IS_SURROGATE(character));
            stringHasher.addCharacter(character);
            utf16Length++;
        } else {
            ASSERT(U_IS_SUPPLEMENTARY(character));
            stringHasher.addCharacters(U16_LEAD(character), U16_TRAIL(character));
            utf16Length += 2;
        }
    }

    dataLength = inputOffset;
    return stringHasher.hashWithTop8BitsMasked();
}

bool equalUTF16WithUTF8(const UChar* a, const char* b, const char* bEnd)
{
    while (b < bEnd) {
        int offset = 0;
        UChar32 character;
        U8_NEXT(reinterpret_cast<const uint8_t*>(b), offset, bEnd - b, character);
        if (character < 0)
            return false;
        b += offset;

        if (U_IS_BMP(character)) {
            ASSERT(!U_IS_SURROGATE(character));
            if (*a++ != character)
                return false;
        } else {
            ASSERT(U_IS_SUPPLEMENTARY(character));
            if (*a++ != U16_LEAD(character))
                return false;
            if (*a++ != U16_TRAIL(character))
                return false;
        }
    }

    return true;
}

bool equalLatin1WithUTF8(const LChar* a, const char* b, const char* bEnd)
{
    while (b < bEnd) {
        if (isASCII(*a) || isASCII(*b)) {
            if (*a++ != *b++)
                return false;
            continue;
        }

        if (b + 1 == bEnd)
            return false;

        if ((b[0] & 0xE0) != 0xC0 || (b[1] & 0xC0) != 0x80)
            return false;

        LChar character = ((b[0] & 0x1F) << 6) | (b[1] & 0x3F);

        b += 2;

        if (*a++ != character)
            return false;
    }

    return true;
}

} // namespace Unicode
} // namespace WTF
