1 /*
2  *  Copyright (C) 2010  Regents of the University of Michigan
3  *
4  *   This program is free software: you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation, either version 3 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "STLUtilities.h"
19 
20 namespace STLUtilities
21 {
22 
23 //
24 // Split the string input into words delimited by the character
25 // delimiter.  For a given number of input delimiters, result.size()
26 // will not change, regardless of the data in between the delimiters.
27 //
28 // Refactor this to pre-allocate the word that we place data into,
29 // then we have minimal data copy.
30 //
Tokenize(std::vector<std::string> & result,const char * input,char delimiter)31 int Tokenize(std::vector<std::string> &result, const char *input, char delimiter)
32 {
33     if (*input=='\0')
34     {
35         result.clear();
36         result.resize(1);   // one word, and it is empty
37         return 0;
38     }
39 
40     size_t wordCount = 1;
41 
42     // since input is non-empty, we know we will have at least
43     // one word, so we allocate it here, and begin to fill it in
44     if (result.size()<wordCount) result.resize(1);
45     else result[0].clear();
46 
47     std::string *word = &result[0];
48 
49     while (*input)
50     {
51         if (*input==delimiter)
52         {
53             // we got a delimeter, and since an empty word following
54             // a delimeter still counts as a word, we allocate it here
55             wordCount++;
56             if (result.size()<wordCount) result.resize(wordCount);
57             else
58             {
59                 result[wordCount-1].clear();
60             }
61             word = &result[wordCount-1];
62         }
63         else
64         {
65             // save the char in this word
66             word->push_back(*input);
67         }
68         input++;
69     }
70 
71     if (wordCount < result.size()) result.resize(wordCount);  // potentially truncate to wordCount elements
72 
73     return result.size();
74 }
75 
76 } // end of namespace STLUtilities
77