# str.hpp

Go to the documentation of this file.

    00001 /* $Id: str.hpp 19222 2010-02-23 23:18:41Z 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 CStrA &src) : base(src)
    00032   {
    00033     base::FixTail();
    00034   }
    00035
    00037   FORCEINLINE CStrA(const OnTransfer& ot)
    00038     : base(ot)
    00039   {
    00040   }
    00041
    00043   FORCEINLINE char *GrowSizeNC(bsize_t count)
    00044   {
    00045     char *ret = base::GrowSizeNC(count);
    00046     base::FixTail();
    00047     return ret;
    00048   }
    00049
    00051   FORCEINLINE void AppendStr(const char *str)
    00052   {
    00053     if (!StrEmpty(str)) {
    00054       base::Append(str, strlen(str));
    00055       base::FixTail();
    00056     }
    00057   }
    00058
    00060   FORCEINLINE void Append(const CStrA &src)
    00061   {
    00062     if (src.RawSize() > 0) {
    00063       base::AppendRaw(src);
    00064       base::FixTail();
    00065     }
    00066   }
    00067
    00069   FORCEINLINE CStrA &operator = (const char *src)
    00070   {
    00071     base::Clear();
    00072     AppendStr(src);
    00073     return *this;
    00074   }
    00075
    00077   FORCEINLINE CStrA &operator = (const CStrA &src)
    00078   {
    00079     if (&src != this) {
    00080       base::Clear();
    00081       base::AppendRaw(src);
    00082       base::FixTail();
    00083     }
    00084     return *this;
    00085   }
    00086
    00088   FORCEINLINE bool operator < (const CStrA &other) const
    00089   {
    00090     return strcmp(base::Data(), other.Data()) < 0;
    00091   }
    00092
    00094   int AddFormatL(const char *format, va_list args)
    00095   {
    00096     bsize_t addSize = max<size_t>(strlen(format), 16);
    00097     addSize += addSize / 2;
    00098     int ret;
    00099     int err = 0;
    00100     for (;;) {
    00101       char *buf = MakeFreeSpace(addSize);
    00102       ret = vsnprintf(buf, base::GetReserve(), format, args);
    00103       if (ret >= base::GetReserve()) {
    00104         /* Greater return than given count means needed buffer size. */
    00105         addSize = ret + 1;
    00106         continue;
    00107       }
    00108       if (ret >= 0) {
    00109         /* success */
    00110         break;
    00111       }
    00112       err = errno;
    00113       if (err != ERANGE && err != ENOENT && err != 0) {
    00114         /* some strange failure */
    00115         break;
    00116       }
    00117       /* small buffer (M$ implementation) */
    00118       addSize *= 2;
    00119     }
    00120     if (ret > 0) {
    00121       GrowSizeNC(ret);
    00122     } else {
    00123       base::FixTail();
    00124     }
    00125     return ret;
    00126   }
    00127
    00129   int CDECL WARN_FORMAT(2, 3) AddFormat(const char *format, ...)
    00130   {
    00131     va_list args;
    00132     va_start(args, format);
    00133     int ret = AddFormatL(format, args);
    00134     va_end(args);
    00135     return ret;
    00136   }
    00137
    00139   int CDECL WARN_FORMAT(2, 3) Format(const char *format, ...)
    00140   {
    00141     base::Free();
    00142     va_list args;
    00143     va_start(args, format);
    00144     int ret = AddFormatL(format, args);
    00145     va_end(args);
    00146     return ret;
    00147   }
    00148 };
    00149
    00150 #endif /* STR_HPP */