BaseString.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* -*- c-basic-offset: 4; -*- */
  14. #include <ndb_global.h>
  15. #include <BaseString.hpp>
  16. #include <basestring_vsnprintf.h>
  17. BaseString::BaseString()
  18. {
  19.     m_chr = new char[1];
  20.     m_chr[0] = 0;
  21.     m_len = 0;
  22. }
  23. BaseString::BaseString(const char* s)
  24. {
  25.     const size_t n = strlen(s);
  26.     m_chr = new char[n + 1];
  27.     memcpy(m_chr, s, n + 1);
  28.     m_len = n;
  29. }
  30. BaseString::BaseString(const BaseString& str)
  31. {
  32.     const char* const s = str.m_chr;
  33.     const size_t n = str.m_len;
  34.     char* t = new char[n + 1];
  35.     memcpy(t, s, n + 1);
  36.     m_chr = t;
  37.     m_len = n;
  38. }
  39. BaseString::~BaseString()
  40. {
  41.     delete[] m_chr;
  42. }
  43. BaseString&
  44. BaseString::assign(const char* s)
  45. {
  46.     const size_t n = strlen(s);
  47.     char* t = new char[n + 1];
  48.     memcpy(t, s, n + 1);
  49.     delete[] m_chr;
  50.     m_chr = t;
  51.     m_len = n;
  52.     return *this;
  53. }
  54. BaseString&
  55. BaseString::assign(const char* s, size_t n)
  56. {
  57.     char* t = new char[n + 1];
  58.     memcpy(t, s, n);
  59.     t[n] = 0;
  60.     delete[] m_chr;
  61.     m_chr = t;
  62.     m_len = n;
  63.     return *this;
  64. }
  65. BaseString&
  66. BaseString::assign(const BaseString& str, size_t n)
  67. {
  68.     if (n > str.m_len)
  69. n = str.m_len;
  70.     return assign(str.m_chr, n);
  71. }
  72. BaseString&
  73. BaseString::append(const char* s)
  74. {
  75.     const size_t n = strlen(s);
  76.     char* t = new char[m_len + n + 1];
  77.     memcpy(t, m_chr, m_len);
  78.     memcpy(t + m_len, s, n + 1);
  79.     delete[] m_chr;
  80.     m_chr = t;
  81.     m_len += n;
  82.     return *this;
  83. }
  84. BaseString&
  85. BaseString::append(char c) {
  86.     return appfmt("%c", c);
  87. }
  88. BaseString&
  89. BaseString::append(const BaseString& str)
  90. {
  91.     return append(str.m_chr);
  92. }
  93. BaseString&
  94. BaseString::append(const Vector<BaseString> &vector,
  95.    const BaseString &separator) {
  96.     for(size_t i=0;i<vector.size(); i++) {
  97. append(vector[i]);
  98. if(i<vector.size()-1)
  99.     append(separator);
  100.     }
  101.     return *this;
  102. }
  103. BaseString&
  104. BaseString::assfmt(const char *fmt, ...)
  105. {
  106.     char buf[1];
  107.     va_list ap;
  108.     int l;
  109.     /* Figure out how long the formatted string will be. A small temporary
  110.      * buffer is used, because I don't trust all implementations to work
  111.      * when called as vsnprintf(NULL, 0, ...).
  112.      */
  113.     va_start(ap, fmt);
  114.     l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
  115.     va_end(ap);
  116.     if(l > (int)m_len) {
  117. delete[] m_chr;
  118. m_chr = new char[l];
  119.     }
  120.     va_start(ap, fmt);
  121.     basestring_vsnprintf(m_chr, l, fmt, ap);
  122.     va_end(ap);
  123.     m_len = strlen(m_chr);
  124.     return *this;
  125. }
  126. BaseString&
  127. BaseString::appfmt(const char *fmt, ...)
  128. {
  129.     char buf[1];
  130.     va_list ap;
  131.     int l;
  132.     /* Figure out how long the formatted string will be. A small temporary
  133.      * buffer is used, because I don't trust all implementations to work
  134.      * when called as vsnprintf(NULL, 0, ...).
  135.      */
  136.     va_start(ap, fmt);
  137.     l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
  138.     va_end(ap);
  139.     char *tmp = new char[l];
  140.     va_start(ap, fmt);
  141.     basestring_vsnprintf(tmp, l, fmt, ap);
  142.     va_end(ap);
  143.     append(tmp);
  144.     delete[] tmp;
  145.     return *this;
  146. }
  147. BaseString&
  148. BaseString::operator=(const BaseString& str)
  149. {
  150.     if (this != &str) {
  151. this->assign(str);
  152.     }
  153.     return *this;
  154. }
  155. int
  156. BaseString::split(Vector<BaseString> &v,
  157.   const BaseString &separator,
  158.   int maxSize) const {
  159.     char *str = strdup(m_chr);
  160.     int i, start, len, num = 0;
  161.     len = strlen(str);
  162.     for(start = i = 0;
  163. (i <= len) && ( (maxSize<0) || ((int)v.size()<=maxSize-1) );
  164. i++) {
  165. if(strchr(separator.c_str(), str[i]) || i == len) {
  166.     if(maxSize < 0 || (int)v.size() < maxSize-1)
  167. str[i] = '';
  168.     v.push_back(BaseString(str+start));
  169.     num++;
  170.     start = i+1;
  171. }
  172.     }
  173.     free(str);
  174.     return num;
  175. }
  176. ssize_t
  177. BaseString::indexOf(char c) {
  178.     char *p;
  179.     p = strchr(m_chr, c);
  180.     if(p == NULL)
  181. return -1;
  182.     return (ssize_t)(p-m_chr);
  183. }
  184. ssize_t
  185. BaseString::lastIndexOf(char c) {
  186.     char *p;
  187.     p = strrchr(m_chr, c);
  188.     if(p == NULL)
  189. return -1;
  190.     return (ssize_t)(p-m_chr);
  191. }
  192. BaseString
  193. BaseString::substr(ssize_t start, ssize_t stop) {
  194.     if(stop < 0)
  195. stop = length();
  196.     ssize_t len = stop-start;
  197.     if(len <= 0)
  198. return BaseString("");
  199.     BaseString s;
  200.     s.assign(m_chr+start, len);
  201.     return s;
  202. }
  203. static bool
  204. iswhite(char c) {
  205.   switch(c) {
  206.   case ' ':
  207.   case 't':
  208.     return true;
  209.   default:
  210.     return false;
  211.   }
  212.   /* NOTREACHED */
  213. }
  214. char **
  215. BaseString::argify(const char *argv0, const char *src) {
  216.     Vector<char *> vargv;
  217.     
  218.     if(argv0 != NULL)
  219. vargv.push_back(strdup(argv0));
  220.     
  221.     char *tmp = new char[strlen(src)+1];
  222.     char *dst = tmp;
  223.     const char *end = src + strlen(src);
  224.     /* Copy characters from src to destination, while compacting them
  225.      * so that all whitespace is compacted and replaced by a NUL-byte.
  226.      * At the same time, add pointers to strings in the vargv vector.
  227.      * When whitespace is detected, the characters '"' and '' are honored,
  228.      * to make it possible to give arguments containing whitespace.
  229.      * The semantics of '"' and '' match that of most Unix shells.
  230.      */
  231.     while(src < end && *src) {
  232. /* Skip initial whitespace */
  233. while(src < end && *src && iswhite(*src))
  234.     src++;
  235. char *begin = dst;
  236. while(src < end && *src) {
  237.     /* Handle '"' quotation */
  238.     if(*src == '"') {
  239. src++;
  240. while(src < end && *src && *src != '"') {
  241.     if(*src == '\')
  242. src++;
  243.     *dst++ = *src++;
  244. }
  245. src++;
  246. if(src >= end)
  247.     goto end;
  248.     }
  249.     
  250.     /* Handle '' */
  251.     if(*src == '\')
  252. src++;
  253.     else if(iswhite(*src))
  254. break;
  255.     /* Actually copy characters */
  256.     *dst++ = *src++;
  257. }
  258. /* Make sure the string is properly terminated */
  259. *dst++ = '';
  260. src++;
  261. vargv.push_back(strdup(begin));
  262.     }
  263.  end:
  264.     
  265.     delete[] tmp;
  266.     vargv.push_back(NULL);
  267.     
  268.     /* Convert the C++ Vector into a C-vector of strings, suitable for
  269.      * calling execv().
  270.      */
  271.     char **argv = (char **)malloc(sizeof(*argv) * (vargv.size()));
  272.     if(argv == NULL)
  273. return NULL;
  274.     
  275.     for(size_t i = 0; i < vargv.size(); i++){
  276. argv[i] = vargv[i];
  277.     }
  278.     
  279.     return argv;
  280. }
  281. BaseString&
  282. BaseString::trim(const char * delim){
  283.     trim(m_chr, delim);
  284.     m_len = strlen(m_chr);
  285.     return * this;
  286. }
  287. char*
  288. BaseString::trim(char * str, const char * delim){
  289.     int len = strlen(str) - 1;
  290.     for(; len > 0 && strchr(delim, str[len]); len--);
  291.     
  292.     int pos = 0;
  293.     for(; pos <= len && strchr(delim, str[pos]); pos++);
  294.     
  295.     if(pos > len){
  296. str[0] = 0;
  297. return 0;
  298.     } else {
  299. memmove(str, &str[pos], len - pos + 1);
  300. str[len-pos+1] = 0;
  301.     }
  302.     
  303.     return str;
  304. }
  305. int
  306. BaseString::vsnprintf(char *str, size_t size, const char *format, va_list ap)
  307. {
  308.   return(basestring_vsnprintf(str, size, format, ap));
  309. }
  310. int
  311. BaseString::snprintf(char *str, size_t size, const char *format, ...)
  312. {
  313.   va_list ap;
  314.   va_start(ap, format);
  315.   int ret= basestring_vsnprintf(str, size, format, ap);
  316.   va_end(ap);
  317.   return(ret);
  318. }
  319. #ifdef TEST_BASE_STRING
  320. /*
  321. g++ -g -Wall -o tbs -DTEST_BASE_STRING -I$NDB_TOP/include/util 
  322.         -I$NDB_TOP/include/portlib BaseString.cpp
  323. valgrind ./tbs
  324. */
  325. int main()
  326. {
  327.     BaseString s("abc");
  328.     BaseString t(s);
  329.     s.assign("def");
  330.     t.append("123");
  331.     assert(s == "def");
  332.     assert(t == "abc123");
  333.     s.assign("");
  334.     t.assign("");
  335.     for (unsigned i = 0; i < 1000; i++) {
  336. s.append("xyz");
  337. t.assign(s);
  338. assert(strlen(t.c_str()) % 3 == 0);
  339.     }
  340.     {
  341. BaseString s(":123:abc:;:foo:");
  342. Vector<BaseString> v;
  343. assert(s.split(v, ":;") == 7);
  344. assert(v[0] == "");
  345. assert(v[1] == "123");
  346. assert(v[2] == "abc");
  347. assert(v[3] == "");
  348. assert(v[4] == "");
  349. assert(v[5] == "foo");
  350. assert(v[6] == "");
  351.     }
  352.     {
  353. BaseString s(":123:abc:foo:bar");
  354. Vector<BaseString> v;
  355. assert(s.split(v, ":;", 4) == 4);
  356. assert(v[0] == "");
  357. assert(v[1] == "123");
  358. assert(v[2] == "abc");
  359. assert(v[3] == "foo:bar");
  360. BaseString n;
  361. n.append(v, "()");
  362. assert(n == "()123()abc()foo:bar");
  363. n = "";
  364. n.append(v);
  365. assert(n == " 123 abc foo:bar");
  366.     }
  367.     {
  368. assert(BaseString("hamburger").substr(4,2) == "");
  369. assert(BaseString("hamburger").substr(3) == "burger");
  370. assert(BaseString("hamburger").substr(4,8) == "urge");
  371. assert(BaseString("smiles").substr(1,5) == "mile");
  372. assert(BaseString("012345").indexOf('2') == 2);
  373. assert(BaseString("hej").indexOf('X') == -1);
  374.     }
  375.     {
  376. assert(BaseString(" 1").trim(" ") == "1");
  377. assert(BaseString("1 ").trim(" ") == "1");
  378. assert(BaseString(" 1 ").trim(" ") == "1");
  379. assert(BaseString("abctnr kalleabctrn").trim("abctrn ") == "kalle");
  380. assert(BaseString(" ").trim(" ") == "");
  381.     }
  382.     return 0;
  383. }
  384. #endif
  385. template class Vector<char *>;
  386. template class Vector<BaseString>;