Changeset f2b8cdc in mainline for uspace/lib/libc/generic/string.c
- Timestamp:
- 2009-04-04T22:04:28Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade
- Children:
- b27eb71
- Parents:
- 4527fb5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/string.c
r4527fb5 rf2b8cdc 40 40 #include <malloc.h> 41 41 #include <errno.h> 42 #include <align.h> 42 43 #include <string.h> 43 44 … … 193 194 } 194 195 196 /** Get size of string. 197 * 198 * Get the number of bytes which are used by the string @a str (excluding the 199 * NULL-terminator). 200 * 201 * @param str String to consider. 202 * 203 * @return Number of bytes used by the string 204 * 205 */ 206 size_t str_size(const char *str) 207 { 208 size_t size = 0; 209 210 while (*str++ != 0) 211 size++; 212 213 return size; 214 } 215 216 /** Get size of wide string. 217 * 218 * Get the number of bytes which are used by the wide string @a str (excluding the 219 * NULL-terminator). 220 * 221 * @param str Wide string to consider. 222 * 223 * @return Number of bytes used by the wide string 224 * 225 */ 226 size_t wstr_size(const wchar_t *str) 227 { 228 return (wstr_length(str) * sizeof(wchar_t)); 229 } 230 231 /** Get size of string with length limit. 232 * 233 * Get the number of bytes which are used by up to @a max_len first 234 * characters in the string @a str. If @a max_len is greater than 235 * the length of @a str, the entire string is measured (excluding the 236 * NULL-terminator). 237 * 238 * @param str String to consider. 239 * @param max_len Maximum number of characters to measure. 240 * 241 * @return Number of bytes used by the characters. 242 * 243 */ 244 size_t str_lsize(const char *str, count_t max_len) 245 { 246 count_t len = 0; 247 size_t offset = 0; 248 249 while (len < max_len) { 250 if (str_decode(str, &offset, STR_NO_LIMIT) == 0) 251 break; 252 253 len++; 254 } 255 256 return offset; 257 } 258 259 /** Get size of wide string with length limit. 260 * 261 * Get the number of bytes which are used by up to @a max_len first 262 * wide characters in the wide string @a str. If @a max_len is greater than 263 * the length of @a str, the entire wide string is measured (excluding the 264 * NULL-terminator). 265 * 266 * @param str Wide string to consider. 267 * @param max_len Maximum number of wide characters to measure. 268 * 269 * @return Number of bytes used by the wide characters. 270 * 271 */ 272 size_t wstr_lsize(const wchar_t *str, count_t max_len) 273 { 274 return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t)); 275 } 276 277 /** Get number of characters in a string. 278 * 279 * @param str NULL-terminated string. 280 * 281 * @return Number of characters in string. 282 * 283 */ 284 count_t str_length(const char *str) 285 { 286 count_t len = 0; 287 size_t offset = 0; 288 289 while (str_decode(str, &offset, STR_NO_LIMIT) != 0) 290 len++; 291 292 return len; 293 } 294 295 /** Get number of characters in a wide string. 296 * 297 * @param str NULL-terminated wide string. 298 * 299 * @return Number of characters in @a str. 300 * 301 */ 302 count_t wstr_length(const wchar_t *wstr) 303 { 304 count_t len = 0; 305 306 while (*wstr++ != 0) 307 len++; 308 309 return len; 310 } 311 312 /** Get number of characters in a string with size limit. 313 * 314 * @param str NULL-terminated string. 315 * @param size Maximum number of bytes to consider. 316 * 317 * @return Number of characters in string. 318 * 319 */ 320 count_t str_nlength(const char *str, size_t size) 321 { 322 count_t len = 0; 323 size_t offset = 0; 324 325 while (str_decode(str, &offset, size) != 0) 326 len++; 327 328 return len; 329 } 330 331 /** Get number of characters in a string with size limit. 332 * 333 * @param str NULL-terminated string. 334 * @param size Maximum number of bytes to consider. 335 * 336 * @return Number of characters in string. 337 * 338 */ 339 count_t wstr_nlength(const wchar_t *str, size_t size) 340 { 341 count_t len = 0; 342 count_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); 343 count_t offset = 0; 344 345 while ((offset < limit) && (*str++ != 0)) { 346 len++; 347 offset += sizeof(wchar_t); 348 } 349 350 return len; 351 } 352 353 /** Check whether character is plain ASCII. 354 * 355 * @return True if character is plain ASCII. 356 * 357 */ 358 bool ascii_check(wchar_t ch) 359 { 360 if ((ch >= 0) && (ch <= 127)) 361 return true; 362 363 return false; 364 } 365 195 366 /** Check whether character is valid 196 367 * … … 198 369 * 199 370 */ 200 bool chr_check( constwchar_t ch)371 bool chr_check(wchar_t ch) 201 372 { 202 373 if ((ch >= 0) && (ch <= 1114111)) … … 204 375 205 376 return false; 377 } 378 379 /** Compare two NULL terminated strings. 380 * 381 * Do a char-by-char comparison of two NULL-terminated strings. 382 * The strings are considered equal iff they consist of the same 383 * characters on the minimum of their lengths. 384 * 385 * @param s1 First string to compare. 386 * @param s2 Second string to compare. 387 * 388 * @return 0 if the strings are equal, -1 if first is smaller, 389 * 1 if second smaller. 390 * 391 */ 392 int str_cmp(const char *s1, const char *s2) 393 { 394 wchar_t c1 = 0; 395 wchar_t c2 = 0; 396 397 size_t off1 = 0; 398 size_t off2 = 0; 399 400 while (true) { 401 c1 = str_decode(s1, &off1, STR_NO_LIMIT); 402 c2 = str_decode(s2, &off2, STR_NO_LIMIT); 403 404 if (c1 < c2) 405 return -1; 406 407 if (c1 > c2) 408 return 1; 409 410 if (c1 == 0 || c2 == 0) 411 break; 412 } 413 414 return 0; 415 } 416 417 /** Compare two NULL terminated strings with length limit. 418 * 419 * Do a char-by-char comparison of two NULL-terminated strings. 420 * The strings are considered equal iff they consist of the same 421 * characters on the minimum of their lengths and the length limit. 422 * 423 * @param s1 First string to compare. 424 * @param s2 Second string to compare. 425 * @param max_len Maximum number of characters to consider. 426 * 427 * @return 0 if the strings are equal, -1 if first is smaller, 428 * 1 if second smaller. 429 * 430 */ 431 int str_lcmp(const char *s1, const char *s2, count_t max_len) 432 { 433 wchar_t c1 = 0; 434 wchar_t c2 = 0; 435 436 size_t off1 = 0; 437 size_t off2 = 0; 438 439 count_t len = 0; 440 441 while (true) { 442 if (len >= max_len) 443 break; 444 445 c1 = str_decode(s1, &off1, STR_NO_LIMIT); 446 c2 = str_decode(s2, &off2, STR_NO_LIMIT); 447 448 if (c1 < c2) 449 return -1; 450 451 if (c1 > c2) 452 return 1; 453 454 if (c1 == 0 || c2 == 0) 455 break; 456 457 ++len; 458 } 459 460 return 0; 461 462 } 463 464 /** Copy NULL-terminated string. 465 * 466 * Copy source string @a src to destination buffer @a dst. 467 * No more than @a size bytes are written. NULL-terminator is always 468 * written after the last succesfully copied character (i.e. if the 469 * destination buffer is has at least 1 byte, it will be always 470 * NULL-terminated). 471 * 472 * @param src Source string. 473 * @param dst Destination buffer. 474 * @param count Size of the destination buffer. 475 * 476 */ 477 void str_ncpy(char *dst, const char *src, size_t size) 478 { 479 /* No space for the NULL-terminator in the buffer */ 480 if (size == 0) 481 return; 482 483 wchar_t ch; 484 size_t str_off = 0; 485 size_t dst_off = 0; 486 487 while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { 488 if (chr_encode(ch, dst, &dst_off, size) != EOK) 489 break; 490 } 491 492 if (dst_off >= size) 493 dst[size - 1] = 0; 494 else 495 dst[dst_off] = 0; 496 } 497 498 /** Copy NULL-terminated wide string to string 499 * 500 * Copy source wide string @a src to destination buffer @a dst. 501 * No more than @a size bytes are written. NULL-terminator is always 502 * written after the last succesfully copied character (i.e. if the 503 * destination buffer is has at least 1 byte, it will be always 504 * NULL-terminated). 505 * 506 * @param src Source wide string. 507 * @param dst Destination buffer. 508 * @param count Size of the destination buffer. 509 * 510 */ 511 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 512 { 513 /* No space for the NULL-terminator in the buffer */ 514 if (size == 0) 515 return; 516 517 wchar_t ch; 518 count_t src_idx = 0; 519 size_t dst_off = 0; 520 521 while ((ch = src[src_idx++]) != 0) { 522 if (chr_encode(ch, dst, &dst_off, size) != EOK) 523 break; 524 } 525 526 if (dst_off >= size) 527 dst[size - 1] = 0; 528 else 529 dst[dst_off] = 0; 530 } 531 532 /** Find first occurence of character in string. 533 * 534 * @param str String to search. 535 * @param ch Character to look for. 536 * 537 * @return Pointer to character in @a str or NULL if not found. 538 * 539 */ 540 const char *str_chr(const char *str, wchar_t ch) 541 { 542 wchar_t acc; 543 size_t off = 0; 544 545 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 546 if (acc == ch) 547 return (str + off); 548 } 549 550 return NULL; 551 } 552 553 /** Insert a wide character into a wide string. 554 * 555 * Insert a wide character into a wide string at position 556 * @a pos. The characters after the position are shifted. 557 * 558 * @param str String to insert to. 559 * @param ch Character to insert to. 560 * @param pos Character index where to insert. 561 @ @param max_pos Characters in the buffer. 562 * 563 * @return True if the insertion was sucessful, false if the position 564 * is out of bounds. 565 * 566 */ 567 bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos) 568 { 569 count_t len = wstr_length(str); 570 571 if ((pos > len) || (pos + 1 > max_pos)) 572 return false; 573 574 count_t i; 575 for (i = len; i + 1 > pos; i--) 576 str[i + 1] = str[i]; 577 578 str[pos] = ch; 579 580 return true; 581 } 582 583 /** Remove a wide character from a wide string. 584 * 585 * Remove a wide character from a wide string at position 586 * @a pos. The characters after the position are shifted. 587 * 588 * @param str String to remove from. 589 * @param pos Character index to remove. 590 * 591 * @return True if the removal was sucessful, false if the position 592 * is out of bounds. 593 * 594 */ 595 bool wstr_remove(wchar_t *str, count_t pos) 596 { 597 count_t len = wstr_length(str); 598 599 if (pos >= len) 600 return false; 601 602 count_t i; 603 for (i = pos + 1; i <= len; i++) 604 str[i - 1] = str[i]; 605 606 return true; 206 607 } 207 608
Note:
See TracChangeset
for help on using the changeset viewer.