ncbistr.cpp
来自「ncbi源码」· C++ 代码 · 共 1,876 行 · 第 1/4 页
CPP
1,876 行
break; } Int8 n = 0; Int8 limdiv = kMax_I8 / 10; Int8 limoff = kMax_I8 % 10; do { if (!isdigit(*pc)) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to Int8 - bad digit", s_DiffPtr(pc, str.c_str())); } int delta = *pc - '0'; n *= 10; // Overflow checking if (n > limdiv || (n == limdiv && delta > limoff)) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted Int8 - overflow", s_DiffPtr(pc, str.c_str())); } n += delta; } while (*++pc); return sign ? -n : n;}Uint8 NStr::StringToUInt8(const string& str, int base /* = 10 */){ const char* pc = str.c_str(); if (*pc == '+') ++pc; Uint8 n = 0; Uint8 limdiv = kMax_UI8 / base; int limoff = int(kMax_UI8 % base); do { // Do a sanity check for common radixes int ch = *pc; if (base == 10 && !isdigit(ch) || base == 16 && !isxdigit(ch) || base == 8 && (ch < '0' || ch > '7') || base == 2 && (ch < '0' || ch > '1')) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to UInt8 - bad digit", s_DiffPtr(pc, str.c_str())); } int delta; // corresponding numeric value of *pc if (isdigit(ch)) { delta = ch - '0'; } else { ch = tolower(ch); // Got to be 'a' to 'f' because of previous sanity checks delta = ch - 'a' + 10; } n *= base; // Overflow checking if (n > limdiv || (n == limdiv && delta > limoff)) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to UInt8 - overflow", s_DiffPtr(pc, str.c_str())); } n += delta; } while (*++pc); return n;}void NStr::UInt8ToString(string& out_str, Uint8 value){ const size_t kBufSize = (sizeof(value) * CHAR_BIT) / 3 + 2; char buffer[kBufSize]; char* pos = buffer + kBufSize; if ( value == 0 ) { *--pos = '0'; } else { do { *--pos = char('0' + (value % 10)); value /= 10; } while ( value ); } out_str.resize(0); out_str.append(pos, buffer + kBufSize - pos);}string NStr::UInt8ToString(Uint8 value){ string ret; NStr::UInt8ToString(ret, value); return ret;}// A maximal double precision used in the double to string conversion#if defined(NCBI_OS_MSWIN)const unsigned int kMaxDoublePrecision = 200;#elseconst unsigned int kMaxDoublePrecision = 308;#endif// A maximal size of a double value in a string form.// Exponent size + sign + dot + ending '\0' + max.precisionconst unsigned int kMaxDoubleStringSize = 308 + 3 + kMaxDoublePrecision;string NStr::DoubleToString(double value){ char buffer[kMaxDoubleStringSize]; ::sprintf(buffer, "%g", value); return buffer;}void NStr::DoubleToString(string& out_str, double value){ char buffer[kMaxDoubleStringSize]; ::sprintf(buffer, "%g", value); out_str = buffer;}string NStr::DoubleToString(double value, unsigned int precision){ char buffer[kMaxDoubleStringSize]; SIZE_TYPE n = DoubleToString(value, precision, buffer, kMaxDoubleStringSize); buffer[n] = '\0'; return buffer;}SIZE_TYPE NStr::DoubleToString(double value, unsigned int precision, char* buf, SIZE_TYPE buf_size){ char buffer[kMaxDoubleStringSize]; if (precision > kMaxDoublePrecision) { precision = kMaxDoublePrecision; } int n = ::sprintf(buffer, "%.*f", (int) precision, value); SIZE_TYPE n_copy = min((SIZE_TYPE) n, buf_size); memcpy(buf, buffer, n_copy); return n_copy;}string NStr::PtrToString(const void* value){ char buffer[64]; ::sprintf(buffer, "%p", value); return buffer;}void NStr::PtrToString(string& out_str, const void* value){ char buffer[64]; ::sprintf(buffer, "%p", value); out_str = buffer;}const void* NStr::StringToPtr(const string& str){ void *ptr = NULL; ::sscanf(str.c_str(), "%p", &ptr); return ptr;}static const string s_kTrueString = "true";static const string s_kFalseString = "false";static const string s_kTString = "t";static const string s_kFString = "f";static const string s_kYesString = "yes";static const string s_kNoString = "no";static const string s_kYString = "y";static const string s_kNString = "n";const string& NStr::BoolToString(bool value){ return value ? s_kTrueString : s_kFalseString;}bool NStr::StringToBool(const string& str){ if ( AStrEquiv(str, s_kTrueString, PNocase()) || AStrEquiv(str, s_kTString, PNocase()) || AStrEquiv(str, s_kYesString, PNocase()) || AStrEquiv(str, s_kYString, PNocase()) ) return true; if ( AStrEquiv(str, s_kFalseString, PNocase()) || AStrEquiv(str, s_kFString, PNocase()) || AStrEquiv(str, s_kNoString, PNocase()) || AStrEquiv(str, s_kNString, PNocase()) ) return false; NCBI_THROW2(CStringException, eConvert, "String cannot be converted to bool", 0);}string NStr::FormatVarargs(const char* format, va_list args){#ifdef HAVE_VASPRINTF char* s; int n = vasprintf(&s, format, args); if (n >= 0) { string str(s, n); free(s); return str; } else { return kEmptyStr; }#elif defined(NCBI_COMPILER_GCC) && defined(NO_PUBSYNC) CNcbiOstrstream oss; oss.vform(format, args); return CNcbiOstrstreamToString(oss);#elif defined(HAVE_VSNPRINTF) // deal with implementation quirks size_t size = 1024; AutoPtr<char, ArrayDeleter<char> > buf(new char[size]); buf.get()[size-1] = buf.get()[size-2] = 0; size_t n = vsnprintf(buf.get(), size, format, args); while (n >= size || buf.get()[size-2]) { if (buf.get()[size-1]) { ERR_POST(Warning << "Buffer overrun by buggy vsnprintf"); } size = max(size << 1, n); buf.reset(new char[size]); buf.get()[size-1] = buf.get()[size-2] = 0; n = vsnprintf(buf.get(), size, format, args); } return (n > 0) ? string(buf.get(), n) : kEmptyStr;#elif defined(HAVE_VPRINTF) char buf[1024]; buf[sizeof(buf) - 1] = 0; vsprintf(buf, format, args); if (buf[sizeof(buf) - 1]) { ERR_POST(Warning << "Buffer overrun by vsprintf"); } return buf;#else# error Please port this code to your system.#endif}SIZE_TYPE NStr::FindNoCase(const string& str, const string& pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence where){ string pat(pattern, 0, 1); SIZE_TYPE l = pattern.size(); if (isupper(pat[0])) { pat += (char)tolower(pat[0]); } else if (islower(pat[0])) { pat += (char)toupper(pat[0]); } if (where == eFirst) { SIZE_TYPE pos = str.find_first_of(pat, start); while (pos != NPOS && pos <= end && CompareNocase(str, pos, l, pattern) != 0) { pos = str.find_first_of(pat, pos + 1); } return pos > end ? NPOS : pos; } else { // eLast SIZE_TYPE pos = str.find_last_of(pat, end); while (pos != NPOS && pos >= start && CompareNocase(str, pos, l, pattern) != 0) { if (pos == 0) { return NPOS; } pos = str.find_last_of(pat, pos - 1); } return pos < start ? NPOS : pos; }}string NStr::TruncateSpaces(const string& str, ETrunc where){ SIZE_TYPE beg = 0; if (where == eTrunc_Begin || where == eTrunc_Both) { while (beg < str.length() && isspace(str[beg])) beg++; if (beg == str.length()) return kEmptyStr; } SIZE_TYPE end = str.length() - 1; if (where == eTrunc_End || where == eTrunc_Both) { while ( isspace(str[end]) ) end--; } _ASSERT( beg <= end ); return str.substr(beg, end - beg + 1);}string& NStr::Replace(const string& src, const string& search, const string& replace, string& dst, SIZE_TYPE start_pos, size_t max_replace){ // source and destination should not be the same if (&src == &dst) { NCBI_THROW2(CStringException, eBadArgs, "String replace called with source == destination", 0); } dst = src; if( start_pos + search.size() > src.size() || search == replace) return dst; for(size_t count = 0; !(max_replace && count >= max_replace); count++) { start_pos = dst.find(search, start_pos); if(start_pos == NPOS) break; dst.replace(start_pos, search.size(), replace); start_pos += replace.size(); } return dst;}string NStr::Replace(const string& src, const string& search, const string& replace, SIZE_TYPE start_pos, size_t max_replace){ string dst; return Replace(src, search, replace, dst, start_pos, max_replace);}list<string>& NStr::Split(const string& str, const string& delim, list<string>& arr, EMergeDelims merge){ for (size_t pos = 0; ; ) { size_t prev_pos = (merge == eMergeDelims ? str.find_first_not_of(delim, pos) : pos); if (prev_pos == NPOS) { break; } pos = str.find_first_of(delim, prev_pos); if (pos == NPOS) { arr.push_back(str.substr(prev_pos)); break; } else { arr.push_back(str.substr(prev_pos, pos - prev_pos)); ++pos; } } return arr;}vector<string>& NStr::Tokenize(const string& str, const string& delim, vector<string>& arr, EMergeDelims merge){ if (delim.empty()) { arr.push_back(str); return arr; } size_t pos, prev_pos; // Count number of tokens to determine the array size size_t tokens = 0; for (pos = prev_pos = 0; pos < str.length(); ++pos) { char c = str[pos]; size_t dpos = delim.find(c); if (dpos != string::npos) ++tokens; } arr.reserve(arr.size() + tokens + 1); // Tokenization for (pos = 0; ; ) { prev_pos = (merge == eMergeDelims ? str.find_first_not_of(delim, pos) : pos); if (prev_pos == NPOS) { break; } pos = str.find_first_of(delim, prev_pos); if (pos == NPOS) { arr.push_back(str.substr(prev_pos)); break; } else { arr.push_back(str.substr(prev_pos, pos - prev_pos)); ++pos; } } return arr;}bool NStr::SplitInTwo(const string& str, const string& delim, string& str1, string& str2){ SIZE_TYPE delim_pos = str.find_first_of(delim); if (NPOS == delim_pos) { // only one piece. str1 = str; str2 = kEmptyStr; return false; } str1 = str.substr(0, delim_pos); str2 = str.substr(delim_pos + 1); // skip only one delimiter character. return true;}template <typename T>string s_NStr_Join(const T& arr, const string& delim){ if (arr.empty()) { return kEmptyStr; } string result = arr.front(); typename T::const_iterator it = arr.begin(); SIZE_TYPE needed = result.size(); while (++it != arr.end()) { needed += delim.size() + it->size(); } result.reserve(needed); it = arr.begin(); while (++it != arr.end()) { result += delim; result += *it; } return result;}string NStr::Join(const list<string>& arr, const string& delim){ return s_NStr_Join(arr, delim);}string NStr::Join(const vector<string>& arr, const string& delim){ return s_NStr_Join(arr, delim);}string NStr::PrintableString(const string& str, NStr::ENewLineMode nl_mode){ static const char s_Hex[] = "0123456789ABCDEF"; ITERATE ( string, it, str ) { if ( !isprint(*it) || *it == '"' || *it == '\\' ) { // bad character - convert via CNcbiOstrstream CNcbiOstrstream out; // write first good characters in one chunk out.write(str.data(), it-str.begin()); // convert all other characters one by one
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?