StringTokenizer.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include <vector>
00032 #include <iostream>
00033 #include "UtilExceptions.h"
00034 #include "StringTokenizer.h"
00035
00036 #ifdef CHECK_MEMORY_LEAKS
00037 #include <foreign/nvwa/debug_new.h>
00038 #endif // CHECK_MEMORY_LEAKS
00039
00040
00041
00042
00043
00044 const int StringTokenizer::NEWLINE = -256;
00045 const int StringTokenizer::WHITECHARS = -257;
00046
00047
00048
00049
00050
00051 StringTokenizer::StringTokenizer(std::string tosplit)
00052 : myTosplit(tosplit), myPos(0) {
00053 prepareWhitechar(tosplit);
00054 }
00055
00056
00057 StringTokenizer::StringTokenizer(std::string tosplit, std::string token, bool splitAtAllChars)
00058 : myTosplit(tosplit), myPos(0) {
00059 prepare(tosplit, token, splitAtAllChars);
00060 }
00061
00062
00063 StringTokenizer::StringTokenizer(std::string tosplit, int special)
00064 : myTosplit(tosplit), myPos(0) {
00065 switch (special) {
00066 case NEWLINE:
00067 prepare(tosplit, "\r\n", true);
00068 break;
00069 case WHITECHARS:
00070 prepareWhitechar(tosplit);
00071 break;
00072 default:
00073 char *buf = new char[2];
00074 buf[0] = (char) special;
00075 buf[1] = 0;
00076 prepare(tosplit, buf, false);
00077 delete[] buf;
00078 break;
00079 }
00080 }
00081
00082
00083 StringTokenizer::~StringTokenizer() {}
00084
00085 void StringTokenizer::reinit() {
00086 myPos = 0;
00087 }
00088
00089 bool StringTokenizer::hasNext() {
00090 return myPos!=myStarts.size();
00091 }
00092
00093 std::string StringTokenizer::next() {
00094 if (myPos>=myStarts.size()) {
00095 throw OutOfBoundsException();
00096 }
00097 if (myLengths[myPos]==0) {
00098 myPos++;
00099 return "";
00100 }
00101 size_t start = myStarts[myPos];
00102 size_t length = myLengths[myPos++];
00103 return myTosplit.substr(start,length);
00104 }
00105
00106 std::string StringTokenizer::front() {
00107 if (myStarts.size()==0) {
00108 throw OutOfBoundsException();
00109 }
00110 if (myLengths[0]==0) {
00111 return "";
00112 }
00113 return myTosplit.substr(myStarts[0],myLengths[0]);
00114 }
00115
00116 std::string StringTokenizer::get(size_t pos) const {
00117 if (pos>=myStarts.size()) {
00118 throw OutOfBoundsException();
00119 }
00120 if (myLengths[pos]==0) {
00121 return "";
00122 }
00123 size_t start = myStarts[pos];
00124 size_t length = myLengths[pos];
00125 return myTosplit.substr(start, length);
00126 }
00127
00128
00129 size_t StringTokenizer::size() const {
00130 return myStarts.size();
00131 }
00132
00133 void StringTokenizer::prepare(const std::string &tosplit, const std::string &token, bool splitAtAllChars) {
00134 size_t beg = 0;
00135 size_t len = token.length();
00136 if (splitAtAllChars) {
00137 len = 1;
00138 }
00139 while (beg<tosplit.length()) {
00140 size_t end;
00141 if (splitAtAllChars) {
00142 end = tosplit.find_first_of(token, beg);
00143 } else {
00144 end = tosplit.find(token, beg);
00145 }
00146 if (end == std::string::npos) {
00147 end = tosplit.length();
00148 }
00149 myStarts.push_back(beg);
00150 myLengths.push_back(end-beg);
00151 beg = end + len;
00152 if (beg==tosplit.length()) {
00153 myStarts.push_back(beg-1);
00154 myLengths.push_back(0);
00155 }
00156 }
00157 }
00158
00159 void StringTokenizer::prepareWhitechar(const std::string &tosplit) {
00160 size_t len = tosplit.length();
00161 size_t beg = 0;
00162 while (beg<len&&tosplit[beg]<=32) {
00163 beg++;
00164 }
00165 while (beg!=std::string::npos&&beg<len) {
00166 size_t end = beg;
00167 while (end<len&&tosplit[end]>32) {
00168 end++;
00169 }
00170 myStarts.push_back(beg);
00171 myLengths.push_back(end-beg);
00172 beg = end;
00173 while (beg<len&&tosplit[beg]<=32) {
00174 beg++;
00175 }
00176 }
00177 }
00178
00179 std::vector<std::string>
00180 StringTokenizer::getVector() {
00181 std::vector<std::string> ret;
00182 ret.reserve(size());
00183 while (hasNext()) {
00184 ret.push_back(next());
00185 }
00186 reinit();
00187 return ret;
00188 }
00189
00190
00191
00192
00193