00001 #include <cstring>
00002
00003 namespace OW_NAMESPACE
00004 {
00005 class String;
00006
00007 namespace SafeCString
00008 {
00009
00013 char * str_dup(char const * s);
00014
00019 char * str_dup_nothrow(char const * s);
00020
00021
00027 inline char const * nonull(char const * s)
00028 {
00029 return s ? s : "";
00030 }
00031
00032
00048 char * strcpy_trunc(char * dst, std::size_t dstsize, char const * src);
00049
00065 char * strcpy_trunc(
00066 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00067 );
00068
00072 template <std::size_t N> inline
00073 char * strcpy_trunc(char (&dst)[N], char const * src)
00074 {
00075 return strcpy_trunc(dst, N, src);
00076 }
00077
00081 template <std::size_t N> inline
00082 char * strcpy_trunc(char (&dst)[N], char const * src, std::size_t srclen)
00083 {
00084 return strcpy_trunc(dst, N, src, srclen);
00085 }
00086
00091 template <std::size_t N> inline
00092 std::size_t strcpy_to_pos_trunc(
00093 char (&dst)[N], std::size_t pos, char const * src
00094 )
00095 {
00096 return strcpy_trunc(dst + pos, N - pos, src) - dst;
00097 }
00098
00103 template <std::size_t N> inline
00104 std::size_t strcpy_to_pos_trunc(
00105 char (&dst)[N], std::size_t pos, char const * src, std::size_t srclen
00106 )
00107 {
00108 return strcpy_trunc(dst + pos, N - pos, src, srclen) - dst;
00109 }
00110
00111 OW_DECLARE_EXCEPTION(Overflow);
00113 int const RESULT_TRUNCATED = 0;
00114 int const DEST_UNTERMINATED = 1;
00115
00133 char * strcpy_check(char * dst, std::size_t dstsize, char const * src);
00134
00152 char * strcpy_check(
00153 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00154 );
00155
00159 template <std::size_t N> inline
00160 char * strcpy_check(char (&dst)[N], char const * src)
00161 {
00162 return strcpy_check(dst, N, src);
00163 }
00164
00168 template <std::size_t N> inline
00169 char * strcpy_check(char (&dst)[N], char const * src, std::size_t srclen)
00170 {
00171 return strcpy_check(dst, N, src, srclen);
00172 }
00173
00178 template <std::size_t N> inline
00179 std::size_t strcpy_to_pos_check(
00180 char (&dst)[N], std::size_t pos, char const * src
00181 )
00182 {
00183 return strcpy_check(dst + pos, N - pos, src) - dst;
00184 }
00185
00190 template <std::size_t N> inline
00191 std::size_t strcpy_to_pos_check(
00192 char (&dst)[N], std::size_t pos, char const * src, std::size_t srclen
00193 )
00194 {
00195 return strcpy_check(dst + pos, N - pos, src, srclen) - dst;
00196 }
00197
00198
00216 char * strcat_trunc(char * dst, std::size_t dstsize, char const * src);
00217
00236 char * strcat_trunc(
00237 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00238 );
00239
00243 template <std::size_t N> inline
00244 char * strcat_trunc(char (&dst)[N], char const * src)
00245 {
00246 return strcat_trunc(dst, N, src);
00247 }
00248
00252 template <std::size_t N> inline
00253 char * strcat_trunc(char (&dst)[N], char const * src, std::size_t srclen)
00254 {
00255 return strcat_trunc(dst, N, src, srclen);
00256 }
00257
00279 char * strcat_check(char * dst, std::size_t dstsize, char const * src);
00280
00303 char * strcat_check(
00304 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00305 );
00306
00310 template <std::size_t N> inline
00311 char * strcat_check(char (&dst)[N], char const * src)
00312 {
00313 return strcat_check(dst, N, src);
00314 }
00315
00319 template <std::size_t N> inline
00320 char * strcat_check(char (&dst)[N], char const * src, std::size_t srclen)
00321 {
00322 return strcat_check(dst, N, src, srclen);
00323 }
00324
00325
00326 namespace Impl
00327 {
00328 inline std::size_t nchars_output(int retval, std::size_t dstsize)
00329 {
00330 return (
00331 retval < 0 || retval >= static_cast<int>(dstsize) ? dstsize - 1
00332 : static_cast<std::size_t>(retval)
00333 );
00334 }
00335
00336 std::size_t nchars_check(int retval, std::size_t dstsize);
00337 }
00338
00345 template <typename T1>
00346 std::size_t sprintf_trunc(
00347 char * dst, std::size_t dstsize, char const * fmt, T1 const & x1
00348 )
00349 {
00350 return Impl::nchars_output(snprintf(dst, dstsize, fmt, x1), dstsize);
00351 }
00352
00359 template <typename T1, typename T2>
00360 std::size_t sprintf_trunc(
00361 char * dst, std::size_t dstsize, char const * fmt,
00362 T1 const & x1, T2 const & x2
00363 )
00364 {
00365 return Impl::nchars_output(
00366 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00367 }
00368
00375 template <typename T1, typename T2>
00376 std::size_t sprintf_trunc(
00377 char * dst, std::size_t dstsize, char const * fmt,
00378 T1 const & x1, T2 const & x2
00379 )
00380 {
00381 return Impl::nchars_output(
00382 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00383 }
00384
00391 template <typename T1, typename T2, typename T3>
00392 std::size_t sprintf_trunc(
00393 char * dst, std::size_t dstsize, char const * fmt,
00394 T1 const & x1, T2 const & x2, T3 const & x3
00395 )
00396 {
00397 return Impl::nchars_output(
00398 snprintf(dst, dstsize, fmt, x1, x2, x3), dstsize);
00399 }
00400
00407 template <typename T1, typename T2, typename T3, typename T4>
00408 std::size_t sprintf_trunc(
00409 char * dst, std::size_t dstsize, char const * fmt,
00410 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00411 )
00412 {
00413 return Impl::nchars_output(
00414 snprintf(dst, dstsize, fmt, x1, x2, x3, x4), dstsize);
00415 }
00416
00423 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00424 std::size_t sprintf_trunc(
00425 char * dst, std::size_t dstsize, char const * fmt,
00426 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00427 )
00428 {
00429 return Impl::nchars_output(
00430 snprintf(dst, dstsize, fmt, x1, x2, x3, x4, x5), dstsize);
00431 }
00432
00436 template <std::size_t N, typename T1>
00437 std::size_t sprintf_trunc(char (&dst)[N], char const * fmt, T1 const & x1)
00438 {
00439 return Impl::nchars_output(snprintf(dst, N, fmt, x1), N);
00440 }
00441
00445 template <std::size_t N, typename T1, typename T2>
00446 std::size_t sprintf_trunc(
00447 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00448 )
00449 {
00450 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2), N);
00451 }
00452
00456 template <std::size_t N, typename T1, typename T2>
00457 std::size_t sprintf_trunc(
00458 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00459 )
00460 {
00461 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2), N);
00462 }
00463
00467 template <std::size_t N, typename T1, typename T2, typename T3>
00468 std::size_t sprintf_trunc(
00469 char (&dst)[N], char const * fmt,
00470 T1 const & x1, T2 const & x2, T3 const & x3
00471 )
00472 {
00473 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2, x3), N);
00474 }
00475
00479 template <std::size_t N, typename T1, typename T2, typename T3, typename T4>
00480 std::size_t sprintf_trunc(
00481 char (&dst)[N], char const * fmt,
00482 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00483 )
00484 {
00485 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2, x3, x4), N);
00486 }
00487
00491 template <std::size_t N, typename T1, typename T2, typename T3, typename T4,
00492 typename T5>
00493 std::size_t sprintf_trunc(
00494 char (&dst)[N], char const * fmt,
00495 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00496 )
00497 {
00498 return Impl::nchars_output(
00499 snprintf(dst, N, fmt, x1, x2, x3, x4, x5), N);
00500 }
00501
00502
00511 template <typename T1>
00512 std::size_t sprintf_check(
00513 char * dst, std::size_t dstsize, char const * fmt, T1 const & x1
00514 )
00515 {
00516 return Impl::nchars_check(snprintf(dst, dstsize, fmt, x1), dstsize);
00517 }
00518
00527 template <typename T1, typename T2>
00528 std::size_t sprintf_check(
00529 char * dst, std::size_t dstsize, char const * fmt,
00530 T1 const & x1, T2 const & x2
00531 )
00532 {
00533 return Impl::nchars_check(
00534 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00535 }
00536
00545 template <typename T1, typename T2>
00546 std::size_t sprintf_check(
00547 char * dst, std::size_t dstsize, char const * fmt,
00548 T1 const & x1, T2 const & x2
00549 )
00550 {
00551 return Impl::nchars_check(
00552 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00553 }
00554
00563 template <typename T1, typename T2, typename T3>
00564 std::size_t sprintf_check(
00565 char * dst, std::size_t dstsize, char const * fmt,
00566 T1 const & x1, T2 const & x2, T3 const & x3
00567 )
00568 {
00569 return Impl::nchars_check(
00570 snprintf(dst, dstsize, fmt, x1, x2, x3), dstsize);
00571 }
00572
00581 template <typename T1, typename T2, typename T3, typename T4>
00582 std::size_t sprintf_check(
00583 char * dst, std::size_t dstsize, char const * fmt,
00584 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00585 )
00586 {
00587 return Impl::nchars_check(
00588 snprintf(dst, dstsize, fmt, x1, x2, x3, x4), dstsize);
00589 }
00590
00599 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00600 std::size_t sprintf_check(
00601 char * dst, std::size_t dstsize, char const * fmt,
00602 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00603 )
00604 {
00605 return Impl::nchars_check(
00606 snprintf(dst, dstsize, fmt, x1, x2, x3, x4, x5), dstsize);
00607 }
00608
00612 template <std::size_t N, typename T1>
00613 std::size_t sprintf_check(char (&dst)[N], char const * fmt, T1 const & x1)
00614 {
00615 return Impl::nchars_check(snprintf(dst, N, fmt, x1), N);
00616 }
00617
00621 template <std::size_t N, typename T1, typename T2>
00622 std::size_t sprintf_check(
00623 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00624 )
00625 {
00626 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2), N);
00627 }
00628
00632 template <std::size_t N, typename T1, typename T2>
00633 std::size_t sprintf_check(
00634 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00635 )
00636 {
00637 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2), N);
00638 }
00639
00643 template <std::size_t N, typename T1, typename T2, typename T3>
00644 std::size_t sprintf_check(
00645 char (&dst)[N], char const * fmt,
00646 T1 const & x1, T2 const & x2, T3 const & x3
00647 )
00648 {
00649 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3), N);
00650 }
00651
00655 template <std::size_t N, typename T1, typename T2, typename T3, typename T4>
00656 std::size_t sprintf_check(
00657 char (&dst)[N], char const * fmt,
00658 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00659 )
00660 {
00661 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3, x4), N);
00662 }
00663
00667 template <std::size_t N, typename T1, typename T2, typename T3, typename T4,
00668 typename T5>
00669 std::size_t sprintf_check(
00670 char (&dst)[N], char const * fmt,
00671 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00672 )
00673 {
00674 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3, x4, x5), N);
00675 }
00676
00677
00684 template <typename T1>
00685 std::size_t vprintf_trunc(
00686 char * dst, std::size_t dstsize, char const * fmt, va_list ap
00687 )
00688 {
00689 return Impl::nchars_output(vsnprintf(dst, dstsize, fmt, ap), dstsize);
00690 }
00691
00695 template <std::size_t N> inline
00696 std::size_t vprintf_trunc(char (&dst)[N], char const * fmt, va_list ap)
00697 {
00698 return vprintf_trunc(dst, N, fmt, ap);
00699 }
00700
00701
00710 inline std::size_t vprintf_check(
00711 char * dst, std::size_t dstsize, char const * fmt, va_list ap
00712 )
00713 {
00714 return Impl::nchars_check(vsnprintf(dst, dstsize, fmt, ap), dstsize);
00715 }
00716
00720 template <std::size_t N> inline
00721 std::size_t vprintf_check(char (&dst)[N], char const * fmt, va_list ap)
00722 {
00723 return vprintf_check(dst, N, fmt, ap);
00724 }
00725
00726
00727 struct FILE;
00728
00739 char * fgets_trunc(char * dst, std::size_t dstsize, FILE * fp);
00740
00744 template <std::size_t N> inline
00745 char * fgets_trunc(char (&dst)[N], FILE * fp)
00746 {
00747 return fgets_trunc(dst, N, fp);
00748 }
00749
00763 char * fgets_check(char * dst, std::size_t dstsize, FILE * fp);
00764
00768 template <std::size_t N> inline
00769 char * fgets_check(char (&dst)[N], FILE * fp)
00770 {
00771 return fgets_check(dst, N, fp);
00772 }
00773
00785 String fget_string(FILE * fp, std::size_t const max_chars);
00786
00787
00788 #define OW_INTSTR_AUX(x) # x
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 #define OW_INTSTR(x) OW_INTSTR_AUX(x)
00799
00800 }
00801 }