Changeset b888d5f in mainline
- Timestamp:
- 2009-04-03T07:52:29Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 043eca0
- Parents:
- 7ce3cb2
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/string.h
r7ce3cb2 rb888d5f 38 38 #include <typedefs.h> 39 39 40 #define UTF8_NO_LIMIT ((size_t) -1) 40 #define STR_NO_LIMIT ((size_t) -1) 41 42 /**< Maximum size of a string containing cnt characters */ 43 #define STR_BOUNDS(cnt) (cnt << 2) 41 44 42 45 extern char invalch; 43 46 44 extern wchar_t chr_decode(const char *, size_t *, size_t); 45 extern int chr_encode(wchar_t, char *, size_t *, size_t); 46 extern count_t chr_width(wchar_t); 47 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz); 48 extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz); 47 49 48 extern size_t str_size(const char *); 49 extern size_t str_lsize(const char *, count_t); 50 extern size_t str_wsize(const char *, count_t); 50 extern size_t str_size(const char *str); 51 extern size_t wstr_size(const wchar_t *str); 51 52 52 extern count_t str_length(const char *); 53 extern count_t wstr_length(const wchar_t *); 54 extern count_t wstr_wlength(const wchar_t *, count_t); 53 extern size_t str_lsize(const char *str, count_t max_len); 54 extern size_t wstr_lsize(const wchar_t *str, count_t max_len); 55 56 extern count_t str_length(const char *str); 57 extern count_t wstr_length(const wchar_t *wstr); 58 59 extern count_t str_nlength(const char *str, size_t size); 60 extern count_t wstr_nlength(const wchar_t *str, size_t size); 55 61 56 62 extern bool ascii_check(const wchar_t ch); 57 extern bool unicode_check(const wchar_t ch);63 extern bool chr_check(const wchar_t ch); 58 64 59 extern int strcmp(const char *src, const char *dst); 60 extern int strncmp(const char *src, const char *dst, size_t len); 61 extern void strncpy(char *dest, const char *src, size_t len); 65 extern int str_cmp(const char *s1, const char *s2); 66 extern int str_lcmp(const char *s1, const char *s2, count_t max_len); 62 67 63 extern char *strchr(const char *s, int i); 68 extern void str_ncpy(char *dst, const char *src, size_t size); 69 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); 70 71 extern const char *str_chr(const char *str, wchar_t ch); 72 73 extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos); 74 extern bool wstr_remove(wchar_t *str, count_t pos); 64 75 65 76 #endif -
kernel/generic/src/lib/string.c
r7ce3cb2 rb888d5f 38 38 * strings, called just strings are encoded in UTF-8. Wide strings (encoded 39 39 * in UTF-32) are supported to a limited degree. A single character is 40 * represented as wchar_t. 41 * 42 * Strings have the following metrics: 43 * 44 * Metric Abbrev. Meaning 45 * ------ ------ ------- 46 * size n Number of bytes the string is encoded into, excluding 47 * the null terminator. 48 * length l The number of characters in the string, excluding 49 * the null terminator. 50 * width w The number of character cells the string takes up on a 51 * monospace display. 52 * 53 * Naming scheme: 54 * 55 * chr_xxx operate on characters 56 * str_xxx operate on strings 57 * wstr_xxx operate on wide strings 58 * 59 * [w]str_[n|l|w]xxx operate on a prefix limited by size, length 60 * or width. 40 * represented as wchar_t.@n 41 * 42 * Overview of the terminology:@n 43 * 44 * Term Meaning 45 * -------------------- ---------------------------------------------------- 46 * byte 8 bits stored in uint8_t (unsigned 8 bit integer) 47 * 48 * character UTF-32 encoded Unicode character, stored in wchar_t 49 * (signed 32 bit integer), code points 0 .. 1114111 50 * are valid 51 * 52 * ASCII character 7 bit encoded ASCII character, stored in char 53 * (usually signed 8 bit integer), code points 0 .. 127 54 * are valid 55 * 56 * string UTF-8 encoded NULL-terminated Unicode string, char * 57 * 58 * wide string UTF-32 encoded NULL-terminated Unicode string, 59 * wchar_t * 60 * 61 * [wide] string size number of BYTES in a [wide] string (excluding 62 * the NULL-terminator), size_t 63 * 64 * [wide] string length number of CHARACTERS in a [wide] string (excluding 65 * the NULL-terminator), count_t 66 * 67 * [wide] string width number of display cells on a monospace display taken 68 * by a [wide] string, count_t 69 * 70 * 71 * Overview of string metrics:@n 72 * 73 * Metric Abbrev. Type Meaning 74 * ------ ------ ------ ------------------------------------------------- 75 * size n size_t number of BYTES in a string (excluding the 76 * NULL-terminator) 77 * 78 * length l count_t number of CHARACTERS in a string (excluding the 79 * null terminator) 80 * 81 * width w count_t number of display cells on a monospace display 82 * taken by a string 83 * 84 * 85 * Function naming prefixes:@n 86 * 87 * chr_ operate on characters 88 * ascii_ operate on ASCII characters 89 * str_ operate on strings 90 * wstr_ operate on wide strings 91 * 92 * [w]str_[n|l|w] operate on a prefix limited by size, length 93 * or width 94 * 95 * 96 * A specific character inside a [wide] string can be referred to by:@n 97 * 98 * pointer (char *, wchar_t *) 99 * byte offset (size_t) 100 * character index (count_t) 101 * 61 102 */ 62 103 … … 67 108 #include <arch.h> 68 109 #include <errno.h> 69 #include < console/kconsole.h>110 #include <align.h> 70 111 71 112 char invalch = '?'; 72 113 73 /** Byte mask consisting of lowest @n bits (out of eight).*/74 #define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1))75 76 /** Byte mask consisting of lowest @n bits (out of 32) .*/77 #define LO_MASK_32(n) ((uint32_t)((1 << (n)) - 1))78 79 /** Byte mask consisting of highest @n bits (out of eight).*/80 #define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))81 82 /** Number of data bits in a UTF-8 continuation byte .*/83 #define CONT_BITS 684 85 /** Decode a single character from a s ubstring.86 * 87 * Decode a single character from a s ubstring of size @a sz. Decoding starts114 /** Byte mask consisting of lowest @n bits (out of 8) */ 115 #define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) 116 117 /** Byte mask consisting of lowest @n bits (out of 32) */ 118 #define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1)) 119 120 /** Byte mask consisting of highest @n bits (out of 8) */ 121 #define HI_MASK_8(n) (~LO_MASK_8(8 - (n))) 122 123 /** Number of data bits in a UTF-8 continuation byte */ 124 #define CONT_BITS 6 125 126 /** Decode a single character from a string. 127 * 128 * Decode a single character from a string of size @a size. Decoding starts 88 129 * at @a offset and this offset is moved to the beginning of the next 89 130 * character. In case of decoding error, offset generally advances at least 90 * by one. However, offset is never moved beyond (str + sz). 91 * 92 * @param str String (not necessarily NULL-terminated). 93 * @param index Index (counted in plain characters) where to start 94 * the decoding. 95 * @param limit Size of the substring. 96 * 97 * @return Value of decoded character or '?' on decoding error. 98 */ 99 wchar_t chr_decode(const char *str, size_t *offset, size_t sz) 100 { 101 uint8_t b0, b; /* Bytes read from str. */ 102 wchar_t ch; 103 104 int b0_bits; /* Data bits in first byte. */ 105 int cbytes; /* Number of continuation bytes. */ 106 107 if (*offset + 1 > sz) 108 return invalch; 109 110 b0 = (uint8_t) str[(*offset)++]; 111 112 /* Determine code length. */ 113 131 * by one. However, offset is never moved beyond size. 132 * 133 * @param str String (not necessarily NULL-terminated). 134 * @param offset Byte offset in string where to start decoding. 135 * @param size Size of the string (in bytes). 136 * 137 * @return Value of decoded character, invalch on decoding error or 138 * NULL if attempt to decode beyond @a size. 139 * 140 */ 141 wchar_t str_decode(const char *str, size_t *offset, size_t size) 142 { 143 if (*offset + 1 > size) 144 return 0; 145 146 /* First byte read from string */ 147 uint8_t b0 = (uint8_t) str[(*offset)++]; 148 149 /* Determine code length */ 150 151 unsigned int b0_bits; /* Data bits in first byte */ 152 unsigned int cbytes; /* Number of continuation bytes */ 153 114 154 if ((b0 & 0x80) == 0) { 115 155 /* 0xxxxxxx (Plain ASCII) */ … … 129 169 cbytes = 3; 130 170 } else { 131 /* 10xxxxxx -- unexpected continuation byte .*/171 /* 10xxxxxx -- unexpected continuation byte */ 132 172 return invalch; 133 173 } 134 135 if (*offset + cbytes > s z) {174 175 if (*offset + cbytes > size) 136 176 return invalch; 137 } 138 139 ch = b0 & LO_MASK_8(b0_bits); 140 141 /* Decode continuation bytes. */ 177 178 wchar_t ch = b0 & LO_MASK_8(b0_bits); 179 180 /* Decode continuation bytes */ 142 181 while (cbytes > 0) { 143 b = (uint8_t) str[(*offset)++];144 145 /* Must be 10xxxxxx .*/146 if ((b & 0xc0) != 0x80) {182 uint8_t b = (uint8_t) str[(*offset)++]; 183 184 /* Must be 10xxxxxx */ 185 if ((b & 0xc0) != 0x80) 147 186 return invalch; 148 } 149 150 /* Shift data bits to ch. */ 187 188 /* Shift data bits to ch */ 151 189 ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS)); 152 --cbytes;153 } 154 190 cbytes--; 191 } 192 155 193 return ch; 156 194 } … … 162 200 * is moved to the position where the next character can be written to. 163 201 * 164 * @param ch 165 * @param str 166 * @param offset Offset (in bytes)where to start writing.167 * @param s z Size of the output buffer.202 * @param ch Input character. 203 * @param str Output buffer. 204 * @param offset Byte offset where to start writing. 205 * @param size Size of the output buffer (in bytes). 168 206 * 169 207 * @return EOK if the character was encoded successfully, EOVERFLOW if there … … 171 209 * code was invalid. 172 210 */ 173 int chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz) 174 { 175 uint32_t cc; /* Unsigned version of ch. */ 176 177 int cbytes; /* Number of continuation bytes. */ 178 int b0_bits; /* Number of data bits in first byte. */ 179 int i; 180 181 if (*offset >= sz) 211 int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size) 212 { 213 if (*offset >= size) 182 214 return EOVERFLOW; 183 184 if ( ch < 0)215 216 if (!chr_check(ch)) 185 217 return EINVAL; 186 187 /* Bit operations should only be done on unsigned numbers. */ 188 cc = (uint32_t) ch; 189 190 /* Determine how many continuation bytes are needed. */ 218 219 /* Unsigned version of ch (bit operations should only be done 220 on unsigned types). */ 221 uint32_t cc = (uint32_t) ch; 222 223 /* Determine how many continuation bytes are needed */ 224 225 unsigned int b0_bits; /* Data bits in first byte */ 226 unsigned int cbytes; /* Number of continuation bytes */ 227 191 228 if ((cc & ~LO_MASK_32(7)) == 0) { 192 229 b0_bits = 7; … … 202 239 cbytes = 3; 203 240 } else { 204 /* Codes longer than 21 bits are not supported .*/241 /* Codes longer than 21 bits are not supported */ 205 242 return EINVAL; 206 243 } 207 208 /* Check for available space in buffer .*/209 if (*offset + cbytes >= s z)244 245 /* Check for available space in buffer */ 246 if (*offset + cbytes >= size) 210 247 return EOVERFLOW; 211 212 /* Encode continuation bytes. */ 213 for (i = cbytes; i > 0; --i) { 248 249 /* Encode continuation bytes */ 250 unsigned int i; 251 for (i = cbytes; i > 0; i--) { 214 252 str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS)); 215 253 cc = cc >> CONT_BITS; 216 254 } 217 218 /* Encode first byte .*/255 256 /* Encode first byte */ 219 257 str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1); 220 221 /* Advance offset .*/222 *offset += (1 + cbytes);258 259 /* Advance offset */ 260 *offset += cbytes + 1; 223 261 224 262 return EOK; 225 263 } 226 264 227 /** Get display width of character. 228 * 229 * @param ch The character. 230 * @return Character width in display cells. 231 */ 232 count_t chr_width(wchar_t ch) 233 { 234 return 1; 235 } 236 237 /** Get size of string, with length limit. 265 /** Get size of string. 266 * 267 * Get the number of bytes which are used by the string @a str (excluding the 268 * NULL-terminator). 269 * 270 * @param str String to consider. 271 * 272 * @return Number of bytes used by the string 273 * 274 */ 275 size_t str_size(const char *str) 276 { 277 size_t size = 0; 278 279 while (*str++ != 0) 280 size++; 281 282 return size; 283 } 284 285 /** Get size of wide string. 286 * 287 * Get the number of bytes which are used by the wide string @a str (excluding the 288 * NULL-terminator). 289 * 290 * @param str Wide string to consider. 291 * 292 * @return Number of bytes used by the wide string 293 * 294 */ 295 size_t wstr_size(const wchar_t *str) 296 { 297 return (wstr_length(str) * sizeof(wchar_t)); 298 } 299 300 /** Get size of string with length limit. 238 301 * 239 302 * Get the number of bytes which are used by up to @a max_len first 240 303 * characters in the string @a str. If @a max_len is greater than 241 * the length of @a str, the entire string is measured. 242 * 243 * @param str String to consider. 244 * @param count Maximum number of characters to measure. 245 * 246 * @return Number of bytes used by the characters. 304 * the length of @a str, the entire string is measured (excluding the 305 * NULL-terminator). 306 * 307 * @param str String to consider. 308 * @param max_len Maximum number of characters to measure. 309 * 310 * @return Number of bytes used by the characters. 311 * 247 312 */ 248 313 size_t str_lsize(const char *str, count_t max_len) 249 314 { 250 315 count_t len = 0; 251 size_t cur = 0; 252 size_t prev; 253 wchar_t ch; 254 255 while (true) { 256 prev = cur; 257 if (len >= max_len) 316 size_t offset = 0; 317 318 while (len < max_len) { 319 if (str_decode(str, &offset, STR_NO_LIMIT) == 0) 258 320 break; 259 ch = chr_decode(str, &cur, UTF8_NO_LIMIT); 260 if (ch == '\0') break; 261 321 262 322 len++; 263 323 } 264 265 return prev; 266 } 267 268 /** Get size of string, with width limit. 269 * 270 * Get the number of bytes which are used by the longest prefix of @a str 271 * that can fit into @a max_width display cells. 272 * 273 * @param str String to consider. 274 * @param count Maximum number of display cells. 275 * 276 * @return Number of bytes used by the characters that fit. 277 */ 278 size_t str_wsize(const char *str, count_t max_width) 279 { 280 count_t width = 0; 281 size_t cur = 0; 282 size_t prev; 283 wchar_t ch; 284 285 while (true) { 286 prev = cur; 287 if (width >= max_width) 288 break; 289 ch = chr_decode(str, &cur, UTF8_NO_LIMIT); 290 if (ch == '\0') break; 291 292 width += chr_width(ch); 293 } 294 295 return prev; 296 } 297 298 299 /** Get length of wide string, with width limit. 300 * 301 * Get the number of characters in a wide string that can fit into @a max_width 302 * display cells. 303 * 304 * @param wstr Wide string to consider. 305 * @param count Maximum number of display cells. 306 * 307 * @return Number of bytes used by the characters that fit. 308 */ 309 count_t wstr_wlength(const wchar_t *wstr, count_t max_width) 310 { 311 count_t width = 0; 312 index_t cur = 0; 313 314 while (true) { 315 if (width >= max_width) 316 break; 317 if (wstr[cur] == '\0') break; 318 319 width += chr_width(wstr[cur]); 320 ++cur; 321 } 322 323 return (count_t) cur; 324 325 return offset; 326 } 327 328 /** Get size of wide string with length limit. 329 * 330 * Get the number of bytes which are used by up to @a max_len first 331 * wide characters in the wide string @a str. If @a max_len is greater than 332 * the length of @a str, the entire wide string is measured (excluding the 333 * NULL-terminator). 334 * 335 * @param str Wide string to consider. 336 * @param max_len Maximum number of wide characters to measure. 337 * 338 * @return Number of bytes used by the wide characters. 339 * 340 */ 341 size_t wstr_lsize(const wchar_t *str, count_t max_len) 342 { 343 return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t)); 344 } 345 346 /** Get number of characters in a string. 347 * 348 * @param str NULL-terminated string. 349 * 350 * @return Number of characters in string. 351 * 352 */ 353 count_t str_length(const char *str) 354 { 355 count_t len = 0; 356 size_t offset = 0; 357 358 while (str_decode(str, &offset, STR_NO_LIMIT) != 0) 359 len++; 360 361 return len; 362 } 363 364 /** Get number of characters in a wide string. 365 * 366 * @param str NULL-terminated wide string. 367 * 368 * @return Number of characters in @a str. 369 * 370 */ 371 count_t wstr_length(const wchar_t *wstr) 372 { 373 count_t len = 0; 374 375 while (*wstr++ != 0) 376 len++; 377 378 return len; 379 } 380 381 /** Get number of characters in a string with size limit. 382 * 383 * @param str NULL-terminated string. 384 * @param size Maximum number of bytes to consider. 385 * 386 * @return Number of characters in string. 387 * 388 */ 389 count_t str_nlength(const char *str, size_t size) 390 { 391 count_t len = 0; 392 size_t offset = 0; 393 394 while (str_decode(str, &offset, size) != 0) 395 len++; 396 397 return len; 398 } 399 400 /** Get number of characters in a string with size limit. 401 * 402 * @param str NULL-terminated string. 403 * @param size Maximum number of bytes to consider. 404 * 405 * @return Number of characters in string. 406 * 407 */ 408 count_t wstr_nlength(const wchar_t *str, size_t size) 409 { 410 count_t len = 0; 411 count_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); 412 count_t offset = 0; 413 414 while ((offset < limit) && (*str++ != 0)) { 415 len++; 416 offset += sizeof(wchar_t); 417 } 418 419 return len; 324 420 } 325 421 … … 337 433 } 338 434 339 /** Check whether character is Unicode. 340 * 341 * @return True if character is valid Unicode code point. 342 */ 343 bool unicode_check(const wchar_t ch) 435 /** Check whether character is valid 436 * 437 * @return True if character is a valid Unicode code point. 438 * 439 */ 440 bool chr_check(const wchar_t ch) 344 441 { 345 442 if ((ch >= 0) && (ch <= 1114111)) … … 349 446 } 350 447 351 /** Return number of bytes the string occupies. 352 * 353 * @param str A string. 354 * @return Number of bytes in @a str excluding the null terminator. 355 */ 356 size_t str_size(const char *str) 357 { 358 size_t size; 359 360 size = 0; 361 while (*str++ != '\0') 362 ++size; 363 364 return size; 365 } 366 367 /** Return number of characters in a string. 368 * 369 * @param str NULL-terminated string. 370 * @return Number of characters in string. 371 */ 372 count_t str_length(const char *str) 373 { 374 count_t len = 0; 375 size_t offset = 0; 376 377 while (chr_decode(str, &offset, UTF8_NO_LIMIT) != 0) { 378 len++; 379 } 380 381 return len; 382 } 383 384 /** Return number of characters in a wide string. 385 * 386 * @param str NULL-terminated wide string. 387 * @return Number of characters in @a str. 388 */ 389 count_t wstr_length(const wchar_t *wstr) 390 { 391 count_t len; 392 393 len = 0; 394 while (*wstr++ != '\0') 395 ++len; 396 397 return len; 398 } 399 400 /** Compare two NULL terminated strings 401 * 402 * Do a char-by-char comparison of two NULL terminated strings. 448 /** Compare two NULL terminated strings. 449 * 450 * Do a char-by-char comparison of two NULL-terminated strings. 403 451 * The strings are considered equal iff they consist of the same 404 452 * characters on the minimum of their lengths. 405 453 * 406 * @param src First string to compare. 407 * @param dst Second string to compare. 408 * 409 * @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. 410 * 411 */ 412 int strcmp(const char *src, const char *dst) 413 { 414 for (; *src && *dst; src++, dst++) { 415 if (*src < *dst) 454 * @param s1 First string to compare. 455 * @param s2 Second string to compare. 456 * 457 * @return 0 if the strings are equal, -1 if first is smaller, 458 * 1 if second smaller. 459 * 460 */ 461 int str_cmp(const char *s1, const char *s2) 462 { 463 wchar_t c1; 464 wchar_t c2; 465 466 size_t off1 = 0; 467 size_t off2 = 0; 468 469 while ((c1 = str_decode(s1, &off1, STR_NO_LIMIT) != 0) 470 && (c2 = str_decode(s2, &off2, STR_NO_LIMIT) != 0)) { 471 472 if (off1 != off2) 473 break; 474 475 if (c1 < c2) 416 476 return -1; 417 if (*src > *dst) 477 478 if (c1 > c2) 418 479 return 1; 419 480 } 420 if (*src == *dst) 481 482 if ((off1 == off2) && (c1 == c2)) 421 483 return 0; 422 484 423 if ( !*src)485 if ((c1 == 0) || (off1 < off2)) 424 486 return -1; 425 487 … … 427 489 } 428 490 429 430 /** Compare two NULL terminated strings 431 * 432 * Do a char-by-char comparison of two NULL terminated strings. 491 /** Compare two NULL terminated strings with length limit. 492 * 493 * Do a char-by-char comparison of two NULL-terminated strings. 433 494 * The strings are considered equal iff they consist of the same 434 * characters on the minimum of their lengths and specified maximal 435 * length. 436 * 437 * @param src First string to compare. 438 * @param dst Second string to compare. 439 * @param len Maximal length for comparison. 440 * 441 * @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. 442 */ 443 int strncmp(const char *src, const char *dst, size_t len) 444 { 445 unsigned int i; 446 447 for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) { 448 if (*src < *dst) 495 * characters on the minimum of their lengths and the length limit. 496 * 497 * @param s1 First string to compare. 498 * @param s2 Second string to compare. 499 * @param max_len Maximum number of characters to consider. 500 * 501 * @return 0 if the strings are equal, -1 if first is smaller, 502 * 1 if second smaller. 503 * 504 */ 505 int str_lcmp(const char *s1, const char *s2, count_t max_len) 506 { 507 wchar_t c1 = 0; 508 wchar_t c2 = 0; 509 510 size_t off1 = 0; 511 size_t off2 = 0; 512 513 count_t len = 0; 514 515 while ((len < max_len) 516 && ((c1 = str_decode(s1, &off1, STR_NO_LIMIT)) != 0) 517 && ((c2 = str_decode(s2, &off2, STR_NO_LIMIT)) != 0)) { 518 519 if (off1 != off2) 520 break; 521 522 if (c1 < c2) 449 523 return -1; 450 524 451 if ( *src > *dst)525 if (c1 > c2) 452 526 return 1; 453 } 454 455 if (i == len || *src == *dst) 527 528 len++; 529 } 530 531 if ((off1 == off2) && (len == max_len) && (c1 == c2)) 456 532 return 0; 457 533 458 if ( !*src)534 if ((c1 == 0) || (off1 < off2)) 459 535 return -1; 460 536 … … 462 538 } 463 539 464 465 466 /** Copy NULL terminated string. 467 * 468 * Copy at most 'len' characters from string 'src' to 'dest'. 469 * If 'src' is shorter than 'len', '\0' is inserted behind the 470 * last copied character. 471 * 472 * @param src Source string. 473 * @param dest Destination buffer. 474 * @param len Size of destination buffer. 475 */ 476 void strncpy(char *dest, const char *src, size_t len) 477 { 478 unsigned int i; 479 480 for (i = 0; i < len; i++) { 481 if (!(dest[i] = src[i])) 482 return; 483 } 484 485 dest[i - 1] = '\0'; 540 /** Copy NULL-terminated string. 541 * 542 * Copy source string @a src to destination buffer @a dst. 543 * No more than @a size bytes are written. NULL-terminator is always 544 * written after the last succesfully copied character (i.e. if the 545 * destination buffer is has at least 1 byte, it will be always 546 * NULL-terminated). 547 * 548 * @param src Source string. 549 * @param dst Destination buffer. 550 * @param count Size of the destination buffer. 551 * 552 */ 553 void str_ncpy(char *dst, const char *src, size_t size) 554 { 555 /* No space for the NULL-terminator in the buffer */ 556 if (size == 0) 557 return; 558 559 wchar_t ch; 560 size_t str_off = 0; 561 size_t dst_off = 0; 562 563 while ((ch = str_decode(src, &str_off, STR_NO_LIMIT) != 0)) { 564 if (chr_encode(ch, dst, &dst_off, size) != EOK) 565 break; 566 } 567 568 if (dst_off >= size) 569 dst[size - 1] = 0; 570 else 571 dst[dst_off] = 0; 572 } 573 574 /** Copy NULL-terminated wide string to string 575 * 576 * Copy source wide string @a src to destination buffer @a dst. 577 * No more than @a size bytes are written. NULL-terminator is always 578 * written after the last succesfully copied character (i.e. if the 579 * destination buffer is has at least 1 byte, it will be always 580 * NULL-terminated). 581 * 582 * @param src Source wide string. 583 * @param dst Destination buffer. 584 * @param count Size of the destination buffer. 585 * 586 */ 587 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 588 { 589 /* No space for the NULL-terminator in the buffer */ 590 if (size == 0) 591 return; 592 593 wchar_t ch; 594 count_t src_idx = 0; 595 size_t dst_off = 0; 596 597 while ((ch = src[src_idx++]) != 0) { 598 if (chr_encode(ch, dst, &dst_off, size) != EOK) 599 break; 600 } 601 602 if (dst_off >= size) 603 dst[size - 1] = 0; 604 else 605 dst[dst_off] = 0; 486 606 } 487 607 488 608 /** Find first occurence of character in string. 489 609 * 490 * @param s String to search. 491 * @param i Character to look for. 492 * 493 * @return Pointer to character in @a s or NULL if not found. 494 */ 495 extern char *strchr(const char *s, int i) 496 { 497 while (*s != '\0') { 498 if (*s == i) 499 return (char *) s; 500 ++s; 610 * @param str String to search. 611 * @param ch Character to look for. 612 * 613 * @return Pointer to character in @a str or NULL if not found. 614 * 615 */ 616 const char *str_chr(const char *str, wchar_t ch) 617 { 618 wchar_t acc; 619 size_t off = 0; 620 621 while ((acc = str_decode(str, &off, STR_NO_LIMIT) != 0)) { 622 if (acc == ch) 623 return (str + off); 501 624 } 502 625 … … 504 627 } 505 628 629 /** Insert a wide character into a wide string. 630 * 631 * Insert a wide character into a wide string at position 632 * @a pos. The characters after the position are shifted. 633 * 634 * @param str String to insert to. 635 * @param ch Character to insert to. 636 * @param pos Character index where to insert. 637 @ @param max_pos Characters in the buffer. 638 * 639 * @return True if the insertion was sucessful, false if the position 640 * is out of bounds. 641 * 642 */ 643 bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos) 644 { 645 count_t len = wstr_length(str); 646 647 if ((pos > len) || (pos + 1 > max_pos)) 648 return false; 649 650 count_t i; 651 for (i = len; i + 1 > pos; i--) 652 str[i + 1] = str[i]; 653 654 str[pos] = ch; 655 656 return true; 657 } 658 659 /** Remove a wide character from a wide string. 660 * 661 * Remove a wide character from a wide string at position 662 * @a pos. The characters after the position are shifted. 663 * 664 * @param str String to remove from. 665 * @param pos Character index to remove. 666 * 667 * @return True if the removal was sucessful, false if the position 668 * is out of bounds. 669 * 670 */ 671 bool wstr_remove(wchar_t *str, count_t pos) 672 { 673 count_t len = wstr_length(str); 674 675 if (pos >= len) 676 return false; 677 678 count_t i; 679 for (i = pos + 1; i <= len; i++) 680 str[i - 1] = str[i]; 681 682 return true; 683 } 684 506 685 /** @} 507 686 */
Note:
See TracChangeset
for help on using the changeset viewer.