#include <string>
#include <cstring>
#include <iostream>
bool validateUTF8(std::string const& _input, size_t& _invalidPosition)
{
const size_t length = _input.length();
bool valid = true;
size_t i = 0;
for (; i < length; i++)
{
if ((unsigned char)_input[i] < 0x80)
continue;
size_t count = 0;
switch(_input[i] & 0xe0) {
case 0xc0: count = 1; break;
case 0xe0: count = 2; break;
case 0xf0: count = 3; break;
default: break;
}
if (count == 0)
{
valid = false;
break;
}
if ((i + count) >= length)
{
valid = false;
break;
}
for (size_t j = 0; j < count; j++)
{
i++;
if ((_input[i] & 0xc0) != 0x80)
{
valid = false;
break;
}
}
}
if (valid)
return true;
_invalidPosition = i;
return false;
}
int main() {
const std::string input = "\xF0\x9F\xA6\x84";
size_t position = 0;
bool ret = validateUTF8(input, position);
std::cout << "Final Position:" << position << std::endl;
std::cout << "OK:" << ret << std::endl;
return 0;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCmJvb2wgdmFsaWRhdGVVVEY4KHN0ZDo6c3RyaW5nIGNvbnN0JiBfaW5wdXQsIHNpemVfdCYgX2ludmFsaWRQb3NpdGlvbikKewoJY29uc3Qgc2l6ZV90IGxlbmd0aCA9IF9pbnB1dC5sZW5ndGgoKTsKCWJvb2wgdmFsaWQgPSB0cnVlOwoJc2l6ZV90IGkgPSAwOwoKCWZvciAoOyBpIDwgbGVuZ3RoOyBpKyspCgl7CgkJaWYgKCh1bnNpZ25lZCBjaGFyKV9pbnB1dFtpXSA8IDB4ODApCgkJCWNvbnRpbnVlOwoKCQlzaXplX3QgY291bnQgPSAwOwoJCXN3aXRjaChfaW5wdXRbaV0gJiAweGUwKSB7CgkJCWNhc2UgMHhjMDogY291bnQgPSAxOyBicmVhazsKCQkJY2FzZSAweGUwOiBjb3VudCA9IDI7IGJyZWFrOwoJCQljYXNlIDB4ZjA6IGNvdW50ID0gMzsgYnJlYWs7CgkJCWRlZmF1bHQ6IGJyZWFrOwoJCX0KCgkJaWYgKGNvdW50ID09IDApCgkJewoJCQl2YWxpZCA9IGZhbHNlOwoJCQlicmVhazsKCQl9CgoJCWlmICgoaSArIGNvdW50KSA+PSBsZW5ndGgpCgkJewoJCQl2YWxpZCA9IGZhbHNlOwoJCQlicmVhazsKCQl9CgoJCWZvciAoc2l6ZV90IGogPSAwOyBqIDwgY291bnQ7IGorKykKCQl7CgkJCWkrKzsKCQkJaWYgKChfaW5wdXRbaV0gJiAweGMwKSAhPSAweDgwKQoJCQl7CgkJCQl2YWxpZCA9IGZhbHNlOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJaWYgKHZhbGlkKQoJCXJldHVybiB0cnVlOwoKCV9pbnZhbGlkUG9zaXRpb24gPSBpOwoJcmV0dXJuIGZhbHNlOwp9CgppbnQgbWFpbigpIHsKCWNvbnN0IHN0ZDo6c3RyaW5nIGlucHV0ID0gIlx4RjBceDlGXHhBNlx4ODQiOwoJc2l6ZV90IHBvc2l0aW9uID0gMDsKCQoJYm9vbCByZXQgPSB2YWxpZGF0ZVVURjgoaW5wdXQsIHBvc2l0aW9uKTsKCXN0ZDo6Y291dCA8PCAiRmluYWwgUG9zaXRpb246IiA8PCBwb3NpdGlvbiA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIk9LOiIgPDwgcmV0IDw8IHN0ZDo6ZW5kbDsKCQoJcmV0dXJuIDA7Cn0=