# str.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    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 "../core/math_func.hpp"
    00019 #include "../string_func.h"
    00020
    00022 struct CStrA : public CBlobT<char>
    00023 {
    00024   typedef CBlobT<char> base;
    00025
    00027   FORCEINLINE CStrA()
    00028   {
    00029   }
    00030
    00032   FORCEINLINE CStrA(const CStrA &src) : base(src)
    00033   {
    00034     base::FixTail();
    00035   }
    00036
    00038   FORCEINLINE CStrA(const OnTransfer& ot)
    00039     : base(ot)
    00040   {
    00041   }
    00042
    00044   FORCEINLINE char *GrowSizeNC(uint count)
    00045   {
    00046     char *ret = base::GrowSizeNC(count);
    00047     base::FixTail();
    00048     return ret;
    00049   }
    00050
    00052   FORCEINLINE void AppendStr(const char *str)
    00053   {
    00054     if (!StrEmpty(str)) {
    00055       base::AppendRaw(str, strlen(str));
    00056       base::FixTail();
    00057     }
    00058   }
    00059
    00061   FORCEINLINE void Append(const CStrA &src)
    00062   {
    00063     if (src.Length() > 0) {
    00064       base::AppendRaw(src);
    00065       base::FixTail();
    00066     }
    00067   }
    00068
    00070   FORCEINLINE CStrA &operator = (const char *src)
    00071   {
    00072     base::Clear();
    00073     AppendStr(src);
    00074     return *this;
    00075   }
    00076
    00078   FORCEINLINE CStrA &operator = (const CStrA &src)
    00079   {
    00080     if (&src != this) {
    00081       base::Clear();
    00082       base::AppendRaw(src.Data(), src.Size());
    00083       base::FixTail();
    00084     }
    00085     return *this;
    00086   }
    00087
    00089   FORCEINLINE bool operator < (const CStrA &other) const
    00090   {
    00091     return strcmp(base::Data(), other.Data()) < 0;
    00092   }
    00093
    00095   int AddFormatL(const char *format, va_list args)
    00096   {
    00097     size_t addSize = max<size_t>(strlen(format), 16);
    00098     addSize += addSize / 2;
    00099     int ret;
    00100     int err = 0;
    00101     for (;;) {
    00102       char *buf = MakeFreeSpace(addSize);
    00103       ret = vsnprintf(buf, base::GetReserve(), format, args);
    00104       if (ret >= (int)base::GetReserve()) {
    00105         /* Greater return than given count means needed buffer size. */
    00106         addSize = ret + 1;
    00107         continue;
    00108       }
    00109       if (ret >= 0) {
    00110         /* success */
    00111         break;
    00112       }
    00113       err = errno;
    00114       if (err != ERANGE && err != ENOENT && err != 0) {
    00115         /* some strange failure */
    00116         break;
    00117       }
    00118       /* small buffer (M$ implementation) */
    00119       addSize *= 2;
    00120     }
    00121     if (ret > 0) {
    00122       GrowSizeNC(ret);
    00123     } else {
    00124       base::FixTail();
    00125     }
    00126     return ret;
    00127   }
    00128
    00130   int CDECL WARN_FORMAT(2, 3) AddFormat(const char *format, ...)
    00131   {
    00132     va_list args;
    00133     va_start(args, format);
    00134     int ret = AddFormatL(format, args);
    00135     va_end(args);
    00136     return ret;
    00137   }
    00138
    00140   int CDECL WARN_FORMAT(2, 3) Format(const char *format, ...)
    00141   {
    00142     base::Free();
    00143     va_list args;
    00144     va_start(args, format);
    00145     int ret = AddFormatL(format, args);
    00146     va_end(args);
    00147     return ret;
    00148   }
    00149 };
    00150
    00151 #endif /* STR_HPP */