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 + -
显示快捷键?