2
**********************************************************************
3
* Copyright (C) 1999-2001, International Business Machines
4
* Corporation and others. All Rights Reserved.
5
**********************************************************************
6
* Date Name Description
7
* 11/17/99 aliu Creation.
8
**********************************************************************
10
#include "unicode/unitohex.h"
11
#include "unicode/rep.h"
12
#include "unicode/unifilt.h"
17
* ID for this transliterator.
19
const char UnicodeToHexTransliterator::_ID[] = "Any-Hex";
21
const UChar UnicodeToHexTransliterator::HEX_DIGITS[32] = {
22
// Use Unicode hex values for EBCDIC compatibility
23
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 01234567
24
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 89abcdef
25
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 01234567
26
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 89ABCDEF
30
* Constructs a transliterator.
32
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
33
const UnicodeString& thePattern,
35
UnicodeFilter* adoptedFilter,
37
Transliterator(_ID, adoptedFilter),
38
uppercase(isUppercase) {
40
if (U_FAILURE(status)) {
43
applyPattern(thePattern, status);
47
* Constructs a transliterator.
49
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
50
const UnicodeString& thePattern,
52
Transliterator(_ID, 0),
55
if (U_FAILURE(status)) {
58
applyPattern(thePattern, status);
62
* Constructs a transliterator with the default prefix "\u"
63
* that outputs four uppercase hex digits.
65
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
66
UnicodeFilter* adoptedFilter) :
67
Transliterator(_ID, adoptedFilter),
68
pattern("\\\\u0000", ""),
78
UnicodeToHexTransliterator::UnicodeToHexTransliterator(
79
const UnicodeToHexTransliterator& other) :
80
Transliterator(other),
81
pattern(other.pattern),
84
minDigits(other.minDigits),
85
uppercase(other.uppercase) {
89
* Assignment operator.
91
UnicodeToHexTransliterator&
92
UnicodeToHexTransliterator::operator=(const UnicodeToHexTransliterator& other) {
93
Transliterator::operator=(other);
94
pattern = other.pattern;
95
prefix = other.prefix;
96
suffix = other.suffix;
97
minDigits = other.minDigits;
98
uppercase = other.uppercase;
103
UnicodeToHexTransliterator::clone(void) const {
104
return new UnicodeToHexTransliterator(*this);
107
void UnicodeToHexTransliterator::applyPattern(const UnicodeString& thePattern,
108
UErrorCode& status) {
109
if (U_FAILURE(status)) {
113
// POSSIBILE FUTURE MODIFICATION
114
// Parse thePattern, and if this succeeds, set pattern to thePattern.
115
// If it fails, call applyPattern(pattern) to restore the original
118
pattern = thePattern;
122
int32_t maxDigits = 0;
124
/* The mode specifies where we are in each spec.
126
* mode 1 = in optional digits (#)
127
* mode 2 = in required digits (0)
132
for (int32_t i=0; i<pattern.length(); ++i) {
133
UChar c = pattern.charAt(i);
134
UBool isLiteral = FALSE;
135
if (c == BACKSLASH) {
136
if ((i+1)<pattern.length()) {
138
c = pattern.charAt(++i);
141
status = U_ILLEGAL_ARGUMENT_ERROR;
149
// Seeing a '#' moves us from mode 0 (prefix) to mode 1
150
// (optional digits).
153
} else if (mode != 1) {
155
status = U_ILLEGAL_ARGUMENT_ERROR;
161
// Seeing a '0' moves us to mode 2 (required digits)
164
} else if (mode != 2) {
166
status = U_ILLEGAL_ARGUMENT_ERROR;
182
// Any literal outside the prefix moves us into mode 3
190
if (minDigits < 1 || maxDigits > 4) {
191
// Invalid min/max digit count
192
status = U_ILLEGAL_ARGUMENT_ERROR;
197
const UnicodeString& UnicodeToHexTransliterator::toPattern(void) const {
202
* Returns true if this transliterator outputs uppercase hex digits.
204
UBool UnicodeToHexTransliterator::isUppercase(void) const {
209
* Sets if this transliterator outputs uppercase hex digits.
211
* <p>Callers must take care if a transliterator is in use by
212
* multiple threads. The uppercase mode should not be changed by
213
* one thread while another thread may be transliterating.
214
* @param outputUppercase if true, then this transliterator
215
* outputs uppercase hex digits.
217
void UnicodeToHexTransliterator::setUppercase(UBool outputUppercase) {
218
uppercase = outputUppercase;
222
* Implements {@link Transliterator#handleTransliterate}.
224
void UnicodeToHexTransliterator::handleTransliterate(Replaceable& text, UTransPosition& offsets,
225
UBool /*isIncremental*/) const {
227
* Performs transliteration changing all characters to
228
* Unicode hexadecimal escapes. For example, '@' -> "U+0040",
229
* assuming the prefix is "U+".
231
int32_t cursor = offsets.start;
232
int32_t limit = offsets.limit;
236
while (cursor < limit) {
237
UChar c = text.charAt(cursor);
240
UBool showRest = FALSE;
241
for (int32_t i=3; i>=0; --i) {
242
/* Get each nibble from left to right */
243
int32_t d = (c >> (i<<2)) & 0xF;
244
if (showRest || (d != 0) || minDigits > i) {
245
hex.append(HEX_DIGITS[uppercase ? (d|16) : d]);
251
text.handleReplaceBetween(cursor, cursor+1, hex);
252
int32_t len = hex.length();
253
cursor += len; // Advance cursor by 1 and adjust for new text
258
offsets.contextLimit += limit - offsets.limit;
259
offsets.limit = limit;
260
offsets.start = cursor;