00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00038 #ifndef BLOCXX_SAFE_CSTRING_HPP_INCLUDE_GUARD_
00039 #define BLOCXX_SAFE_CSTRING_HPP_INCLUDE_GUARD_
00040
00041 #include "blocxx/BLOCXX_config.h"
00042 #include <cstddef>
00043 #include <cstdarg>
00044 #include <cstdio>
00045 #include "blocxx/Exception.hpp"
00046
00047
00048 namespace BLOCXX_NAMESPACE
00049 {
00050
00051 namespace SafeCString
00052 {
00053 #ifdef BLOCXX_WIN32
00054 #define vsnprintf _vsnprintf
00055 #endif
00056
00060 BLOCXX_COMMON_API char * str_dup(char const * s);
00061
00066 char * str_dup_nothrow(char const * s);
00067
00068
00074 inline char const * nonull(char const * s)
00075 {
00076 return s ? s : "";
00077 }
00078
00079
00095 char * strcpy_trunc(char * dst, std::size_t dstsize, char const * src);
00096
00112 char * strcpy_trunc(
00113 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00114 );
00115
00119 template <std::size_t N> inline
00120 char * strcpy_trunc(char (&dst)[N], char const * src)
00121 {
00122 return strcpy_trunc(dst, N, src);
00123 }
00124
00128 template <std::size_t N> inline
00129 char * strcpy_trunc(char (&dst)[N], char const * src, std::size_t srclen)
00130 {
00131 return strcpy_trunc(dst, N, src, srclen);
00132 }
00133
00138 template <std::size_t N> inline
00139 std::size_t strcpy_to_pos_trunc(
00140 char (&dst)[N], std::size_t pos, char const * src
00141 )
00142 {
00143 return strcpy_trunc(dst + pos, N - pos, src) - dst;
00144 }
00145
00150 template <std::size_t N> inline
00151 std::size_t strcpy_to_pos_trunc(
00152 char (&dst)[N], std::size_t pos, char const * src, std::size_t srclen
00153 )
00154 {
00155 return strcpy_trunc(dst + pos, N - pos, src, srclen) - dst;
00156 }
00157
00158 BLOCXX_DECLARE_EXCEPTION(Overflow);
00160 int const RESULT_TRUNCATED = 0;
00161 int const DEST_UNTERMINATED = 1;
00162
00180 char * strcpy_check(char * dst, std::size_t dstsize, char const * src);
00181
00199 char * strcpy_check(
00200 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00201 );
00202
00206 template <std::size_t N> inline
00207 char * strcpy_check(char (&dst)[N], char const * src)
00208 {
00209 return strcpy_check(dst, N, src);
00210 }
00211
00215 template <std::size_t N> inline
00216 char * strcpy_check(char (&dst)[N], char const * src, std::size_t srclen)
00217 {
00218 return strcpy_check(dst, N, src, srclen);
00219 }
00220
00225 template <std::size_t N> inline
00226 std::size_t strcpy_to_pos_check(
00227 char (&dst)[N], std::size_t pos, char const * src
00228 )
00229 {
00230 return strcpy_check(dst + pos, N - pos, src) - dst;
00231 }
00232
00237 template <std::size_t N> inline
00238 std::size_t strcpy_to_pos_check(
00239 char (&dst)[N], std::size_t pos, char const * src, std::size_t srclen
00240 )
00241 {
00242 return strcpy_check(dst + pos, N - pos, src, srclen) - dst;
00243 }
00244
00245
00263 char * strcat_trunc(char * dst, std::size_t dstsize, char const * src);
00264
00283 char * strcat_trunc(
00284 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00285 );
00286
00290 template <std::size_t N> inline
00291 char * strcat_trunc(char (&dst)[N], char const * src)
00292 {
00293 return strcat_trunc(dst, N, src);
00294 }
00295
00299 template <std::size_t N> inline
00300 char * strcat_trunc(char (&dst)[N], char const * src, std::size_t srclen)
00301 {
00302 return strcat_trunc(dst, N, src, srclen);
00303 }
00304
00326 char * strcat_check(char * dst, std::size_t dstsize, char const * src);
00327
00350 char * strcat_check(
00351 char * dst, std::size_t dstsize, char const * src, std::size_t srclen
00352 );
00353
00357 template <std::size_t N> inline
00358 char * strcat_check(char (&dst)[N], char const * src)
00359 {
00360 return strcat_check(dst, N, src);
00361 }
00362
00366 template <std::size_t N> inline
00367 char * strcat_check(char (&dst)[N], char const * src, std::size_t srclen)
00368 {
00369 return strcat_check(dst, N, src, srclen);
00370 }
00371
00372
00373 namespace Impl
00374 {
00375 inline std::size_t nchars_output(int retval, std::size_t dstsize)
00376 {
00377 return (
00378 retval < 0 || retval >= static_cast<int>(dstsize) ? dstsize - 1
00379 : static_cast<std::size_t>(retval)
00380 );
00381 }
00382
00383 std::size_t nchars_check(int retval, std::size_t dstsize);
00384 }
00385
00392 template <typename T1>
00393 std::size_t sprintf_trunc(
00394 char * dst, std::size_t dstsize, char const * fmt, T1 const & x1
00395 )
00396 {
00397 return Impl::nchars_output(snprintf(dst, dstsize, fmt, x1), dstsize);
00398 }
00399
00406 template <typename T1, typename T2>
00407 std::size_t sprintf_trunc(
00408 char * dst, std::size_t dstsize, char const * fmt,
00409 T1 const & x1, T2 const & x2
00410 )
00411 {
00412 return Impl::nchars_output(
00413 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00414 }
00415
00422 template <typename T1, typename T2, typename T3>
00423 std::size_t sprintf_trunc(
00424 char * dst, std::size_t dstsize, char const * fmt,
00425 T1 const & x1, T2 const & x2, T3 const & x3
00426 )
00427 {
00428 return Impl::nchars_output(
00429 snprintf(dst, dstsize, fmt, x1, x2, x3), dstsize);
00430 }
00431
00438 template <typename T1, typename T2, typename T3, typename T4>
00439 std::size_t sprintf_trunc(
00440 char * dst, std::size_t dstsize, char const * fmt,
00441 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00442 )
00443 {
00444 return Impl::nchars_output(
00445 snprintf(dst, dstsize, fmt, x1, x2, x3, x4), dstsize);
00446 }
00447
00454 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00455 std::size_t sprintf_trunc(
00456 char * dst, std::size_t dstsize, char const * fmt,
00457 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00458 )
00459 {
00460 return Impl::nchars_output(
00461 snprintf(dst, dstsize, fmt, x1, x2, x3, x4, x5), dstsize);
00462 }
00463
00467 template <std::size_t N, typename T1>
00468 std::size_t sprintf_trunc(char (&dst)[N], char const * fmt, T1 const & x1)
00469 {
00470 return Impl::nchars_output(snprintf(dst, N, fmt, x1), N);
00471 }
00472
00476 template <std::size_t N, typename T1, typename T2>
00477 std::size_t sprintf_trunc(
00478 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00479 )
00480 {
00481 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2), N);
00482 }
00483
00487 template <std::size_t N, typename T1, typename T2, typename T3>
00488 std::size_t sprintf_trunc(
00489 char (&dst)[N], char const * fmt,
00490 T1 const & x1, T2 const & x2, T3 const & x3
00491 )
00492 {
00493 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2, x3), N);
00494 }
00495
00499 template <std::size_t N, typename T1, typename T2, typename T3, typename T4>
00500 std::size_t sprintf_trunc(
00501 char (&dst)[N], char const * fmt,
00502 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00503 )
00504 {
00505 return Impl::nchars_output(snprintf(dst, N, fmt, x1, x2, x3, x4), N);
00506 }
00507
00511 template <std::size_t N, typename T1, typename T2, typename T3, typename T4,
00512 typename T5>
00513 std::size_t sprintf_trunc(
00514 char (&dst)[N], char const * fmt,
00515 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00516 )
00517 {
00518 return Impl::nchars_output(
00519 snprintf(dst, N, fmt, x1, x2, x3, x4, x5), N);
00520 }
00521
00522
00531 template <typename T1>
00532 std::size_t sprintf_check(
00533 char * dst, std::size_t dstsize, char const * fmt, T1 const & x1
00534 )
00535 {
00536 return Impl::nchars_check(snprintf(dst, dstsize, fmt, x1), dstsize);
00537 }
00538
00547 template <typename T1, typename T2>
00548 std::size_t sprintf_check(
00549 char * dst, std::size_t dstsize, char const * fmt,
00550 T1 const & x1, T2 const & x2
00551 )
00552 {
00553 return Impl::nchars_check(
00554 snprintf(dst, dstsize, fmt, x1, x2), dstsize);
00555 }
00556
00565 template <typename T1, typename T2, typename T3>
00566 std::size_t sprintf_check(
00567 char * dst, std::size_t dstsize, char const * fmt,
00568 T1 const & x1, T2 const & x2, T3 const & x3
00569 )
00570 {
00571 return Impl::nchars_check(
00572 snprintf(dst, dstsize, fmt, x1, x2, x3), dstsize);
00573 }
00574
00583 template <typename T1, typename T2, typename T3, typename T4>
00584 std::size_t sprintf_check(
00585 char * dst, std::size_t dstsize, char const * fmt,
00586 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00587 )
00588 {
00589 return Impl::nchars_check(
00590 snprintf(dst, dstsize, fmt, x1, x2, x3, x4), dstsize);
00591 }
00592
00601 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00602 std::size_t sprintf_check(
00603 char * dst, std::size_t dstsize, char const * fmt,
00604 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00605 )
00606 {
00607 return Impl::nchars_check(
00608 snprintf(dst, dstsize, fmt, x1, x2, x3, x4, x5), dstsize);
00609 }
00610
00614 template <std::size_t N, typename T1>
00615 std::size_t sprintf_check(char (&dst)[N], char const * fmt, T1 const & x1)
00616 {
00617 return Impl::nchars_check(snprintf(dst, N, fmt, x1), N);
00618 }
00619
00623 template <std::size_t N, typename T1, typename T2>
00624 std::size_t sprintf_check(
00625 char (&dst)[N], char const * fmt, T1 const & x1, T2 const & x2
00626 )
00627 {
00628 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2), N);
00629 }
00630
00634 template <std::size_t N, typename T1, typename T2, typename T3>
00635 std::size_t sprintf_check(
00636 char (&dst)[N], char const * fmt,
00637 T1 const & x1, T2 const & x2, T3 const & x3
00638 )
00639 {
00640 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3), N);
00641 }
00642
00646 template <std::size_t N, typename T1, typename T2, typename T3, typename T4>
00647 std::size_t sprintf_check(
00648 char (&dst)[N], char const * fmt,
00649 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4
00650 )
00651 {
00652 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3, x4), N);
00653 }
00654
00658 template <std::size_t N, typename T1, typename T2, typename T3, typename T4,
00659 typename T5>
00660 std::size_t sprintf_check(
00661 char (&dst)[N], char const * fmt,
00662 T1 const & x1, T2 const & x2, T3 const & x3, T4 const & x4, T5 const & x5
00663 )
00664 {
00665 return Impl::nchars_check(snprintf(dst, N, fmt, x1, x2, x3, x4, x5), N);
00666 }
00667
00668
00675 template <typename T1>
00676 std::size_t vprintf_trunc(
00677 char * dst, std::size_t dstsize, char const * fmt, va_list ap
00678 )
00679 {
00680 return Impl::nchars_output(vsnprintf(dst, dstsize, fmt, ap), dstsize);
00681 }
00682
00686 template <std::size_t N> inline
00687 std::size_t vprintf_trunc(char (&dst)[N], char const * fmt, va_list ap)
00688 {
00689 return vprintf_trunc(dst, N, fmt, ap);
00690 }
00691
00692
00701 inline std::size_t vprintf_check(
00702 char * dst, std::size_t dstsize, char const * fmt, va_list ap
00703 )
00704 {
00705 return Impl::nchars_check(vsnprintf(dst, dstsize, fmt, ap), dstsize);
00706 }
00707
00711 template <std::size_t N> inline
00712 std::size_t vprintf_check(char (&dst)[N], char const * fmt, va_list ap)
00713 {
00714 return vprintf_check(dst, N, fmt, ap);
00715 }
00716
00717 }
00718 }
00719
00720 #define BLOCXX_INTSTR_AUX(x) # x
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 #define BLOCXX_INTSTR(x) BLOCXX_INTSTR_AUX(x)
00731
00732 #endif