blob: adcfd6d9128b1292906dbfd767d1c37531235cb8 [file] [log] [blame]
part of strings;
const int _ASCII_END = 0x7f;
const int _ASCII_START = 0x0;
const int _C0_END = 0x1f;
const int _C0_START = 0x00;
const int _UNICODE_END = 0x10ffff;
const int _DIGIT = 0x1;
const int _LOWER = 0x2;
const int _UNDERSCORE = 0x4;
const int _UPPER = 0x8;
const int _ALPHA = _LOWER | _UPPER;
const int _ALPHA_NUM = _ALPHA | _DIGIT;
const int _VALID = _ALPHA_NUM | _UNDERSCORE;
final List<int> _ascii = <int>[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 4, 0, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0,
0];
/**
* Returns a string in the form "UpperCamelCase" or "lowerCamelCase".
*
* Example:
* print(camelize("dart_vm"));
* => DartVm
*/
String camelize(String string, [bool lower = false]) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return string;
}
string = string.toLowerCase();
var capitlize = true;
var length = string.length;
var position = 0;
var remove = false;
var sb = new StringBuffer();
for (var i = 0; i < length; i++) {
var s = string[i];
var c = s.codeUnitAt(0);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (capitlize && flag & _ALPHA != 0) {
if (lower && position == 0) {
sb.write(s);
} else {
sb.write(s.toUpperCase());
}
capitlize = false;
remove = true;
position++;
} else {
if (flag & _UNDERSCORE != 0) {
if (!remove) {
sb.write(s);
remove = true;
}
capitlize = true;
} else {
if (flag & _ALPHA_NUM != 0) {
capitlize = false;
remove = true;
} else {
capitlize = true;
remove = false;
position = 0;
}
sb.write(s);
}
}
}
return sb.toString();
}
/**
* Returns a string with capitalized first character.
*
* Example:
* print(capitalize("dart"));
* => Dart
*/
String capitalize(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return string;
}
return string[0].toUpperCase() + string.substring(1);
}
/**
* Returns an escaped string.
*
* Example:
* print(escape("Hello 'world' \n"));
* => Hello \'world\' \n
*/
String escape(String string, [String encode(int charCode)]) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return string;
}
if (encode == null) {
encode = toUnicode;
}
var sb = new StringBuffer();
var i = 0;
for (var c in string.runes) {
if (c >= _C0_START && c <= _C0_END) {
switch (c) {
case 9:
sb.write("\\t");
break;
case 10:
sb.write("\\n");
break;
case 13:
sb.write("\\r");
break;
default:
sb.write(encode(c));
}
} else if (c >= _ASCII_START && c <= _ASCII_END) {
switch (c) {
case 34:
sb.write("\\\"");
break;
case 36:
sb.write("\\\$");
break;
case 39:
sb.write("\\\'");
break;
case 92:
sb.write("\\\\");
break;
default:
sb.write(string[i]);
}
} else if (_isPrintable(c)) {
sb.write(string[i]);
} else {
sb.write(encode(c));
}
i++;
}
return sb.toString();
}
/**
* Returns true if the string does not contain upper case letters; otherwise
* false;
*
* Example:
* print(isLowerCase("camelCase"));
* => false
*
* print(isLowerCase("dart"));
* => true
*
* print(isLowerCase(""));
* => false
*/
bool isLowerCase(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return true;
}
var length = string.length;
for (var i = 0; i < length; i++) {
var c = string.codeUnitAt(i);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (c <= _ASCII_END) {
if (flag & _UPPER != 0) {
return false;
}
} else {
var s = string[i];
if (s == s.toUpperCase()) {
return false;
}
}
}
return true;
}
/**
* Returns true if the string does not contain lower case letters; otherwise
* false;
*
* Example:
* print(isUpperCase("CamelCase"));
* => false
*
* print(isUpperCase("DART"));
* => true
*
* print(isUpperCase(""));
* => false
*/
bool isUpperCase(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return true;
}
var length = string.length;
for (var i = 0; i < length; i++) {
var c = string.codeUnitAt(i);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (c <= _ASCII_END) {
if (flag & _LOWER != 0) {
return false;
}
} else {
var s = string[i];
if (s == s.toLowerCase()) {
return false;
}
}
}
return true;
}
/**
* Returns the joined elements of the list if the list is not null; otherwise
* null.
*
* Example:
* print(join(null));
* => null
*
* print(join([1, 2]));
* => 12
*/
String join(List list, [String separator = ""]) {
if (list == null) {
return null;
}
return list.join(separator);
}
/**
* Returns a string with reversed order of characters.
*
* Example:
* print(reverse("hello"));
* => olleh
*/
String reverse(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length < 2) {
return string;
}
return new String.fromCharCodes(string.codeUnits.reversed);
}
/**
* Returns true if the string starts with the lower case character; otherwise
* false;
*
* Example:
* print(startsWithLowerCase("camelCase"));
* => true
*
* print(startsWithLowerCase(""));
* => false
*/
bool startsWithLowerCase(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return false;
}
var c = string.codeUnitAt(0);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (c <= _ASCII_END) {
if (flag & _LOWER != 0) {
return true;
}
} else {
var s = string[0];
if (s == s.toLowerCase()) {
return true;
}
}
return false;
}
/**
* Returns true if the string starts with the upper case character; otherwise
* false;
*
* Example:
* print(startsWithUpperCase("Dart"));
* => true
*
* print(startsWithUpperCase(""));
* => false
*/
bool startsWithUpperCase(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return false;
}
var c = string.codeUnitAt(0);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (c <= _ASCII_END) {
if (flag & _UPPER != 0) {
return true;
}
} else {
var s = string[0];
if (s == s.toUpperCase()) {
return true;
}
}
return false;
}
/**
* Returns an unescaped printable string.
*
* Example:
* print(toPrintable("Hello 'world' \n"));
* => Hello 'world' \n
*/
String toPrintable(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return string;
}
var sb = new StringBuffer();
var i = 0;
for (var c in string.runes) {
if (c >= _C0_START && c <= _C0_END) {
switch (c) {
case 9:
sb.write("\\t");
break;
case 10:
sb.write("\\n");
break;
case 13:
sb.write("\\r");
break;
default:
sb.write(toUnicode(c));
}
} else if (_isPrintable(c)) {
sb.write(string[i]);
} else {
sb.write(toUnicode(c));
}
i++;
}
return sb.toString();
}
/**
* Returns an Unicode representation of the character code.
*
* Example:
* print(toUnicode(48));
* => \u0030
*/
String toUnicode(int charCode) {
if (charCode == null || charCode < 0 || charCode > _UNICODE_END) {
throw new ArgumentError('charCode: $charCode');
}
var hex = charCode.toRadixString(16);
var length = hex.length;
if (length < 4) {
hex = hex.padLeft(4, "0");
}
return '\\u$hex';
}
/**
* Returns an underscored string.
*
* Example:
* print(underscore("DartVM DartCore"));
* => dart_vm dart_core
*/
String underscore(String string) {
if (string == null) {
throw new ArgumentError("string: $string");
}
if (string.length == 0) {
return string;
}
var length = string.length;
var sb = new StringBuffer();
var separate = false;
for (var i = 0; i < length; i++) {
var s = string[i];
var c = s.codeUnitAt(0);
var flag = 0;
if (c <= _ASCII_END) {
flag = _ascii[c];
}
if (separate && flag & _UPPER != 0) {
sb.write("_");
sb.write(s);
separate = true;
} else {
if (flag & _ALPHA_NUM != 0) {
separate = true;
} else if (flag & _UNDERSCORE != 0 && separate) {
separate = true;
} else {
separate = false;
}
sb.write(s);
}
}
return sb.toString().toLowerCase();
}
SparseBoolList _generateBool(List<int> ranges) {
var list = new SparseBoolList();
var length = ranges.length;
for (var i = 0; i < length; i += 2) {
list.addGroup(new GroupedRangeList<bool>(ranges[i], ranges[i + 1], true));
}
return list;
}
// TODO: Optimize via table
// TODO: Improve list of printable characters
bool _isPrintable(int character) {
switch (unicode.generalCategories[character]) {
case unicode.CONTROL:
case unicode.FORMAT:
case unicode.LINE_SEPARATOR:
case unicode.NOT_ASSIGNED:
case unicode.PARAGRAPH_SEPARATOR:
case unicode.PRIVATE_USE:
case unicode.SURROGATE:
return false;
default:
return true;
}
}