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