Chromium 字符串

string 的种类

在 Chromium 的源码里面,主要使用 std::string 和 std::u16string,Webkit 使用基于 std::string 的 WTF::string。同样也会使用 StringPiece 这个类,是一个指针,指针指向的字符串长度形成了 token,同样还有 WebCString 和 WebString,在 webkit glue layer 之中。

string 的编码

Chromium 本身使用了很多编码种类。UTF-8 是最通用的,同样也使用 UTF-16 和 UCS-2 以及其他 UTF-8。

什么时候使用哪种编码

最关键的规则是 meta-rule,周边代码的编码风格。在前端,我们使用 UTF-8 作为 std::string/char 以及使用 UTF-16 作为 string16/char16 的编码,基于 std:string 是编码不可知的,所以我们只把 UTF-8 放进去。std::wstring/wchar_t 只能用在 windows 系统的本地 api 里面,因为在不同的平台的长度不同,大部分的 UI string 是 UTF-16 的,而 url 是 UTF-8,字符串在 webkit glue 层是 UTF-16。

关于 GURL

一个最常用的数据类型是 GURL 类,它的构造函数输入 UTF-8 编码的 std::string 作为它本身的 URL,你可以使用 spec() 方法来拿到整个 url 的 std:string,或者你可以使用其他方法来获得 url 的其他部分,比如 scheme(),host() 等。

Chromium 代码库的字符串使用指南

1. 在普通用法的时候,使用 std::string 就好了。

2. 检查长度——如果检查是否为空,比起使用 "string.length() ==0",最好使用 "string.empty()"。

3. 当你在文件的头部使用字符常量的时候,使用 char[],而不是 std::string,例如:

const char kFoo[] = "foo" 

这是我们指南的一部分,这种方式因为没有析构过程所以更快,另外代码也更加可维护因为没有 shutdown 的顺序依赖。

4. 在 string 的操作方面,有一些可操作的规范。如果你想用 atoi(),你能用 IntToString(),你想要打印全面的话,你可以尝试一下 StringPrintf()。如果你想要 C++的 string 被 C 的 API 可写入的话,可以使用 WriteInto()。如果函数又涉及 C++和 C 风格的 string,那么 StringPiece 会更合适。

5. 函数的输入参数,更适合传进来一个字符串的常量引用而不是新的拷贝。

6. 在函数的输出参数方面,返回新的字符串或者传一个字符串的指针都是OK的,在性能上也没有什么太大差距。

7. 经常情况下,效率不是最重要的,但是有的时候还是很重要的--当在一个内循环里面,需要特别注意减少 string 的构造,以及临时拷贝的数目。

当你使用 std::string 的时候,你可能会不注意构造大量的临时字符串对象或者拷贝很多次字符串,每次拷贝会调用 malloc,它需要上锁,导致变慢。尽量减少临时变量被构造的次数。

在构造字符串的时候,尽量 string1 += string2; string1 += string3;” 而不是“string1 = string1 + string2 + string3;”,更好的方案是,在你需要很多这样的操作的时候,考虑字符串构造类。

为了本地化,我们有 ICU 库,有很多有用的 helper,可以用来做类似找到单词边界,转化大小写之类的。我们尝试避免重复在不同的字符串编码格式中转化,因为转化的成本很高。当然你转化一次是 OK 的,但是如果一个字符串在一个流程中被反复转化六次之类的,应当被修改。

字符串示例

定义 u16string

std::u16string message = u"test";

std::u16string 转 std::string

std::u16string test;
std::string result = base::UTF16ToUTF8(test);

std::string 转 std::u16string

std::string test;
std::u16string result = base::UTF8ToUTF16(test);

WTF::String UTF-8 和 UTF-16 读取

String body_data;
if (encoding_ == "UTF-8") {
    body_data = String::FromUTF8(buffer_.data(), buffer_.size());
} else {
    body_data = String(buffer_.data(), buffer_.size());
}

WTF::String UTF-8 转 std::string

String test;
std::string result = std::string(test.Utf8().data(),test.Utf8().size()));