OpenTTD: src/misc/str.hpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

str.hpp
Go to the documentation of this file.
1 /* $Id: str.hpp 26506 2014-04-24 19:51:45Z rubidium $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #ifndef STR_HPP
13 #define STR_HPP
14
15 #include <errno.h>
16 #include <stdarg.h>
17 #include "blob.hpp"
18 #include "../core/math_func.hpp"
19 #include "../string_func.h"
20
22 struct CStrA : public CBlobT<char>
23 {
24 typedef CBlobT<char> base;
25
27 inline CStrA()
28 {
29 }
30
32 inline CStrA(const CStrA &src) : base(src)
33 {
34 base::FixTail();
35 }
36
38 inline CStrA(const OnTransfer& ot)
39 : base(ot)
40 {
41 }
42
44 inline char *GrowSizeNC(uint count)
45 {
46 char *ret = base::GrowSizeNC(count);
47 base::FixTail();
48 return ret;
49 }
50
52 inline void AppendStr(const char *str)
53 {
54 if (!StrEmpty(str)) {
55 base::AppendRaw(str, strlen(str));
56 base::FixTail();
57 }
58 }
59
61 inline void Append(const CStrA &src)
62 {
63 if (src.Length() > 0) {
64 base::AppendRaw(src);
65 base::FixTail();
66 }
67 }
68
70 inline CStrA &operator = (const char *src)
71 {
72 base::Clear();
73 AppendStr(src);
74 return *this;
75 }
76
78 inline CStrA &operator = (const CStrA &src)
79 {
80 if (&src != this) {
81 base::Clear();
82 base::AppendRaw(src.Data(), src.Size());
83 base::FixTail();
84 }
85 return *this;
86 }
87
89 inline bool operator < (const CStrA &other) const
90 {
91 return strcmp(base::Data(), other.Data()) < 0;
92 }
93
95 int AddFormatL(const char *format, va_list args)
96 {
97 size_t addSize = max<size_t>(strlen(format), 16);
98 addSize += addSize / 2;
99 int ret;
100 int err = 0;
101 for (;;) {
102 char *buf = MakeFreeSpace(addSize);
103 ret = vseprintf(buf, buf + base::GetReserve() - 1, format, args);
104 if (ret >= (int)base::GetReserve()) {
105 /* Greater return than given count means needed buffer size. */
106 addSize = ret + 1;
107 continue;
108 }
109 if (ret >= 0) {
110 /* success */
111 break;
112 }
113 err = errno;
114 if (err != ERANGE && err != ENOENT && err != 0) {
115 /* some strange failure */
116 break;
117 }
118 /* small buffer (M$ implementation) */
119 addSize *= 2;
120 }
121 if (ret > 0) {
122 GrowSizeNC(ret);
123 } else {
124 base::FixTail();
125 }
126 return ret;
127 }
128
130 int CDECL WARN_FORMAT(2, 3) AddFormat(const char *format, ...)
131 {
132 va_list args;
133 va_start(args, format);
134 int ret = AddFormatL(format, args);
135 va_end(args);
136 return ret;
137 }
138
140 int CDECL WARN_FORMAT(2, 3) Format(const char *format, ...)
141 {
142 base::Free();
143 va_list args;
144 va_start(args, format);
145 int ret = AddFormatL(format, args);
146 va_end(args);
147 return ret;
148 }
149 };
150
151 #endif /* STR_HPP */