1

我正在编写一个将UTF8字符转换为其代表 Unicode 代码点的类方法。我的原型候选人如下:

static uint32_t Utf8ToWStr( uint8_t Byte1,        uint8_t Byte2 = 0x00,
                            uint8_t Byte3 = 0x00, uint8_t Byte4 = 0x00,
                            uint8_t Byte5 = 0x00, uint8_t Byte6 = 0x00);

static uint32_t Utf8ToWStr(const std::vector<uint8_t> & Bytes);

在我的应用程序中;
Byte1将是大约 90% 的时间中唯一的非零字节。
Byte1并且Byte2将是大约 9% 的时间中唯一的非零字节。
Byte1Byte2并且Byte3将是唯一少于 1% 的时间的非零字节。
Byte4Byte5并且Byte6几乎总是为零。

为了速度,我应该更喜欢哪个原型?

4

3 回答 3

3

我会用

// if you want it as simple as possible
typedef uint8_t data_t[6];

或者

// if you like C++11
typedef std::array<uint8_t, 6> data_t;

或者

// if it should be extensible
typedef struct { uint8_t data[6]; } data_t;

在编译时指出输入数据的固定长度性质。这样,它可以为您节省大量实际调用该函数的输入。

对我来说,使用可变长度向量会以某种方式暗示可能有更多或更少或空的数据。

于 2012-09-18T07:24:21.203 回答
2

可能两者都没有。

想想调用这个函数的代码——他们可能不得不跳过很多圈才能使用它:

uint8_t c1 = *cursor++;
uint8_t c2 = 0;
uint8_t c3 = 0;
uint8_t c4 = 0;
uint8_t c5 = 0;
uint8_t c6 = 0;
if(c1 >= 0x80)
    c2 = *cursor++;
if(c1 >= 0xc0)
    c3 = *cursor++;
if(c1 >= 0xe0)
    c4 = *cursor++;
if(c1 >= 0xf0)
    c5 = *cursor++;
if(c1 >= 0xf8)
    c6 = *cursor++;
uint32_t wch = Utf8ToWStr(c1, c2, c3, c4, c5, c6);

我真诚地怀疑这个界面是否有用。

我的转换例程的正常界面是

bool utf8_to_wchar(uint8_t const *&cursor, uint8_t const *end, uint32_t &result);

返回值用于传达错误(例如,您的函数将如何对参数做出反应(0x81, 0x00)

最后但并非最不重要的一点是,您可能希望有一个模式来指定非规范化的 UTF-8 是否应该给出错误 - 从安全 POV 来看,禁止编码U+003F0x80 0x3f.

于 2012-09-18T07:18:23.467 回答
1

std::vector 可能更慢,因为它将这些字节存储到堆中并为它们分配内存。

您也可以只传递一个指向字节数组的指针,或者如果使用 C++11,则使用 std::array。

于 2012-09-18T07:06:01.337 回答