static const
はクラススレッドセーフですか? 以下のコードtrailingBytesForUTF8
では、これはstatic const
文字配列です。CConvertUTF
クラスの独自のオブジェクト インスタンスを持つ多くのスレッドが存在する場合があります。複数のスレッドが同じ配列に同時にアクセスしている場合、変更可能な状態の問題trailingBytesForUTF8
や、その他のスレッドの問題はありますか? また、スレッドがクラスの同じオブジェクト インスタンスを共有することは決してないことに注意してください。CConvertUTF
// .h
class CConvertUTF final
{
private:
static const char trailingBytesForUTF8[256];
public:
bool IsLegalUTF8Sequence(const char *source, const char *sourceEnd);
bool IsLegalUTF8(const char *source, int length);
};
// .cpp
const char CConvertUTF::trailingBytesForUTF8[256] = {
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, 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,
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, 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,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
bool CConvertUTF::IsLegalUTF8Sequence(const char *source, const char *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
if (source+length > sourceEnd) {
return false;
}
return IsLegalUTF8(source, length);
}
bool CConvertUTF::IsLegalUTF8(const char *source, int length) {
char a;
const *char = source+length;
switch (length) {
default: return false;
/* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
switch (*source) {
/* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return false; break;
case 0xED: if (a > 0x9F) return false; break;
case 0xF0: if (a < 0x90) return false; break;
case 0xF4: if (a > 0x8F) return false; break;
default: if (a < 0x80) return false;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
if (*source > 0xF4) return false;
return true;
}