| 73 | const std::string protoname = STRINGIFY(PROTO); |
| 74 | |
| 75 | static uint32_t readu8(std::string::iterator& it, std::string::iterator end) |
| 76 | { |
| 77 | int len; |
| 78 | uint32_t c = *it++; |
| 79 | if (c < 0x80) |
| 80 | { |
| 81 | /* Do nothing! */ |
| 82 | len = 0; |
| 83 | } |
| 84 | else if (c < 0xc0) |
| 85 | { |
| 86 | /* Invalid character */ |
| 87 | c = -1; |
| 88 | len = 0; |
| 89 | } |
| 90 | else if (c < 0xe0) |
| 91 | { |
| 92 | /* One trailing byte */ |
| 93 | c &= 0x1f; |
| 94 | len = 1; |
| 95 | } |
| 96 | else if (c < 0xf0) |
| 97 | { |
| 98 | /* Two trailing bytes */ |
| 99 | c &= 0x0f; |
| 100 | len = 2; |
| 101 | } |
| 102 | else if (c < 0xf8) |
| 103 | { |
| 104 | /* Three trailing bytes */ |
| 105 | c &= 0x07; |
| 106 | len = 3; |
| 107 | } |
| 108 | else if (c < 0xfc) |
| 109 | { |
| 110 | /* Four trailing bytes */ |
| 111 | c &= 0x03; |
| 112 | len = 4; |
| 113 | } |
| 114 | else |
| 115 | { |
| 116 | /* Five trailing bytes */ |
| 117 | c &= 0x01; |
| 118 | len = 5; |
| 119 | } |
| 120 | |
| 121 | while (len) |
| 122 | { |
| 123 | if (it == end) |
| 124 | break; |
| 125 | |
| 126 | uint8_t d = *it++; |
| 127 | c <<= 6; |
| 128 | c += d & 0x3f; |
| 129 | } |
| 130 | return c; |
| 131 | } |
| 132 |