mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-8899 Switch to StringBuilder for buffer.
X-SVN-Rev: 30974
This commit is contained in:
parent
3280110b3c
commit
4b1538b4f9
1 changed files with 50 additions and 52 deletions
|
@ -19,10 +19,22 @@ import com.ibm.icu.impl.locale.AsciiUtil;
|
|||
* Utility class to parse and normalize locale ids (including POSIX style)
|
||||
*/
|
||||
public final class LocaleIDParser {
|
||||
|
||||
/**
|
||||
* Char array representing the locale ID.
|
||||
*/
|
||||
private char[] id;
|
||||
|
||||
/**
|
||||
* Current position in {@link #id} (while parsing).
|
||||
*/
|
||||
private int index;
|
||||
private char[] buffer;
|
||||
private int blen;
|
||||
|
||||
/**
|
||||
* Temporary buffer for parsed sections of data.
|
||||
*/
|
||||
private StringBuilder buffer;
|
||||
|
||||
// um, don't handle POSIX ids unless we request it. why not? well... because.
|
||||
private boolean canonicalize;
|
||||
private boolean hadCountry;
|
||||
|
@ -49,38 +61,24 @@ public final class LocaleIDParser {
|
|||
public LocaleIDParser(String localeID, boolean canonicalize) {
|
||||
id = localeID.toCharArray();
|
||||
index = 0;
|
||||
buffer = new char[id.length + 5];
|
||||
blen = 0;
|
||||
buffer = new StringBuilder(id.length + 5);
|
||||
this.canonicalize = canonicalize;
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
index = blen = 0;
|
||||
index = 0;
|
||||
buffer = new StringBuilder(id.length + 5);
|
||||
}
|
||||
|
||||
// utilities for working on text in the buffer
|
||||
|
||||
private void resizeBuffer(int newSize) {
|
||||
if (newSize > 1024) {
|
||||
// if buffer is too large, something is wrong. die.
|
||||
throw new IndexOutOfBoundsException("Buffer has grown too large.");
|
||||
}
|
||||
|
||||
char[] nbuffer = new char[newSize];
|
||||
System.arraycopy(buffer, 0, nbuffer, 0, Math.min(buffer.length, newSize));
|
||||
buffer = nbuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append c to the buffer.
|
||||
*/
|
||||
private void append(char c) {
|
||||
if (blen >= buffer.length) {
|
||||
resizeBuffer(buffer.length * 2);
|
||||
}
|
||||
buffer[blen++] = c;
|
||||
buffer.append(c);
|
||||
}
|
||||
|
||||
|
||||
private void addSeparator() {
|
||||
append(UNDERSCORE);
|
||||
}
|
||||
|
@ -89,31 +87,22 @@ public final class LocaleIDParser {
|
|||
* Returns the text in the buffer from start to blen as a String.
|
||||
*/
|
||||
private String getString(int start) {
|
||||
if (start == blen) {
|
||||
return "";
|
||||
}
|
||||
return new String(buffer, start, blen-start);
|
||||
return buffer.substring(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of the buffer to pos, then append the string.
|
||||
*/
|
||||
private void set(int pos, String s) {
|
||||
this.blen = pos; // no safety
|
||||
append(s);
|
||||
buffer.delete(pos, buffer.length());
|
||||
buffer.insert(pos, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the string to the buffer.
|
||||
*/
|
||||
private void append(String s) {
|
||||
int slen = s.length();
|
||||
if (blen + slen > buffer.length) {
|
||||
resizeBuffer(buffer.length * 2 + slen);
|
||||
}
|
||||
for (int i = 0; i < slen; ++i) {
|
||||
buffer[blen++] = s.charAt(i);
|
||||
}
|
||||
buffer.append(s);
|
||||
}
|
||||
|
||||
// utilities for parsing text out of the id
|
||||
|
@ -202,6 +191,8 @@ public final class LocaleIDParser {
|
|||
* separator. Returns the start of the language code in the buffer.
|
||||
*/
|
||||
private int parseLanguage() {
|
||||
int startLength = buffer.length();
|
||||
|
||||
if (haveExperimentalLanguagePrefix()) {
|
||||
append(Character.toLowerCase(id[0]));
|
||||
append(HYPHEN);
|
||||
|
@ -214,7 +205,7 @@ public final class LocaleIDParser {
|
|||
}
|
||||
--index; // unget
|
||||
|
||||
if (blen == 3) {
|
||||
if (buffer.length() - startLength == 3) {
|
||||
String lang = LocaleIDs.threeToTwoLetterLanguage(getString(0));
|
||||
if (lang != null) {
|
||||
set(0, lang);
|
||||
|
@ -249,12 +240,14 @@ public final class LocaleIDParser {
|
|||
int oldIndex = index; // save original index
|
||||
++index;
|
||||
|
||||
int oldBlen = blen; // get before append hyphen, if we truncate everything is undone
|
||||
int oldBlen = buffer.length(); // get before append hyphen, if we truncate everything is undone
|
||||
char c;
|
||||
boolean firstPass = true;
|
||||
while(!isTerminatorOrIDSeparator(c = next())) {
|
||||
if (blen == oldBlen) { // first pass
|
||||
if (firstPass) {
|
||||
addSeparator();
|
||||
append(Character.toUpperCase(c));
|
||||
firstPass = false;
|
||||
} else {
|
||||
append(Character.toLowerCase(c));
|
||||
}
|
||||
|
@ -264,14 +257,14 @@ public final class LocaleIDParser {
|
|||
/* If it's not exactly 4 characters long, then it's not a script. */
|
||||
if (index - oldIndex != 5) { // +1 to account for separator
|
||||
index = oldIndex;
|
||||
blen = oldBlen;
|
||||
buffer.delete(oldBlen, buffer.length());
|
||||
} else {
|
||||
oldBlen++; // index past hyphen, for clients who want to extract just the script
|
||||
}
|
||||
|
||||
return oldBlen;
|
||||
}
|
||||
return blen;
|
||||
return buffer.length();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,19 +296,21 @@ public final class LocaleIDParser {
|
|||
int oldIndex = index;
|
||||
++index;
|
||||
|
||||
int oldBlen = blen;
|
||||
int oldBlen = buffer.length();
|
||||
char c;
|
||||
boolean firstPass = true;
|
||||
while (!isTerminatorOrIDSeparator(c = next())) {
|
||||
if (oldBlen == blen) { // first, add hyphen
|
||||
if (firstPass) { // first, add hyphen
|
||||
hadCountry = true; // we have a country, let variant parsing know
|
||||
addSeparator();
|
||||
++oldBlen; // increment past hyphen
|
||||
firstPass = false;
|
||||
}
|
||||
append(Character.toUpperCase(c));
|
||||
}
|
||||
--index; // unget
|
||||
|
||||
int charsAppended = blen - oldBlen;
|
||||
int charsAppended = buffer.length() - oldBlen;
|
||||
|
||||
if (charsAppended == 0) {
|
||||
// Do nothing.
|
||||
|
@ -325,7 +320,7 @@ public final class LocaleIDParser {
|
|||
// their previous values.
|
||||
index = oldIndex;
|
||||
--oldBlen;
|
||||
blen = oldBlen;
|
||||
buffer.delete(oldBlen, buffer.length());
|
||||
hadCountry = false;
|
||||
}
|
||||
else if (charsAppended == 3) {
|
||||
|
@ -338,7 +333,7 @@ public final class LocaleIDParser {
|
|||
return oldBlen;
|
||||
}
|
||||
|
||||
return blen;
|
||||
return buffer.length();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -388,12 +383,14 @@ public final class LocaleIDParser {
|
|||
* becomes a bit more complex.
|
||||
*/
|
||||
private int parseVariant() {
|
||||
int oldBlen = blen;
|
||||
int oldBlen = buffer.length();
|
||||
|
||||
boolean start = true;
|
||||
boolean needSeparator = true;
|
||||
boolean skipping = false;
|
||||
char c;
|
||||
boolean firstPass = true;
|
||||
|
||||
while ((c = next()) != DONE) {
|
||||
if (c == DOT) {
|
||||
start = false;
|
||||
|
@ -409,15 +406,15 @@ public final class LocaleIDParser {
|
|||
start = false;
|
||||
} else if (!skipping) {
|
||||
if (needSeparator) {
|
||||
boolean incOldBlen = blen == oldBlen; // need to skip separators
|
||||
needSeparator = false;
|
||||
if (incOldBlen && !hadCountry) { // no country, we'll need two
|
||||
if (firstPass && !hadCountry) { // no country, we'll need two
|
||||
addSeparator();
|
||||
++oldBlen; // for sure
|
||||
}
|
||||
addSeparator();
|
||||
if (incOldBlen) { // only for the first separator
|
||||
if (firstPass) { // only for the first separator
|
||||
++oldBlen;
|
||||
firstPass = false;
|
||||
}
|
||||
}
|
||||
c = Character.toUpperCase(c);
|
||||
|
@ -501,8 +498,9 @@ public final class LocaleIDParser {
|
|||
parseVariant();
|
||||
|
||||
// catch unwanted trailing underscore after country if there was no variant
|
||||
if (blen > 1 && buffer[blen-1] == UNDERSCORE) {
|
||||
--blen;
|
||||
int len = buffer.length();
|
||||
if (len > 0 && buffer.charAt(len - 1) == UNDERSCORE) {
|
||||
buffer.deleteCharAt(len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -637,7 +635,7 @@ public final class LocaleIDParser {
|
|||
* Parse the keywords and return start of the string in the buffer.
|
||||
*/
|
||||
private int parseKeywords() {
|
||||
int oldBlen = blen;
|
||||
int oldBlen = buffer.length();
|
||||
Map<String, String> m = getKeywordMap();
|
||||
if (!m.isEmpty()) {
|
||||
boolean first = true;
|
||||
|
@ -648,7 +646,7 @@ public final class LocaleIDParser {
|
|||
append(KEYWORD_ASSIGN);
|
||||
append(e.getValue());
|
||||
}
|
||||
if (blen != oldBlen) {
|
||||
if (first == false) {
|
||||
++oldBlen;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue