Changeset 32704cb in mainline
- Timestamp:
- 2009-03-31T18:50:09Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b54d2f1
- Parents:
- 0dd1d444
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/string.c
r0dd1d444 r32704cb 45 45 char invalch = '?'; 46 46 47 /** Byte mask consisting of bits 0 - (@n - 1)*/47 /** Byte mask consisting of lowest @n bits (out of eight). */ 48 48 #define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1)) 49 50 /** Byte mask consisting of lowest @n bits (out of 32). */ 51 #define LO_MASK_32(n) ((uint32_t)((1 << (n)) - 1)) 52 53 /** Byte mask consisting of highest @n bits (out of eight). */ 54 #define HI_MASK_8(n) (~LO_MASK_8(8 - (n))) 49 55 50 56 /** Number of data bits in a UTF-8 continuation byte. */ … … 145 151 bool utf8_encode(const wchar_t ch, char *str, index_t *index, index_t limit) 146 152 { 153 uint32_t cc; /* Unsigned version of ch. */ 154 155 int cbytes; /* Number of continuation bytes. */ 156 int b0_bits; /* Number of data bits in first byte. */ 157 int i; 158 147 159 if (*index > limit) 148 160 return false; 149 150 if ((ch >= 0) && (ch <= 127)) { 151 /* Plain ASCII (code points 0 .. 127) */ 152 str[*index] = ch & 0x7f; 153 return true; 154 } 155 156 if ((ch >= 128) && (ch <= 2047)) { 157 /* Code points 128 .. 2047 */ 158 if (*index + 1 > limit) 159 return false; 160 161 str[*index] = 0xc0 | ((ch >> 6) & 0x1f); 162 (*index)++; 163 str[*index] = 0x80 | (ch & 0x3f); 164 return true; 165 } 166 167 if ((ch >= 2048) && (ch <= 65535)) { 168 /* Code points 2048 .. 65535 */ 169 if (*index + 2 > limit) 170 return false; 171 172 str[*index] = 0xe0 | ((ch >> 12) & 0x0f); 173 (*index)++; 174 str[*index] = 0x80 | ((ch >> 6) & 0x3f); 175 (*index)++; 176 str[*index] = 0x80 | (ch & 0x3f); 177 return true; 178 } 179 180 if ((ch >= 65536) && (ch <= 1114111)) { 181 /* Code points 65536 .. 1114111 */ 182 if (*index + 3 > limit) 183 return false; 184 185 str[*index] = 0xf0 | ((ch >> 18) & 0x07); 186 (*index)++; 187 str[*index] = 0x80 | ((ch >> 12) & 0x3f); 188 (*index)++; 189 str[*index] = 0x80 | ((ch >> 6) & 0x3f); 190 (*index)++; 191 str[*index] = 0x80 | (ch & 0x3f); 192 return true; 193 } 194 195 return false; 161 162 if (ch < 0) 163 return false; 164 165 /* Bit operations should only be done on unsigned numbers. */ 166 cc = (uint32_t) ch; 167 168 /* Determine how many continuation bytes are needed. */ 169 if ((cc & ~LO_MASK_32(7)) == 0) { 170 b0_bits = 7; 171 cbytes = 0; 172 } else if ((cc & ~LO_MASK_32(11)) == 0) { 173 b0_bits = 5; 174 cbytes = 1; 175 } else if ((cc & ~LO_MASK_32(16)) == 0) { 176 b0_bits = 4; 177 cbytes = 2; 178 } else if ((cc & ~LO_MASK_32(21)) == 0) { 179 b0_bits = 3; 180 cbytes = 3; 181 } else { 182 /* Codes longer than 21 bits are not supported. */ 183 return false; 184 } 185 186 /* Check for available space in buffer. */ 187 if (*index + cbytes > limit) 188 return false; 189 190 /* Encode continuation bytes. */ 191 for (i = cbytes; i > 0; --i) { 192 str[*index + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS)); 193 cc = cc >> CONT_BITS; 194 } 195 196 /* Encode first byte. */ 197 str[*index] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1); 198 199 /* Advance index. */ 200 *index += cbytes; 201 202 return true; 196 203 } 197 204
Note:
See TracChangeset
for help on using the changeset viewer.