/*
**********************************************************************
*   Copyright (C) 1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   11/17/99    aliu        Creation.
**********************************************************************
*/
#include "unicode/unitohex.h"
#include "unicode/rep.h"
#include "unicode/unifilt.h"

/**
 * ID for this transliterator.
 */
const char* UnicodeToHexTransliterator::_ID = "Unicode-Hex";

const char* UnicodeToHexTransliterator::DEFAULT_PREFIX = "\\u";

/**
 * Constructs a transliterator.
 * @param prefix the string that will precede the four hex
 * digits for UNICODE_HEX transliterators.  Ignored
 * if direction is HEX_UNICODE.
 * @param uppercase if true, the four hex digits will be
 * converted to uppercase; otherwise they will be lowercase.
 * Ignored if direction is HEX_UNICODE.
 */
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
                                const UnicodeString& hexPrefix,
                                bool_t isUppercase,
                                UnicodeFilter* adoptedFilter) :
    Transliterator(_ID, adoptedFilter),
    prefix(hexPrefix),
    uppercase(isUppercase) {
}

/**
 * Constructs a transliterator with the default prefix "&#092;u"
 * that outputs uppercase hex digits.
 */
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
                                UnicodeFilter* adoptedFilter) :
    Transliterator(_ID, adoptedFilter),
    prefix(DEFAULT_PREFIX),
    uppercase(TRUE) {
}

/**
 * Copy constructor.
 */
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
                                const UnicodeToHexTransliterator& other) :
    Transliterator(other), prefix(other.prefix),
    uppercase(other.uppercase) {
}

/**
 * Assignment operator.
 */
UnicodeToHexTransliterator&
UnicodeToHexTransliterator::operator=(const UnicodeToHexTransliterator& other) {
    Transliterator::operator=(other);
    prefix = other.prefix;
    uppercase = other.uppercase;
    return *this;
}

Transliterator*
UnicodeToHexTransliterator::clone(void) const {
    return new UnicodeToHexTransliterator(*this);
}

/**
 * Returns the string that precedes the four hex digits.
 * @return prefix string
 */
const UnicodeString& UnicodeToHexTransliterator::getPrefix(void) const {
    return prefix;
}

/**
 * Sets the string that precedes the four hex digits.
 *
 * <p>Callers must take care if a transliterator is in use by
 * multiple threads.  The prefix should not be changed by one
 * thread while another thread may be transliterating.
 * @param prefix prefix string
 */
void UnicodeToHexTransliterator::setPrefix(const UnicodeString& hexPrefix) {
    prefix = hexPrefix;
}

/**
 * Returns true if this transliterator outputs uppercase hex digits.
 */
bool_t UnicodeToHexTransliterator::isUppercase(void) const {
    return uppercase;
}

/**
 * Sets if this transliterator outputs uppercase hex digits.
 *
 * <p>Callers must take care if a transliterator is in use by
 * multiple threads.  The uppercase mode should not be changed by
 * one thread while another thread may be transliterating.
 * @param outputUppercase if true, then this transliterator
 * outputs uppercase hex digits.
 */
void UnicodeToHexTransliterator::setUppercase(bool_t outputUppercase) {
    uppercase = outputUppercase;
}

/**
 * Implements {@link Transliterator#handleTransliterate}.
 */
void UnicodeToHexTransliterator::handleTransliterate(Replaceable& text, Position& offsets,
                                                     bool_t isIncremental) const {
    /**
     * Performs transliteration changing all characters to
     * Unicode hexadecimal escapes.  For example, '@' -> "U+0040",
     * assuming the prefix is "U+". 
     */
    int32_t cursor = offsets.cursor;
    int32_t limit = offsets.limit;

    const UnicodeFilter* filter = getFilter();
    UnicodeString hex;

    while (cursor < limit) {
        UChar c = text.charAt(cursor);
        if (filter != 0 && !filter->contains(c)) {
            ++cursor;
            continue;
        }
        toHex(hex, c);
        text.handleReplaceBetween(cursor, cursor+1, hex);
        int32_t len = hex.length();
        cursor += len; // Advance cursor by 1 and adjust for new text
        --len;
        limit += len;
    }

    offsets.limit = limit;
    offsets.cursor = cursor;
}

UChar UnicodeToHexTransliterator::HEX_DIGITS[32] = {
    // If necessary, replace these character constants with their hex values
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};

/**
 * Given an integer, return its least significant hex digit.
 */
UChar UnicodeToHexTransliterator::itoh(int32_t i) const {
    i &= 0xF;
    return HEX_DIGITS[uppercase ? (i|16) : i];
}

/**
 * Form escape sequence.
 */
UnicodeString& UnicodeToHexTransliterator::toHex(UnicodeString& result,
                                                 UChar c) const {
    result = prefix;
    result.append(itoh(c >> 12));
    result.append(itoh(c >> 8));
    result.append(itoh(c >> 4));
    result.append(itoh(c));
    return result;
}
