00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_util.hpp"
00012
00013 #include <stdarg.h>
00014 #include <string.h>
00015
00016 #include "xrb_emptystring.hpp"
00017
00018 namespace Xrb
00019 {
00020
00021 void Util::ReplaceAllInString (
00022 std::string *string,
00023 std::string const &string_to_replace,
00024 std::string const &string_to_replace_with)
00025 {
00026 ASSERT1(string != NULL);
00027 ASSERT1(string_to_replace.length() > 0);
00028 Uint32 offset = 0;
00029 while (1)
00030 {
00031 Uint32 pos = static_cast<Uint32>(string->find(string_to_replace, offset));
00032 if (pos >= string->length())
00033 break;
00034 string->replace(pos, string_to_replace.length(), string_to_replace_with);
00035 offset = pos + string_to_replace_with.length();
00036 }
00037 }
00038
00039 std::string Util::StringPrintf (char const *format, ...)
00040 {
00041 ASSERT1(format != NULL);
00042
00043
00044 char buffer[0x1000];
00045 va_list list;
00046
00047 va_start(list, format);
00048 vsnprintf(buffer, 0x1000, format, list);
00049 va_end(list);
00050
00051 return std::string(buffer);
00052 }
00053
00054 void StringPrintf (std::string *const string, char const *const format, ...)
00055 {
00056 ASSERT1(string != NULL);
00057 ASSERT1(format != NULL);
00058
00059
00060 char buffer[0x1000];
00061 va_list list;
00062
00063 va_start(list, format);
00064 vsnprintf(buffer, 0x1000, format, list);
00065 va_end(list);
00066
00067 *string = buffer;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 char *Util::StringDuplicate (char const *string_to_duplicate)
00080 {
00081 ASSERT1(string_to_duplicate != NULL);
00082
00083 Uint32 length = strlen(string_to_duplicate);
00084 char *duplicated_string = new char[length + 1];
00085 memcpy(duplicated_string, string_to_duplicate, length + 1);
00086 ASSERT1(duplicated_string[length] == '\0');
00087
00088 return duplicated_string;
00089 }
00090
00091 char Util::Lowercase (char c)
00092 {
00093 if (c >= 'A' && c <= 'Z')
00094 return c += 'a' - 'A';
00095 else
00096 return c;
00097 }
00098
00099 char Util::Uppercase (char c)
00100 {
00101 if (c >= 'a' && c <= 'z')
00102 return c += 'A' - 'a';
00103 else
00104 return c;
00105 }
00106
00107 void Util::MakeLowercase (std::string *const str)
00108 {
00109 ASSERT1(str != NULL);
00110 for (Uint32 i = 0; i < str->length(); ++i)
00111 if ((*str)[i] >= 'A' && (*str)[i] <= 'Z')
00112 (*str)[i] += 'a' - 'A';
00113 }
00114
00115 void Util::MakeUppercase (std::string *const str)
00116 {
00117 ASSERT1(str != NULL);
00118 for (Uint32 i = 0; i < str->length(); ++i)
00119 if ((*str)[i] >= 'a' && (*str)[i] <= 'z')
00120 (*str)[i] += 'A' - 'a';
00121 }
00122
00123 char Util::ShiftedAscii (char const c)
00124 {
00125 static char const ascii_to_shifted_ascii[128] =
00126 {
00127 '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
00128 '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
00129 '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
00130 '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
00131 ' ', '!', '\'', '#', '$', '%', '&', '"',
00132 '(', ')', '*', '+', '<', '_', '>', '?',
00133 ')', '!', '@', '#', '$', '%', '^', '&',
00134 '*', '(', ':', ':', '<', '+', '>', '?',
00135 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
00136 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
00137 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
00138 'x', 'y', 'z', '{', '|', '}', '^', '_',
00139 '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
00140 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
00141 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
00142 'X', 'Y', 'Z', '{', '|', '}', '~', '\0',
00143 };
00144
00145 return (c >= 0) ? ascii_to_shifted_ascii[(Uint32)c] : '\0';
00146 }
00147
00148 bool Util::CharacterLiteralCharNeedsEscaping (char const c)
00149 {
00150
00151
00152
00153 return (c >= '\a' && c <= '\r') || c == '\0' || c == '\n' || c == '\\' || c == '\'';
00154 }
00155
00156 bool Util::StringLiteralCharNeedsEscaping (char const c)
00157 {
00158
00159
00160
00161 return (c >= '\a' && c <= '\r') || c == '\0' || c == '\n' || c == '\\' || c == '\"';
00162 }
00163
00164 char Util::EscapeCode (char const c)
00165 {
00166
00167
00168 switch (c)
00169 {
00170 case '\0': return '0';
00171 case '\a': return 'a';
00172 case '\b': return 'b';
00173 case '\t': return 't';
00174 case '\n': return 'n';
00175 case '\v': return 'v';
00176 case '\f': return 'f';
00177 case '\r': return 'r';
00178 default : return c;
00179 }
00180 }
00181
00182 char Util::EscapedChar (char const c)
00183 {
00184
00185
00186 switch (c)
00187 {
00188 case '0': return '\0';
00189 case 'a': return '\a';
00190 case 'b': return '\b';
00191 case 't': return '\t';
00192 case 'n': return '\n';
00193 case 'v': return '\v';
00194 case 'f': return '\f';
00195 case 'r': return '\r';
00196 default : return c;
00197 }
00198 }
00199
00200 std::string Util::CharacterLiteral (char const c)
00201 {
00202 std::string retval("'");
00203 if (CharacterLiteralCharNeedsEscaping(c))
00204 retval += '\\', retval += EscapeCode(c);
00205 else
00206 retval += c;
00207 retval += '\'';
00208 return retval;
00209 }
00210
00211 std::string Util::StringLiteral (std::string const &text)
00212 {
00213 std::string retval("\"");
00214 for (std::string::const_iterator it = text.begin(),
00215 it_end = text.end();
00216 it != it_end;
00217 ++it)
00218 {
00219 if (StringLiteralCharNeedsEscaping(*it))
00220 retval += '\\', retval += EscapeCode(*it);
00221 else
00222 retval += *it;
00223 }
00224 retval += '"';
00225 return retval;
00226 }
00227
00228 char const *Util::IOErrorString (IOError error)
00229 {
00230 static char const *error_string[IOE_COUNT] =
00231 {
00232 STRINGIFY(IOE_NONE),
00233 STRINGIFY(IOE_IS_AT_END),
00234 STRINGIFY(IOE_INSUFFICIENT_STORAGE),
00235 STRINGIFY(IOE_INSUFFICIENT_AVAILABLE_DATA),
00236 STRINGIFY(IOE_OVERSIZED_STRING),
00237 STRINGIFY(IOE_INVALID_FILENAME),
00238 STRINGIFY(IOE_UNABLE_TO_OPEN_FILE),
00239 STRINGIFY(IOE_INVALID_FILE_OPEN_MODE)
00240 };
00241
00242 ASSERT1(error >= IOE_LOWEST_ERROR && error <= IOE_HIGHEST_ERROR);
00243
00244 return error_string[error];
00245 }
00246
00247 std::string Util::DirectoryPortion (std::string const &path)
00248 {
00249 std::string::size_type last_slash = path.find_last_of("/");
00250 if (last_slash == std::string::npos)
00251 return g_empty_string;
00252 else
00253 return path.substr(0, last_slash+1);
00254 }
00255
00256 std::string Util::FilenamePortion (std::string const &path)
00257 {
00258 std::string::size_type last_slash = path.find_last_of("/");
00259 if (last_slash == std::string::npos)
00260 return path;
00261 else
00262 return path.substr(last_slash+1);
00263 }
00264
00265 }