in libresource/ResourceTypes.cpp [5347:5487]
bool ResTable::collectString(String16* outString,
const char16_t* s, size_t len,
bool preserveSpaces,
const char** outErrorMsg,
bool append)
{
String16 tmp;
char quoted = 0;
const char16_t* p = s;
while (p < (s+len)) {
while (p < (s+len)) {
const char16_t c = *p;
if (c == '\\') {
break;
}
if (!preserveSpaces) {
if (quoted == 0 && isspace16(c)
&& (c != ' ' || isspace16(*(p+1)))) {
break;
}
if (c == '"' && (quoted == 0 || quoted == '"')) {
break;
}
if (c == '\'' && (quoted == 0 || quoted == '\'')) {
/*
* In practice, when people write ' instead of \'
* in a string, they are doing it by accident
* instead of really meaning to use ' as a quoting
* character. Warn them so they don't lose it.
*/
if (outErrorMsg) {
*outErrorMsg = "Apostrophe not preceded by \\";
}
return false;
}
}
p++;
}
if (p < (s+len)) {
if (p > s) {
tmp.append(String16(s, p-s));
}
if (!preserveSpaces && (*p == '"' || *p == '\'')) {
if (quoted == 0) {
quoted = *p;
} else {
quoted = 0;
}
p++;
} else if (!preserveSpaces && isspace16(*p)) {
// Space outside of a quote -- consume all spaces and
// leave a single plain space char.
tmp.append(String16(" "));
p++;
while (p < (s+len) && isspace16(*p)) {
p++;
}
} else if (*p == '\\') {
p++;
if (p < (s+len)) {
switch (*p) {
case 't':
tmp.append(String16("\t"));
break;
case 'n':
tmp.append(String16("\n"));
break;
case '#':
tmp.append(String16("#"));
break;
case '@':
tmp.append(String16("@"));
break;
case '?':
tmp.append(String16("?"));
break;
case '"':
tmp.append(String16("\""));
break;
case '\'':
tmp.append(String16("'"));
break;
case '\\':
tmp.append(String16("\\"));
break;
case 'u':
{
char16_t chr = 0;
int i = 0;
while (i < 4 && p[1] != 0) {
p++;
i++;
int c;
if (*p >= '0' && *p <= '9') {
c = *p - '0';
} else if (*p >= 'a' && *p <= 'f') {
c = *p - 'a' + 10;
} else if (*p >= 'A' && *p <= 'F') {
c = *p - 'A' + 10;
} else {
if (outErrorMsg) {
*outErrorMsg = "Bad character in \\u unicode escape sequence";
}
return false;
}
chr = (chr<<4) | c;
}
tmp.append(String16(&chr, 1));
} break;
default:
// ignore unknown escape chars.
break;
}
p++;
}
}
len -= (p-s);
s = p;
}
}
if (tmp.size() != 0) {
if (len > 0) {
tmp.append(String16(s, len));
}
if (append) {
outString->append(tmp);
} else {
outString->setTo(tmp);
}
} else {
if (append) {
outString->append(String16(s, len));
} else {
outString->setTo(s, len);
}
}
return true;
}