OW_SafeCString.hpp

Go to the documentation of this file.
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     * Use the OW_INTSTR macro to insert symbolic constants into format strings.
00791     * A typical usage would be for a maximum field width when using the
00792     * scanf family of functions.  For example, suppose that buf is an array of
00793     * STRMAX + 1 characters, and STRMAX is a manifest constant.  Then one
00794     * might write
00795     *
00796     *   sscanf(inpstr, "Name: %." OW_INTSTR(STRMAX) "s\n", buf);
00797    */
00798 #define OW_INTSTR(x) OW_INTSTR_AUX(x)
00799 
00800 } // namespace SafeCString
00801 } // namespace OW_NAMESPACE

Generated on Thu Feb 9 08:48:10 2006 for openwbem by  doxygen 1.4.6