📄 ncbistr.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbistr.cpp,v $ * PRODUCTION Revision 1000.6 2004/06/01 19:09:21 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.109 * PRODUCTION * =========================================================================== *//* $Id: ncbistr.cpp,v 1000.6 2004/06/01 19:09:21 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Eugene Vasilchenko, Denis Vakatov * * File Description: * Some helper functions * */#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbi_limits.h>#include <memory>#include <algorithm>#include <ctype.h>#include <errno.h>#include <stdio.h>BEGIN_NCBI_SCOPEinlinestd::string::size_type s_DiffPtr(const char* end, const char* start){ if (end) { return end - start; } return 0;}const char *const kEmptyCStr = "";#ifndef NCBI_OS_MSWINconst string* CNcbiEmptyString::m_Str = 0;const string& CNcbiEmptyString::FirstGet(void) { static const string s_Str = ""; m_Str = &s_Str; return s_Str;}#endif // NCBI_OS_MSWINint NStr::CompareCase(const string& str, SIZE_TYPE pos, SIZE_TYPE n, const char* pattern){ if (pos == NPOS || !n || str.length() <= pos) { return *pattern ? -1 : 0; } if ( !*pattern ) { return 1; } if (n == NPOS || n > str.length() - pos) { n = str.length() - pos; } const char* s = str.data() + pos; while (n && *pattern && *s == *pattern) { s++; pattern++; n--; } if (n == 0) { return *pattern ? -1 : 0; } return *s - *pattern;}int NStr::CompareNocase(const string& str, SIZE_TYPE pos, SIZE_TYPE n, const char* pattern){ if (pos == NPOS || !n || str.length() <= pos) { return *pattern ? -1 : 0; } if ( !*pattern ) { return 1; } if (n == NPOS || n > str.length() - pos) { n = str.length() - pos; } const char* s = str.data() + pos; while (n && *pattern && toupper(*s) == toupper(*pattern)) { s++; pattern++; n--; } if (n == 0) { return *pattern ? -1 : 0; } return toupper(*s) - toupper(*pattern);}int NStr::CompareCase(const string& str, SIZE_TYPE pos, SIZE_TYPE n, const string& pattern){ if (pos == NPOS || !n || str.length() <= pos) { return pattern.empty() ? 0 : -1; } if ( pattern.empty() ) { return 1; } if (n == NPOS || n > str.length() - pos) { n = str.length() - pos; } SIZE_TYPE n_cmp = n; if (n_cmp > pattern.length()) { n_cmp = pattern.length(); } const char* s = str.data() + pos; const char* p = pattern.data(); while (n_cmp && *s == *p) { s++; p++; n_cmp--; } if (n_cmp == 0) { if (n == pattern.length()) return 0; return n > pattern.length() ? 1 : -1; } return *s - *p;}int NStr::CompareNocase(const string& str, SIZE_TYPE pos, SIZE_TYPE n, const string& pattern){ if (pos == NPOS || !n || str.length() <= pos) { return pattern.empty() ? 0 : -1; } if ( pattern.empty() ) { return 1; } if (n == NPOS || n > str.length() - pos) { n = str.length() - pos; } SIZE_TYPE n_cmp = n; if (n_cmp > pattern.length()) { n_cmp = pattern.length(); } const char* s = str.data() + pos; const char* p = pattern.data(); while (n_cmp && toupper(*s) == toupper(*p)) { s++; p++; n_cmp--; } if (n_cmp == 0) { if (n == pattern.length()) return 0; return n > pattern.length() ? 1 : -1; } return toupper(*s) - toupper(*p);}// NOTE: This code is used also in the CDirEntry::MatchesMask.bool NStr::MatchesMask(const char* str, const char* mask) { char c; bool infinite = true; while (infinite) { // Analyze symbol in mask switch ( c = *mask++ ) { case '\0': return *str == '\0'; case '?': if ( *str == '\0' ) { return false; } ++str; break; case '*': c = *mask; // Collapse multiple stars while ( c == '*' ) { c = *++mask; } if (c == '\0') { return true; } // General case, use recursion while ( *str ) { if ( MatchesMask(str, mask) ) { return true; } ++str; } return false; default: // Compare nonpattern character in mask and name if ( c != *str++ ) { return false; } break; } } return false;}char* NStr::ToLower(char* str){ char* s; for (s = str; *str; str++) { *str = tolower(*str); } return s;}string& NStr::ToLower(string& str){ NON_CONST_ITERATE (string, it, str) { *it = tolower(*it); } return str;}char* NStr::ToUpper(char* str){ char* s; for (s = str; *str; str++) { *str = toupper(*str); } return s;}string& NStr::ToUpper(string& str){ NON_CONST_ITERATE (string, it, str) { *it = toupper(*it); } return str;}int NStr::StringToNumeric(const string& str){ if (str.empty() || !isdigit(*str.begin())) { return -1; } errno = 0; char* endptr = 0; unsigned long value = strtoul(str.c_str(), &endptr, 10); if (errno || !endptr || value > (unsigned long) kMax_Int || *endptr != '\0' || endptr == str.c_str()) { return -1; } return (int) value;}# define CHECK_ENDPTR(conv) \ if (check_endptr == eCheck_Need && *endptr != '\0') { \ NCBI_THROW2(CStringException, eBadArgs, \ "String cannot be converted to " conv " - trailing junk", \ s_DiffPtr(endptr, str.c_str())); \ }int NStr::StringToInt(const string& str, int base /* = 10 */, ECheckEndPtr check_endptr /* = eCheck_Need */ ){ errno = 0; char* endptr = 0; long value = strtol(str.c_str(), &endptr, base); if (errno || !endptr || endptr == str.c_str() || value < kMin_Int || value > kMax_Int) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to int", s_DiffPtr(endptr, str.c_str())); } CHECK_ENDPTR("int"); return (int) value;}unsigned int NStr::StringToUInt(const string& str, int base /* =10 */, ECheckEndPtr check_endptr /* =eCheck_Need */){ errno = 0; char* endptr = 0; unsigned long value = strtoul(str.c_str(), &endptr, base); if (errno || !endptr || endptr == str.c_str() || value > kMax_UInt) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted unsigned int", s_DiffPtr(endptr, str.c_str())); } CHECK_ENDPTR("unsigned int"); return (unsigned int) value;}long NStr::StringToLong(const string& str, int base /* = 10 */, ECheckEndPtr check_endptr /* = eCheck_Need */ ){ errno = 0; char* endptr = 0; long value = strtol(str.c_str(), &endptr, base); if (errno || !endptr || endptr == str.c_str()) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to long", s_DiffPtr(endptr, str.c_str())); } CHECK_ENDPTR("long"); return value;}unsigned long NStr::StringToULong(const string& str, int base /*=10 */, ECheckEndPtr check_endptr /*=eCheck_Need*/){ errno = 0; char* endptr = 0; unsigned long value = strtoul(str.c_str(), &endptr, base); if (errno || !endptr || endptr == str.c_str()) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to unsigned long", s_DiffPtr(endptr, str.c_str())); } CHECK_ENDPTR("unsigned long"); return value;}double NStr::StringToDouble(const string& str, ECheckEndPtr check_endptr /* = eCheck_Need */ ){ errno = 0; char* endptr = 0; double value = strtod(str.c_str(), &endptr); if (errno || !endptr || endptr == str.c_str()) { NCBI_THROW2(CStringException, eConvert, "String cannot be converted to double", s_DiffPtr(endptr, str.c_str())); } if (*(endptr - 1) != '.' && *endptr == '.') endptr++; CHECK_ENDPTR("double"); return value;}string NStr::IntToString(long value, bool sign /* = false */ ){ char buffer[64]; ::sprintf(buffer, sign ? "%+ld" : "%ld", value); return buffer;}void NStr::IntToString(string& out_str, long value, bool sign){ char buffer[64]; ::sprintf(buffer, sign ? "%+ld" : "%ld", value); out_str = buffer;}string NStr::UIntToString(unsigned long value){ char buffer[64]; ::sprintf(buffer, "%lu", value); return buffer;}void NStr::UIntToString(string& out_str, unsigned long value){ char buffer[64]; ::sprintf(buffer, "%lu", value); out_str = buffer;}string NStr::Int8ToString(Int8 value, bool sign /* = false */ ){ string ret; NStr::Int8ToString(ret, value, sign); return ret;}void NStr::Int8ToString(string& out_str, Int8 value, bool sign){ const size_t kBufSize = (sizeof(value) * CHAR_BIT) / 3 + 2; char buffer[kBufSize]; char* pos = buffer + kBufSize; if (value == 0) { *--pos = '0'; } else { bool is_negative = value < 0; if ( is_negative ) value = -value; do { *--pos = char('0' + (value % 10)); value /= 10; } while ( value ); if ( is_negative ) *--pos = '-'; else if ( sign ) *--pos = '+'; } out_str.resize(0); out_str.append(pos, buffer + kBufSize - pos);}Int8 NStr::StringToInt8(const string& str){ bool sign = false; const char* pc = str.c_str(); switch (*pc) { case '-': sign = true; /*FALLTHRU*/ case '+': ++pc; /*FALLTHRU*/ default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -