LCOV - code coverage report
Current view: top level - util - CubitString.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 55 202 27.2 %
Date: 2020-06-30 00:58:45 Functions: 18 50 36.0 %
Branches: 19 216 8.8 %

           Branch data     Line data    Source code
       1                 :            : // CubitString.cpp
       2                 :            : 
       3                 :            : 
       4                 :            : #include "CubitString.hpp"
       5                 :            : #include "CubitDefines.h"
       6                 :            : 
       7                 :            : #ifdef _WIN32
       8                 :            : #include <windows.h>
       9                 :            : #define vsnprintf _vsnprintf
      10                 :            : #endif
      11                 :            : 
      12                 :            : #ifdef _MSC_VER
      13                 :            : #pragma warning ( 4 : 4291 4244 4305 4018 )
      14                 :            : #define va_copy(dest, src) (dest = src)
      15                 :            : #endif
      16                 :            : 
      17                 :            : 
      18                 :            : #include <iomanip>
      19                 :            : #include <cstring>
      20                 :            : #include <stdexcept>
      21                 :            : #include <algorithm>
      22                 :            : #include <stdarg.h>
      23                 :            : 
      24                 :            : const size_t CubitString::npos = std::string::npos;
      25                 :            : 
      26                 :     349964 : CubitString::CubitString()
      27                 :            : {
      28                 :     174982 : }
      29                 :            : 
      30                 :    1177606 : CubitString::CubitString(const CubitString& s)
      31                 :    1177606 :   : rep(s.rep)
      32                 :            : {
      33                 :    1177606 : }
      34                 :            : 
      35                 :    5009700 : CubitString::~CubitString()
      36                 :            : {
      37                 :    2504850 : }
      38                 :            : 
      39                 :    2551654 : CubitString::CubitString(const char *s)
      40                 :            : {
      41         [ +  - ]:    1275827 :   if(s)
      42                 :            :   {
      43         [ +  - ]:    1275827 :     rep = s;
      44                 :            :   }
      45                 :    1275827 : }
      46                 :            : 
      47                 :          0 : CubitString::CubitString(const std::string& s)
      48                 :          0 :   : rep(s)
      49                 :            : {
      50                 :          0 : }
      51                 :            : 
      52                 :          0 : CubitString::CubitString(int i, char c)
      53         [ #  # ]:          0 :   : rep(i,c)
      54                 :            : {
      55                 :          0 : }
      56                 :            : 
      57                 :          0 : CubitString CubitString::number(double f, unsigned int max_length, unsigned int sig_digits)
      58                 :            : {
      59 [ #  # ][ #  # ]:          0 :   std::stringstream str;
      60         [ #  # ]:          0 :   if(max_length)
      61                 :            :   {
      62         [ #  # ]:          0 :     str.width(max_length);
      63                 :            :   }
      64         [ #  # ]:          0 :   if(sig_digits)
      65                 :            :   {
      66         [ #  # ]:          0 :     str.precision(sig_digits);
      67                 :            :   }
      68         [ #  # ]:          0 :   str << f;
      69 [ #  # ][ #  # ]:          0 :   std::string ret = str.str();
      70         [ #  # ]:          0 :   size_t i = ret.find_first_not_of(' ');
      71         [ #  # ]:          0 :   if(i != std::string::npos)
      72 [ #  # ][ #  # ]:          0 :     ret = ret.substr(i);
                 [ #  # ]
      73                 :            : 
      74                 :            :   // change precision to be short enough
      75         [ #  # ]:          0 :   if (max_length) 
      76                 :            :   {
      77         [ #  # ]:          0 :     if(sig_digits == 0)
      78                 :          0 :       sig_digits = max_length;
      79                 :            : 
      80 [ #  # ][ #  # ]:          0 :     while(ret.length() > max_length && sig_digits)
         [ #  # ][ #  # ]
      81                 :            :     {
      82                 :          0 :       sig_digits--;
      83         [ #  # ]:          0 :       str.precision(sig_digits);
      84 [ #  # ][ #  # ]:          0 :       str.str(std::string());
                 [ #  # ]
      85         [ #  # ]:          0 :       str << f;
      86 [ #  # ][ #  # ]:          0 :       ret = str.str();
                 [ #  # ]
      87                 :            :     }
      88                 :            :   }
      89 [ #  # ][ #  # ]:          0 :   return ret.c_str();
                 [ #  # ]
      90                 :            : }
      91                 :            : 
      92                 :       8242 : CubitString CubitString::format(const char* format, ...)
      93                 :            : {
      94                 :            :   va_list args, args2;
      95                 :       8242 :   va_start(args, format);
      96                 :            :   // copy because first vsnprintf modifies args
      97                 :       8242 :   va_copy(args2, args);
      98                 :            : 
      99                 :            :   // how much room do we need for our string?
     100                 :       8242 :   int num = vsnprintf(NULL, 0, format, args);
     101                 :            : 
     102                 :            :   // string plus null terminator
     103         [ +  - ]:       8242 :   std::vector<char> str;
     104         [ +  - ]:       8242 :   str.resize(num+1);
     105                 :            : 
     106                 :            :   // print string
     107         [ +  - ]:       8242 :   num = vsnprintf(&str[0], num+1, format, args2);
     108                 :            : 
     109                 :            :   // remove extra null terminator
     110         [ +  - ]:       8242 :   str.resize(num);
     111                 :            : 
     112                 :       8242 :   va_end(args);
     113                 :       8242 :   va_end(args2);
     114                 :            : 
     115 [ +  - ][ -  + ]:       8242 :   return str.empty() ? CubitString() : CubitString(&str[0]);
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
     116                 :            : }
     117                 :            : 
     118                 :     114912 : CubitString& CubitString::operator=(const CubitString& s)
     119                 :            : {
     120                 :     114912 :   rep = s.rep;
     121                 :     114912 :   return *this;
     122                 :            : }
     123                 :            : 
     124                 :            : #ifdef _WIN32
     125                 :            : # define strcasecmp _stricmp
     126                 :            : #endif
     127                 :            : 
     128                 :          0 : bool CubitString::compare(const CubitString& s, CaseSensitivity cs)
     129                 :            : {
     130         [ #  # ]:          0 :   if(cs == CaseSensitive)
     131                 :          0 :     return this->rep == s.rep;
     132                 :            : 
     133                 :            :   // someday we might need to fix this to be unicode aware
     134         [ #  # ]:          0 :   if(strcasecmp(this->rep.c_str(), s.rep.c_str()) == 0)
     135                 :          0 :     return true;
     136                 :          0 :   return false;
     137                 :            : }
     138                 :            : 
     139                 :      24713 : char CubitString::get_at(size_t pos) const
     140                 :            : {
     141                 :            :   // some legacy code wants to look for the null terminator
     142         [ -  + ]:      24713 :   if(pos == rep.size())
     143                 :          0 :     return 0;
     144                 :            : 
     145                 :      24713 :   return rep.at(pos);
     146                 :            : }
     147                 :            : 
     148                 :          0 : bool CubitString::is_empty() const
     149                 :            : {
     150                 :          0 :   return rep.empty();
     151                 :            : }
     152                 :            : 
     153                 :      64419 : size_t CubitString::length() const
     154                 :            : {
     155                 :      64419 :   return rep.length();
     156                 :            : }
     157                 :            : 
     158                 :     355738 : const char * CubitString::c_str() const
     159                 :            : {
     160                 :     355738 :   return rep.c_str();
     161                 :            : }
     162                 :            : 
     163                 :          0 : const std::string& CubitString::str() const
     164                 :            : {
     165                 :          0 :   return rep;
     166                 :            : }
     167                 :            : 
     168                 :          0 : void CubitString::clear()
     169                 :            : {
     170                 :          0 :   rep.clear();
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : void CubitString::resize(size_t n)
     174                 :            : {
     175                 :          0 :   rep.resize(n);
     176                 :          0 : }
     177                 :            : 
     178                 :          0 : void CubitString::resize(size_t n, char c)
     179                 :            : {
     180                 :          0 :   rep.resize(n, c);
     181                 :          0 : }
     182                 :            : 
     183                 :            : 
     184                 :       9034 : CubitString operator+(const CubitString& s1, const CubitString& s2)
     185                 :            : {
     186 [ +  - ][ +  - ]:       9034 :   return CubitString(s1) += s2;
     187                 :            : }
     188                 :            : 
     189                 :          0 : CubitString operator+(const CubitString& s1, const char *c2)
     190                 :            : {
     191 [ #  # ][ #  # ]:          0 :   return CubitString(s1) += c2;
         [ #  # ][ #  # ]
     192                 :            : }
     193                 :            : 
     194                 :          0 : CubitString operator+(const char *c1, const CubitString& s2)
     195                 :            : {
     196 [ #  # ][ #  # ]:          0 :   return CubitString(c1) += s2;
     197                 :            : }
     198                 :            : 
     199                 :      10039 : CubitString& CubitString::operator+=(const CubitString& s)
     200                 :            : {
     201                 :      10039 :   rep += s.rep;
     202                 :      10039 :   return *this;
     203                 :            : }
     204                 :            : 
     205                 :          0 : size_t CubitString::find(const CubitString& s, size_t pos) const
     206                 :            : {
     207 [ #  # ][ #  # ]:          0 :   if(pos != 0 && pos >= rep.size())
                 [ #  # ]
     208 [ #  # ][ #  # ]:          0 :     throw std::out_of_range("find index out of range");
     209                 :          0 :   return rep.find(s.rep, pos);
     210                 :            : }
     211                 :            : 
     212                 :          0 : size_t CubitString::find_first_of(const CubitString& s, size_t pos) const
     213                 :            : {
     214                 :          0 :   return rep.find_first_of(s.rep, pos);
     215                 :            : }
     216                 :            : 
     217                 :          0 : size_t CubitString::find_first(char c, size_t pos) const
     218                 :            : {
     219                 :          0 :   return rep.find(c, pos);
     220                 :            : }
     221                 :            : 
     222                 :        841 : size_t CubitString::find_last(char c, size_t pos) const
     223                 :            : {
     224                 :        841 :   return rep.find_last_of(c, pos);
     225                 :            : }
     226                 :            : 
     227                 :            : 
     228                 :       1170 : CubitString CubitString::substr(size_t first, size_t count) const
     229                 :            : {
     230         [ -  + ]:       1170 :   if(first >= rep.size())
     231                 :          0 :     return CubitString();
     232                 :            : 
     233         [ +  + ]:       1170 :   if(count > rep.size() - first)
     234                 :        183 :     count = rep.size() - first;
     235                 :            : 
     236 [ +  - ][ +  - ]:       1170 :   return rep.substr(first, count).c_str();
     237                 :            : }
     238                 :            : 
     239                 :          0 : void CubitString::erase(size_t pos, size_t len)
     240                 :            : {
     241                 :          0 :   rep.erase(pos, len);
     242                 :          0 : }
     243                 :            : 
     244                 :          0 : void CubitString::replace(size_t pos, size_t len, const CubitString& str)
     245                 :            : {
     246                 :          0 :   rep.replace(pos, len, str.rep);
     247                 :          0 : }
     248                 :            : 
     249                 :          0 : void CubitString::replace(const CubitString& to_find, const CubitString& to_replace)
     250                 :            : {
     251                 :          0 :   size_t len = to_find.length();
     252                 :          0 :   size_t len2 = to_replace.length();
     253         [ #  # ]:          0 :   for(size_t idx = rep.find(to_find.c_str()); idx != npos; idx = rep.find(to_find.c_str(), idx))
     254                 :            :   {
     255                 :          0 :     rep.replace(idx, len, to_replace.rep);
     256                 :          0 :     idx += len2;
     257                 :            :   }
     258                 :          0 : }
     259                 :            : 
     260                 :          0 : bool CubitString::ends_with(const CubitString& str) const
     261                 :            : {
     262         [ #  # ]:          0 :   if(rep.size() >= str.rep.size())
     263                 :            :   {
     264                 :          0 :     size_t offset = rep.size() - str.rep.size();
     265 [ #  # ][ #  # ]:          0 :     return std::equal(str.rep.begin(), str.rep.end(), rep.begin() + offset);
         [ #  # ][ #  # ]
                 [ #  # ]
     266                 :            :   }
     267                 :          0 :   return false;
     268                 :            : }
     269                 :            : 
     270                 :          0 : bool CubitString::starts_with(const CubitString& str) const
     271                 :            : {
     272         [ #  # ]:          0 :   if(rep.size() >= str.rep.size())
     273                 :            :   {
     274                 :          0 :     return std::equal(str.rep.begin(), str.rep.end(), rep.begin());
     275                 :            :   }
     276                 :          0 :   return false;
     277                 :            : }
     278                 :            : 
     279                 :       1931 : void CubitString::put_at(size_t pos, char c)
     280                 :            : {
     281                 :       1931 :   rep.at(pos) = c;
     282                 :       1931 : }
     283                 :            : 
     284                 :          0 : void CubitString::to_lower() 
     285                 :            : {
     286         [ #  # ]:          0 :   for(size_t i=0; i<rep.size(); i++)
     287                 :            :   {
     288                 :          0 :     rep.at(i) = tolower(rep.at(i));
     289                 :            :   }
     290                 :          0 : }
     291                 :            : 
     292                 :          0 : void CubitString::to_upper() 
     293                 :            : {
     294         [ #  # ]:          0 :   for(size_t i=0; i<rep.size(); i++)
     295                 :            :   {
     296                 :          0 :     rep.at(i) = toupper(rep.at(i));
     297                 :            :   }
     298                 :          0 : }
     299                 :            : 
     300                 :          0 : void CubitString::to_lower(char *string)
     301                 :            : {
     302                 :            :     // convert this string to lower case
     303                 :          0 :   char *p = string;
     304         [ #  # ]:          0 :   while (*p != '\0')
     305                 :            :   {
     306                 :          0 :     *p = tolower (*p);
     307                 :          0 :     p++;
     308                 :            :   }
     309                 :          0 : }
     310                 :            : 
     311                 :          0 : void CubitString::to_upper(char *string)
     312                 :            : {
     313                 :            :     // convert this string to upper case
     314                 :          0 :   char *p = string;
     315         [ #  # ]:          0 :   while (*p != '\0')
     316                 :            :   {
     317                 :          0 :     *p = toupper (*p);
     318                 :          0 :     p++;
     319                 :            :   }
     320                 :          0 : }
     321                 :            : 
     322                 :          0 : void CubitString::trim()
     323                 :            : {
     324                 :          0 :   std::string::size_type start = rep.find_first_not_of(" \t\n\v\f\r");
     325                 :          0 :   rep.erase(0, start);
     326                 :          0 :   std::string::size_type end = rep.find_last_not_of(" \t\n\v\f\r");
     327                 :          0 :   rep.erase(end+1, std::string::npos);
     328                 :          0 : }
     329                 :            : 
     330                 :          0 : void CubitString::simplify()
     331                 :            : {
     332                 :          0 :   trim();
     333         [ #  # ]:          0 :   for(std::string::size_type i = rep.find_first_of(" \t\n\v\f\r"); i != std::string::npos;
     334                 :          0 :       i = rep.find_first_of(" \t\n\v\f\r", i+1))
     335                 :            :   {
     336                 :          0 :     std::string::size_type next_i = rep.find_first_not_of(" \t\n\v\f\r", i);
     337         [ #  # ]:          0 :     if(next_i > i+1)
     338                 :            :     {
     339                 :          0 :       rep.erase(i+1, next_i-i-1);
     340                 :          0 :       rep.at(i) = ' ';
     341                 :            :     }
     342                 :            :   }
     343                 :          0 : }
     344                 :            : 
     345                 :          0 : void CubitString::tokenize( char delimiter, std::vector<CubitString> &strings ) const
     346                 :            : {
     347 [ #  # ][ #  # ]:          0 :   std::stringstream ss(rep);
     348 [ #  # ][ #  # ]:          0 :   std::string s;
     349 [ #  # ][ #  # ]:          0 :   while(std::getline(ss, s, delimiter))
                 [ #  # ]
     350 [ #  # ][ #  # ]:          0 :     strings.push_back(CubitString(s.c_str()));
         [ #  # ][ #  # ]
                 [ #  # ]
     351                 :          0 : }
     352                 :            : 
     353                 :      29374 : bool CubitString::operator==(const CubitString& s2) const
     354                 :            : {
     355                 :      29374 :   return rep == s2.rep;
     356                 :            : }
     357                 :            : 
     358                 :      55088 : bool CubitString::operator!=(const CubitString& s2) const
     359                 :            : {
     360                 :      55088 :   return rep != s2.rep;
     361                 :            : }
     362                 :            : 
     363                 :          0 : bool operator<=(const CubitString& s1, const CubitString& s2)
     364                 :            : {
     365                 :          0 :   return s1.rep <= s2.rep;
     366                 :            : }
     367                 :            : 
     368                 :         40 : bool operator>=(const CubitString& s1, const CubitString& s2)
     369                 :            : {
     370                 :         40 :   return s1.rep >= s2.rep;
     371                 :            : }
     372                 :            : 
     373                 :     418767 : bool operator<( const CubitString& s1, const CubitString& s2 )
     374                 :            : {
     375                 :     418767 :   return s1.rep < s2.rep;
     376                 :            : }
     377                 :            : 
     378                 :          0 : bool operator>( const CubitString& s1, const CubitString& s2 )
     379                 :            : {
     380                 :          0 :   return s1.rep > s2.rep;
     381                 :            : }
     382                 :            : 
     383                 :            : #if defined(_WIN32)
     384                 :            : 
     385                 :            : std::wstring CubitString::toUtf16(const char* str)
     386                 :            : {
     387                 :            :   // there are other methods (e.g. C++11), but since its Windows specific to support Windows APIs, just use their API.
     388                 :            :   std::wstring ret;
     389                 :            :   int sz = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
     390                 :            :   if(sz)
     391                 :            :   {
     392                 :            :     std::vector<wchar_t> result(sz);
     393                 :            :     MultiByteToWideChar(CP_UTF8, 0, str, -1, &result[0], sz);
     394                 :            :     ret = &result[0];
     395                 :            :   }
     396                 :            :   return ret;
     397                 :            : }
     398                 :            : 
     399                 :            : std::wstring CubitString::toUtf16(const CubitString& str)
     400                 :            : {
     401                 :            :   return toUtf16(str.c_str());
     402                 :            : }
     403                 :            : 
     404                 :            : CubitString CubitString::toUtf8(const wchar_t* str)
     405                 :            : {
     406                 :            :   CubitString ret;
     407                 :            :   int sz = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
     408                 :            :   if(sz)
     409                 :            :   {
     410                 :            :     std::vector<char> result(sz);
     411                 :            :     WideCharToMultiByte(CP_UTF8, 0, str, -1, &result[0], sz, NULL, NULL);
     412                 :            :     ret = &result[0];
     413                 :            :   }
     414                 :            :   return ret;
     415                 :            : }
     416                 :            : 
     417                 :            : #endif
     418                 :            : 
     419                 :            : #if defined(_MSC_VER)
     420                 :            : 
     421                 :            : std::wstring CubitString::toNative(const char* str)
     422                 :            : {
     423                 :            :   return toUtf16(str);
     424                 :            : }
     425                 :            : 
     426                 :            : std::wstring CubitString::toNative(const CubitString& str)
     427                 :            : {
     428                 :            :   return toUtf16(str);
     429                 :            : }
     430                 :            : 
     431                 :            : #else
     432                 :            : 
     433                 :          0 : CubitString CubitString::toNative(const char* str)
     434                 :            : {
     435                 :          0 :   return str;
     436                 :            : }
     437                 :            : 
     438                 :          0 : CubitString CubitString::toNative(const CubitString& str)
     439                 :            : {
     440                 :          0 :   return str;
     441                 :            : }
     442                 :            : 
     443                 :            : #endif
     444                 :            : 
     445                 :          0 : std::wstring CubitString::toWide(const CubitString& str)
     446                 :            : {
     447                 :            : #ifdef _WIN32
     448                 :            :   return toUtf16(str);
     449                 :            : #else
     450                 :          0 :   std::wstring wstr;
     451         [ #  # ]:          0 :   size_t len = mbstowcs(NULL, str.c_str(), 0) + 1;
     452         [ #  # ]:          0 :   if(len > 0)
     453                 :            :   {
     454         [ #  # ]:          0 :     std::vector<wchar_t> wchar(len);
     455 [ #  # ][ #  # ]:          0 :     mbstowcs(&wchar[0], str.c_str(), len);
     456 [ #  # ][ #  # ]:          0 :     wstr = &wchar[0];
                 [ #  # ]
     457                 :            :   }
     458                 :          0 :   return wstr;
     459                 :            : #endif
     460                 :            : }
     461                 :            : 
     462                 :          0 : CubitString CubitString::toNarrow(const std::wstring& wstr)
     463                 :            : {
     464                 :            : #ifdef _WIN32
     465                 :            :   return toUtf8(wstr.c_str()).c_str();
     466                 :            : #else
     467                 :          0 :   CubitString str;
     468         [ #  # ]:          0 :   size_t len = wcstombs(NULL, wstr.c_str(), 0) + 1;
     469         [ #  # ]:          0 :   if(len > 0)
     470                 :            :   {
     471         [ #  # ]:          0 :     std::vector<char> chars(len);
     472 [ #  # ][ #  # ]:          0 :     wcstombs(&chars[0], wstr.c_str(), len);
     473 [ #  # ][ #  # ]:          0 :     str = &chars[0];
         [ #  # ][ #  # ]
                 [ #  # ]
     474                 :            :   }
     475                 :          0 :   return str;
     476                 :            : #endif
     477                 :            : }
     478                 :            : 
     479                 :            : 
     480                 :            : 
     481                 :            : #ifdef TEST_STRING
     482                 :            : 
     483                 :            : void main() {
     484                 :            : CubitString a = "Test ";
     485                 :            : CubitString b = "String Class";
     486                 :            : CubitString blank(' ');
     487                 :            : 
     488                 :            : CubitString c = a + b;
     489                 :            : c+= b;
     490                 :            : CubitString e = c;
     491                 :            : CubitString f = c;
     492                 :            : CubitString g = c;
     493                 :            : g.put_at(1, 'Z');
     494                 :            : cout << "G = " << g << endl;
     495                 :            : cout << "C = " << c << endl;
     496                 :            : 
     497                 :            : c.put_at(1, 'X');
     498                 :            : CubitString d = b;
     499                 :            : d.put_at(1, 'Y');
     500                 :            : }
     501                 :            : #endif

Generated by: LCOV version 1.11