00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CStringUtil.h"
00020 #include "CArch.h"
00021 #include "common.h"
00022 #include "stdvector.h"
00023 #include <cctype>
00024 #include <cstdio>
00025 #include <cstdlib>
00026 #include <cstring>
00027 #include <algorithm>
00028
00029
00030
00031
00032
00033 CString
00034 CStringUtil::format(const char* fmt, ...)
00035 {
00036 va_list args;
00037 va_start(args, fmt);
00038 CString result = vformat(fmt, args);
00039 va_end(args);
00040 return result;
00041 }
00042
00043 CString
00044 CStringUtil::vformat(const char* fmt, va_list args)
00045 {
00046
00047 std::vector<size_t> pos;
00048 std::vector<size_t> width;
00049 std::vector<int> index;
00050 int maxIndex = 0;
00051 for (const char* scan = fmt; *scan != '\0'; ++scan) {
00052 if (*scan == '%') {
00053 ++scan;
00054 if (*scan == '\0') {
00055 break;
00056 }
00057 else if (*scan == '%') {
00058
00059 index.push_back(0);
00060 pos.push_back(static_cast<int>(scan - 1 - fmt));
00061 width.push_back(2);
00062 }
00063 else if (*scan == '{') {
00064
00065 char* end;
00066 int i = static_cast<int>(strtol(scan + 1, &end, 10));
00067 if (*end != '}') {
00068
00069 scan = end - 1;
00070 }
00071 else {
00072 index.push_back(i);
00073 pos.push_back(static_cast<int>(scan - 1 - fmt));
00074 width.push_back(static_cast<int>(end - scan + 2));
00075 if (i > maxIndex) {
00076 maxIndex = i;
00077 }
00078 scan = end;
00079 }
00080 }
00081 else {
00082
00083 }
00084 }
00085 }
00086
00087
00088 std::vector<const char*> value;
00089 std::vector<size_t> length;
00090 value.push_back("%");
00091 length.push_back(1);
00092 for (int i = 0; i < maxIndex; ++i) {
00093 const char* arg = va_arg(args, const char*);
00094 size_t len = strlen(arg);
00095 value.push_back(arg);
00096 length.push_back(len);
00097 }
00098
00099
00100 size_t resultLength = strlen(fmt);
00101 const int n = static_cast<int>(pos.size());
00102 for (int i = 0; i < n; ++i) {
00103 resultLength -= width[i];
00104 resultLength += length[index[i]];
00105 }
00106
00107
00108 CString result;
00109 result.reserve(resultLength);
00110 size_t src = 0;
00111 for (int i = 0; i < n; ++i) {
00112 result.append(fmt + src, pos[i] - src);
00113 result.append(value[index[i]]);
00114 src = pos[i] + width[i];
00115 }
00116 result.append(fmt + src);
00117
00118 return result;
00119 }
00120
00121 CString
00122 CStringUtil::print(const char* fmt, ...)
00123 {
00124 char tmp[1024];
00125 char* buffer = tmp;
00126 int len = (int)(sizeof(tmp) / sizeof(tmp[0]));
00127 CString result;
00128 while (buffer != NULL) {
00129
00130 va_list args;
00131 va_start(args, fmt);
00132 int n = ARCH->vsnprintf(buffer, len, fmt, args);
00133 va_end(args);
00134
00135
00136 if (n < 0 || n > len) {
00137 if (buffer != tmp) {
00138 delete[] buffer;
00139 }
00140 len *= 2;
00141 buffer = new char[len];
00142 }
00143
00144
00145 else {
00146 result = buffer;
00147 if (buffer != tmp) {
00148 delete[] buffer;
00149 }
00150 buffer = NULL;
00151 }
00152 }
00153
00154 return result;
00155 }
00156
00157
00158
00159
00160
00161
00162 bool
00163 CStringUtil::CaselessCmp::cmpEqual(
00164 const CString::value_type& a,
00165 const CString::value_type& b)
00166 {
00167
00168 return tolower(a) == tolower(b);
00169 }
00170
00171 bool
00172 CStringUtil::CaselessCmp::cmpLess(
00173 const CString::value_type& a,
00174 const CString::value_type& b)
00175 {
00176
00177 return tolower(a) < tolower(b);
00178 }
00179
00180 bool
00181 CStringUtil::CaselessCmp::less(const CString& a, const CString& b)
00182 {
00183 return std::lexicographical_compare(
00184 a.begin(), a.end(),
00185 b.begin(), b.end(),
00186 &CStringUtil::CaselessCmp::cmpLess);
00187 }
00188
00189 bool
00190 CStringUtil::CaselessCmp::equal(const CString& a, const CString& b)
00191 {
00192 return !(less(a, b) || less(b, a));
00193 }
00194
00195 bool
00196 CStringUtil::CaselessCmp::operator()(const CString& a, const CString& b) const
00197 {
00198 return less(a, b);
00199 }