# str.hpp

Go to the documentation of this file.

    00001 /* $Id: str.hpp 18809 2010-01-15 16:41:15Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef  STR_HPP
    00013 #define  STR_HPP
    00014
    00015 #include <errno.h>
    00016 #include <stdarg.h>
    00017 #include "blob.hpp"
    00018 #include "../string_func.h"
    00019
    00021 struct CStrA : public CBlobT<char>
    00022 {
    00023   typedef CBlobT<char> base;
    00024
    00026   FORCEINLINE CStrA()
    00027   {
    00028   }
    00029
    00031   FORCEINLINE CStrA(const OnTransfer& ot)
    00032     : base(ot)
    00033   {
    00034   }
    00035
    00037   FORCEINLINE char *GrowSizeNC(bsize_t count)
    00038   {
    00039     char *ret = base::GrowSizeNC(count);
    00040     base::FixTail();
    00041     return ret;
    00042   }
    00043
    00045   FORCEINLINE void AppendStr(const char *str)
    00046   {
    00047     if (!StrEmpty(str)) {
    00048       base::Append(str, strlen(str));
    00049       base::FixTail();
    00050     }
    00051   }
    00052
    00054   FORCEINLINE CStrA& operator = (const char *src)
    00055   {
    00056     base::Clear();
    00057     AppendStr(src);
    00058     return *this;
    00059   }
    00060
    00062   FORCEINLINE bool operator < (const CStrA &other) const
    00063   {
    00064     return strcmp(base::Data(), other.Data()) < 0;
    00065   }
    00066
    00068   int AddFormatL(const char *format, va_list args)
    00069   {
    00070     bsize_t addSize = max<size_t>(strlen(format), 16);
    00071     addSize += addSize / 2;
    00072     int ret;
    00073     int err = 0;
    00074     for (;;) {
    00075       char *buf = MakeFreeSpace(addSize);
    00076       ret = vsnprintf(buf, base::GetReserve(), format, args);
    00077       if (ret >= base::GetReserve()) {
    00078         /* Greater return than given count means needed buffer size. */
    00079         addSize = ret + 1;
    00080         continue;
    00081       }
    00082       if (ret >= 0) {
    00083         /* success */
    00084         break;
    00085       }
    00086       err = errno;
    00087       if (err != ERANGE && err != ENOENT && err != 0) {
    00088         /* some strange failure */
    00089         break;
    00090       }
    00091       /* small buffer (M$ implementation) */
    00092       addSize *= 2;
    00093     }
    00094     if (ret > 0) {
    00095       GrowSizeNC(ret);
    00096     } else {
    00097       base::FixTail();
    00098     }
    00099     return ret;
    00100   }
    00101
    00103   int AddFormat(const char *format, ...)
    00104   {
    00105     va_list args;
    00106     va_start(args, format);
    00107     int ret = AddFormatL(format, args);
    00108     va_end(args);
    00109     return ret;
    00110   }
    00111
    00113   int Format(const char *format, ...)
    00114   {
    00115     base::Free();
    00116     va_list args;
    00117     va_start(args, format);
    00118     int ret = AddFormatL(format, args);
    00119     va_end(args);
    00120     return ret;
    00121   }
    00122 };
    00123
    00124 #endif /* STR_HPP */