讲解


代码
//编码用函数 返回value按照utf8编码后的字节数 根据valle的大小反推需要的字节数uint32_t getByteNumOfEncodeUtf8(int value) {   ASSERT(value > 0, "Can`t encode negative value!");   // 单个ascii字符需要1字节   if (value <= 0x7f) {      return 1;   }   //此范围内数值编码为utf8需要2字节   if (value <= 0x7ff) {      return 2;   }   //此范围内数值编码为utf8需要3字节   if (value <= 0xffff) {      return 3;   }   //此范围内数值编码为utf8需要4字节   if (value <= 0x10ffff) {      return 4;   }    return 0;  //超过范围返回0}//编码用函数 把value编码为utf8后写入缓冲区buf,返回写入的字节数uint8_t encodeUtf8(uint8_t* buf, int value) {   ASSERT(value > 0, "Can`t encode negative value!");//按照大端字节序写入缓冲区    if (value <= 0x7f) {   // 单个ascii字符需要1字节   // 0x7f => 0b01111111      *buf = value & 0x7f; // 往buf内存地址处写值      return 1;   } else if (value <= 0x7ff) {  //此范围内数值编码为utf8需要2字节      // 0x7ff => 0b11111111111 2字节编码范围      // 110xxxxx 10xxxxxx 11位有效 utf-8 2字节编码规则      // 例如:value 是 0b10100_011001      // 0b11111_000000 & 0b10100_011001 => 0b10100_000000      // 0b10100_000000 >> 6 => 0b10100 value中的高5位      // 写入buf内存 => 0b110_10100 此时buf内存中起始就是高字节部分      // buf内存地址再加一个字节,向内存地址高地址处移动一个字节      // 与操作过滤 或操作合并      //先写入高字节      *buf = 0xc0/*0b110_00000*/ | ((value & 0x7c0/*0b11111_000000*/) >> 6);      buf++;      // 0b111111 & 0b10100_011001 => 0b10100_011001      // 再写入低字节      *buf = 0x80/*0b10_000000*/ | (value & 0x3f/*0b111111*/);      return 2;   } else if (value <= 0xffff) { //此范围内数值编码为utf8需要3字节      // 先写入高字节       *buf = 0xe0 | ((value & 0xf000) >> 12);      buf++;      //再写入中间字节      *buf = 0x80 | ((value & 0xfc0) >> 6);      buf++;       //最后写入低字节      *buf = 0x80 | (value & 0x3f);      return 3;   } else if (value <= 0x10ffff) { //此范围内数值编码为utf8需要4字节      *buf = 0xf0 | ((value & 0x1c0000) >> 18);      buf++;      *buf = 0x80 | ((value & 0x3f000) >> 12);      buf++;      *buf = 0x80 | ((value & 0xfc0) >> 6);      buf++;      *buf = 0x80 | (value & 0x3f);      return 4;   }   NOT_REACHED();   return 0;}//解码用函数 返回解码utf8的字节数uint32_t getByteNumOfDecodeUtf8(uint8_t byte) {   //byte应该是utf8的最高1字节,如果指向了utf8编码后面的低字节部分则返回0   if ((byte & 0xc0/*0b11000000*/) == 0x80/*0b10000000*/) {      // 10不因该是utf-8高位,应该是低位      return 0;   }   if ((byte & 0xf8/*0b11111_000 有效位清0*/) == 0xf0/*0b11110_000 utf-8 4字节高字节清0后各位的特征*/) {      return 4;   }   if ((byte & 0xf0/*0b1111_0000 有效位清0*/) == 0xe0/*0b1110_0000 utf-8 3字节高字节清0后各位的特征*/) {      return 3;   }   if ((byte & 0xe0/*0b111_00000 有效位清0*/) == 0xc0/*0b110_00000 utf-8 2字节高字节清0后各位的特征*/) {      return 2;   }   return 1;   //ascii码} //解码用函数 解码以bytePtr为起始地址的UTF-8序列 其最大长度为length 若不是UTF-8序列就返回-1int decodeUtf8(const uint8_t* bytePtr, uint32_t length) {   //若是1字节的ascii:  0xxxxxxx   if (*bytePtr <= 0x7f) {      return *bytePtr;   }   int value;   uint32_t remainingBytes;   //先读取高1字节   //根据高字节的高n位判断相应字节数的utf8编码   if ((*bytePtr & 0xe0) == 0xc0) {      //若是2字节的utf8      value = *bytePtr & 0x1f/*0b000_11111*/; // 过滤出高字节有效位      remainingBytes = 1;   } else if ((*bytePtr & 0xf0) == 0xe0) {      //若是3字节的utf8      value = *bytePtr & 0x0f;       remainingBytes = 2;   } else if ((*bytePtr & 0xf8) == 0xf0) {      //若是4字节的utf8      value = *bytePtr & 0x07;       remainingBytes = 3;   } else {   //非法编码      return -1;   }   //如果utf8被斩断了就不再读过去了   if (remainingBytes > length - 1) {      return -1;   }   //再读取低字节中的数据   while (remainingBytes > 0) {      bytePtr++;        remainingBytes--;      //高2位必须是10      if ((*bytePtr & 0xc0) != 0x80) {     return -1;      }      //从次高字节往低字节,不断累加各字节的低6位      value = value << 6 | (*bytePtr & 0x3f);   }   return value;}