Пример #1
0
BOOL install_util::CreateLnkPath(std::wstring wsSourceFilePath, std::wstring wsDestLnkPath, std::wstring wsArgument, std::wstring wsAppId)
{
  IShellLink *pisl = NULL;
  HRESULT hr = CoCreateInstance(CLSID_ShellLink,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IShellLink,
    (void**)&pisl);
  if (FAILED(hr))
  {
    return FALSE;
  }

  pisl->SetPath(wsSourceFilePath.c_str());
  pisl->SetArguments(wsArgument.c_str());
  int nStart = wsSourceFilePath.find_last_of(_T("/\\")); 
  pisl->SetWorkingDirectory(wsSourceFilePath.substr(0,nStart).c_str());
  IPersistFile *plPF = NULL; 
  hr = pisl->QueryInterface(IID_IPersistFile, (void**)&plPF);
  bool shortcut_existed = false;
  if (SUCCEEDED(hr))
  {
    if (PathExists(wsDestLnkPath))
    {
      shortcut_existed = true;
      install_util::DeleteFile(wsDestLnkPath.c_str());
    }
	if (Win7OrLater() && !wsAppId.empty() && wsAppId.length() < 64)
	{
		IPropertyStore *piPS = NULL;
		if (SUCCEEDED(pisl->QueryInterface(IID_IPropertyStore, (void**)&piPS)))
		{
			PROPVARIANT property_value;
			if (SUCCEEDED(InitPropVariantFromString(wsAppId.c_str(), &property_value)))
			{
				if (piPS->SetValue(PKEY_AppUserModel_ID, property_value) == S_OK)
					piPS->Commit();
				PropVariantClear(&property_value);
			}
			piPS->Release();
		}
	}

    hr = plPF->Save(wsDestLnkPath.c_str(), TRUE);
    plPF->Release();
  }

  pisl->Release();
  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

  return SUCCEEDED(hr);
}
Пример #2
0
static std::list<std::wstring> _TokenizeString(const std::wstring& str, const wchar_t* delims) {
    std::list<std::wstring> components;

    std::size_t start = 0; // start from 0
    std::size_t delimPos = str.find_first_of(delims);

    while (start != std::wstring::npos) {
        components.emplace_back(str.substr(start, delimPos - start));
        start = str.find_first_not_of(delims, delimPos);
        delimPos = str.find_first_of(delims, start);
    }
    return components;
}
Пример #3
0
bool
MSCalibrationForm::parse_formula( const std::wstring& text, std::wstring& formula
							, std::wstring& adduct_lose, bool& isPositive ) const
{
    adduct_lose.clear();

    std::wstring::size_type pos = text.find_first_of( L"+-" );
    if ( pos == std::wstring::npos ) {
        formula = text;
        return !formula.empty();
    } else {
		formula = text.substr( 0, pos);
		if ( text.at( pos ) == L'+' )
			isPositive = true;
		else if ( text.at( pos ) == L'-' )
			isPositive = false;
		else
			return false;
		adduct_lose = text.substr( pos + 1 );
	}
    return true;
}
Пример #4
0
//------------------------------------------------------------------------|
void MGUtils::StringSplit(std::wstring& str, std::wstring& delim, std::vector<std::wstring>& result)
{
	int start = 0;
	int end = str.find_first_of(delim);
	if(end != -1)
	{
		while(end != -1)
		{
			result.push_back(str.substr(start, end - start));
			start = end + 1;
			end = str.find_first_of(delim, start);
			if(end == -1)
			{
				result.push_back(str.substr(start));
			}
		}
	}
	else
	{
		result.push_back(str.substr(start));
	}
}
Пример #5
0
// Strips the filename and leaves the path
std::wstring CInjector::StripFile(std::wstring filePath)
{
	int pos = -1;
	for (int k = 0; k < filePath.length(); k++)
		if (filePath[k] == L'\\')
			pos = k;

	if (pos != -1) {
		return filePath.substr(0, pos+1);
	} else {
		return L"";
	}
}
Пример #6
0
void DevelopmentResourceZipFile::ReadAssetsDirectory(std::wstring fileSpec)
{
      HANDLE fileHandle;
      WIN32_FIND_DATA findData;
 
      // get first file
	  std::wstring pathSpec = m_AssetsDir + fileSpec;
      fileHandle = FindFirstFile( pathSpec.c_str(), &findData );
      if( fileHandle != INVALID_HANDLE_VALUE )
      {
           // loop on all remeaining entries in dir
            while( FindNextFile( fileHandle,&findData ) )
            {
				if (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
					continue;

				std::wstring fileName = findData.cFileName; 
				if( findData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY )
				{
					if (fileName != L".." && fileName != L".")
					{
						fileName = fileSpec.substr(0, fileSpec.length()-1) + fileName + L"\\*";
						ReadAssetsDirectory(fileName);
					}
				}
				else
				{
					fileName = fileSpec.substr(0, fileSpec.length()-1) + fileName;
					std::wstring lower = fileName;
					std::transform(lower.begin(), lower.end(), lower.begin(), (int(*)(int)) std::tolower);
					wcscpy_s(&findData.cFileName[0], MAX_PATH, lower.c_str());
					m_DirectoryContentsMap[ws2s(lower)] = m_AssetFileInfo.size();
					m_AssetFileInfo.push_back(findData);
				} 
            }
      } 

      FindClose( fileHandle );
}
Пример #7
0
// Extends the length limit from 260 to 32767 characters
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#maxpath
std::wstring GetExtendedLengthPath(const std::wstring& path) {
  const std::wstring prefix = L"\\\\?\\";

  if (StartsWith(path, prefix))
    return path;

  // "\\computer\path" -> "\\?\UNC\computer\path"
  if (StartsWith(path, L"\\\\"))
    return prefix + L"UNC\\" + path.substr(2);

  // "C:\path" -> "\\?\C:\path"
  return prefix + path;
}
Пример #8
0
static std::wstring cleaningYomiForWord(const std::wstring& yomi,const std::wstring& word)
{
	int pos = yomi.find(word);
	if (pos != std::wstring::npos)
	{
		if (pos == 0)
		{
			return L"";
		}
		return yomi.substr(0,pos);
	}
	return yomi;
}
Пример #9
0
void ChatBackend::addUnparsedMessage(std::wstring message)
{
	// TODO: Remove the need to parse chat messages client-side, by sending
	// separate name and text fields in TOCLIENT_CHAT_MESSAGE.

	if (message.size() >= 2 && message[0] == L'<')
	{
		std::size_t closing = message.find_first_of(L'>', 1);
		if (closing != std::wstring::npos &&
				closing + 2 <= message.size() &&
				message[closing+1] == L' ')
		{
			std::wstring name = message.substr(1, closing - 1);
			std::wstring text = message.substr(closing + 2);
			addMessage(name, text);
			return;
		}
	}

	// Unable to parse, probably a server message.
	addMessage(L"", message);
}
Пример #10
0
		std::vector<std::wstring> split(const std::wstring& str, const std::wstring& sep)
		{
			std::vector<std::wstring> ret;
			for (size_t pos = 0; pos <= str.size();)
			{
				size_t new_pos = str.find(sep, pos);
				if (std::string::npos == new_pos)
					new_pos = str.size();
				ret.push_back(str.substr(pos, new_pos - pos));
				pos = new_pos + sep.size();
			}
			return ret;
		}
Пример #11
0
/**
 * Split a string into elements as a newly created arrayBuffer
 * @param inBuf The CharArray to split along
 * @param splitChar The char to use as splitter
 * @param &argLen [OUT] The length of the Array
 * @param escape [IN] Set to true to try to escape ":s ie. //token1 "token2 with space" token3//
 * @return The arrayBuffer
 */
array_buffer::arrayBuffer array_buffer::split2arrayBuffer(const std::wstring inBuf, wchar_t splitChar, unsigned int &argLen, bool escape) {
	if (inBuf.empty())
		return createEmptyArrayBuffer(argLen);

	std::wstring::size_type p1 = 0;
	std::wstring::size_type p2 = 0;
	std::list<std::wstring> token_list;
	while (p1 != std::wstring::npos && p2 != std::wstring::npos) {
		if (escape && inBuf[p1] == '\"') {
			p2 = inBuf.find('\"', p1+1);
			if (p2 != std::wstring::npos)
				p2 = inBuf.find(splitChar, p2);
		} else {
			p2 = inBuf.find(splitChar, p1);
		}
		if (p2 == std::wstring::npos)
			p2 = inBuf.size();
		if (p1 == p2 && p1 != inBuf.size()) {
			p1++;
			continue;
		}
		// p1 = start of "this token"
		// p2 = end of "this token" (next split char)

		if (p2<=p1)
			throw ArrayBufferException("Invalid position");
		std::wstring token = inBuf.substr(p1,p2-p1);
		if (escape && token[0] == '\"')
			token = token.substr(1);
		if (escape && token[token.size()-1] == '\"')
			token = token.substr(0, token.size()-1);


		token_list.push_back(token);
		if (p2 < inBuf.size())
			p2++;
		if (p2 == inBuf.size())
			p2 = std::wstring::npos;
		p1 = p2;
	}
	arrayBuffer arrayBuffer = new arrayBufferItem[token_list.size()];
	argLen=0;
	for (std::list<std::wstring>::const_iterator cit=token_list.begin();cit!=token_list.end();++cit) {
		size_t len = (*cit).size();
		wchar_t* token = new wchar_t[len+1];
		wcsncpy(token, (*cit).c_str(), len);
		arrayBuffer[argLen++] = token;
	}
	token_list.clear();
	return arrayBuffer;
}
Пример #12
0
bool XmlEncode(std::wstring& data, int nMaxCount)
{
    if ((int)data.size() > nMaxCount)
    {
        data = data.substr(0, nMaxCount);
    }

    size_t nCount = 0;
    std::wstring buffer;
    buffer.reserve(data.size());
    for (size_t pos = 0; pos != data.size(); ++pos)
    {
        if (data[pos] == L'\n' || data[pos] == L'\r')
        {
            nCount = pos;
            break;
        }
        else if (data[pos] == L'&')
        {
            buffer.append(L"&amp;");
        }
        else if (data[pos] == L'\"')
        {
            buffer.append(L"&quot;");
        }
        else if (data[pos] == L'\'')
        {
            buffer.append(L"&apos;");
        }
        else if (data[pos] == L'<')
        {
            buffer.append(L"&lt;");
        }
        else if (data[pos] == L'>')
        {
            buffer.append(L"&gt;");
        }
        else if (data[pos] == L'\\')
        {
            buffer.append(L"\\\\");
        }
        else
        {
            buffer.append(&data[pos], 1);
        }
    }

    data.swap(buffer);

    return nCount > 0;
}
Пример #13
0
bool UIniConfig::splitSectionAndKey( std::wstring &formattedKey, wstring &sectionName, wstring &keyName )
{
    size_t slashIndex = formattedKey.find('/');
    if(slashIndex == wstring::npos)
    {
        //没有找到'/',sectionName为general。
        sectionName = L"";
        keyName = formattedKey;
    }
    else if(slashIndex == formattedKey.size()-1 || slashIndex == 0)
    {
        //假如第一个'/'出现在key的第一个字符或最后一个字符,则认为格式错误。
        assert(!"UConfig::set 键名格式错误,'/'不能为key的第一个或最后一个字符。");
        return false;
    }
    else
    {
        sectionName = formattedKey.substr(0,slashIndex);
        keyName = formattedKey.substr(slashIndex+1);
    }

    return true;
}
Пример #14
0
/// <summary>
/// Get filename from full-qualified path
/// </summary>
/// <param name="path">File path</param>
/// <returns>Filename</returns>
std::wstring Utils::StripPath( const std::wstring& path )
{
    if (path.empty())
        return path;

    auto idx = path.rfind( L'\\' );
    if(idx == path.npos)
        idx = path.rfind( L'/' );

    if (idx != path.npos)
        return path.substr( idx + 1 );
    else
        return path;
}
Пример #15
0
std::vector<std::wstring> plLocalization::StringToLocal(const std::wstring & localizedText)
{
    std::vector<std::wstring> tags;
    std::vector<int> tagLocs;
    std::vector<int> sortedTagLocs;
    std::vector<std::wstring> retVal;
    int i;
    for (i=0; i<kNumLanguages; i++)
    {
        std::wstring tag = L"$";
        std::string temp = GetLanguageName((Language)i);
        wchar_t *wTemp = hsStringToWString(temp.c_str());
        std::wstring langName = wTemp;
        delete [] wTemp;
        
        tag += langName.substr(0,2) + L"$";
        tags.push_back(tag);
        tagLocs.push_back(localizedText.find(tag));
        sortedTagLocs.push_back(i);
        retVal.push_back(L"");
    }
    for (i=0; i<kNumLanguages-1; i++)
    {
        for (int j=i; j<kNumLanguages; j++)
        {
            if (tagLocs[sortedTagLocs[i]] > tagLocs[sortedTagLocs[j]])
                sortedTagLocs[i]^=sortedTagLocs[j]^=sortedTagLocs[i]^=sortedTagLocs[j]; // swap the contents (yes, it works)
        }
    }
    // now sortedTagLocs has the indexes of tagLocs sorted from smallest loc to highest loc
    bool noTags = true;
    for (i=0; i<kNumLanguages; i++)
    {
        int lang = sortedTagLocs[i]; // the language we are extracting
        if (tagLocs[lang] != -1)
        {
            noTags = false; // at least one tag was found in the text
            int startLoc = tagLocs[lang] + tags[lang].length();
            int endLoc;
            if (i+1 == kNumLanguages)
                endLoc = localizedText.length();
            else
                endLoc = tagLocs[sortedTagLocs[i+1]];
            retVal[lang] = localizedText.substr(startLoc,endLoc-startLoc);
        }
    }
    if (noTags)
        retVal[0] = localizedText; // if no tags were in the text, we assume it to be English
    return retVal;
}
Пример #16
0
bool ObjectImporter::Import(std::wstring file, ImportedObjectData* rawData)
{
	size_t first = file.find_last_of('\\') + 1;
	size_t last = file.find_last_of('.');
	rawData->name = file.substr(first, last-first);
	

	std::wifstream in (file);
	if(!in.is_open())
	{
		std::wstring msg = L"Failed to open file: \n";
		msg.append(file);
		MessageBox(0, msg.c_str(), L"Import error", 0);
		return false;
	}
	else
	{
		std::wstring buff;

		while (!in.eof())
		{
			in >> buff;

			if(buff.size())
			{
				if(buff == ObjImpFormat::animationCount) 
				{ 
					int count = 0;
					if(!ParseInteger(in, count))
						return false;

					if(count)
					{
						rawData->animations.resize(count);
						if(!ParseAnimationFile(in, rawData))
							return false;
					}
					else		
						if(!ParseStandardFile(in, rawData))
							return false;
				}
				else { ParseLine(in, true); }
			}
		}

		in.close();
	}

	return true;
}
Пример #17
0
std::wstring TextureClass::GetExtension(const std::wstring& filename)
{
	std::string::size_type idx;

	idx = filename.rfind('.');

	if (idx != std::wstring::npos)
	{
		return filename.substr(idx + 1);
	}

	return L"";

}
Пример #18
0
std::wstring getFolderNameFromPath(const std::wstring& src)
{
#ifdef _WIN32
	size_t s = src.find_last_of(L"\\/");
#else
	size_t s = src.rfind(L"/");
#endif
	if (s == std::wstring::npos)
	{
		return L".";
	}

	return src.substr(0,s);
}
Пример #19
0
// Strips ignored characters
std::wstring strip(std::wstring token)
{
	std::wstring out;
	
	unsigned int start = 0;
	unsigned int end = 0;
	
	bool start_set = false;
	
	// Go through the token to find the real start and end points
	for(unsigned int i = 0; i < token.length(); i++)
	{
		// Determine whether or not a character is ignored
		bool in_ign = false;
		for(unsigned int j = 0; j < ign.size(); j++)
		{
			// in_ign will be true if any of the characters in the vector ign matches the current character
			in_ign = ( (token[i] == ign[j]) || in_ign );
		}
		
		// Set starting and ending points
		if(!start_set)
		{
			// The first character that is not in the ignore list is the real start
			if(!in_ign)
			{
				start = i;
				end = start;
				start_set = true;
			}
		}
		else
		{
			// Then find the end point
			if(!in_ign)
			{
				end = i;
			}
		}
	}
	// Evaluate output
	if(!start_set)
	{
		return L"";
	}
	else
	{
		return token.substr(start, end - start + 1);
	}
};
Пример #20
0
/// <summary>
/// Get parent directory
/// </summary>
/// <param name="path">File path</param>
/// <returns>Parent directory</returns>
std::wstring Utils::GetParent( const std::wstring& path )
{
    if (path.empty())
        return path;

    auto idx = path.rfind( L'\\' );
    if (idx == path.npos)
        idx = path.rfind( L'/' );

    if (idx != path.npos)
        return path.substr( 0, idx );
    else
        return path;
}
Пример #21
0
std::vector<std::wstring> getuLines(const std::wstring& str){
    std::vector<std::wstring> ret;
    bool curnew = false;int cnstart=-1;int curline = 0;int startpos=0;
    wchar_t lastchar = NULL; //may want to initialize to a different value using a different container size
    for(unsigned int a = 0; a < str.size(); a++){
        if (str[a]=='\r' || str[a]=='\n'){
            if (lastchar == '\r' && str[a]=='\n'){
                //ignore this one
            }
            else{
                ret.push_back(str.substr(startpos,a-startpos));
                curline++;
            }
            startpos = a + 1;
        }
        else if (a==str.size()-1){
            ret.push_back(str.substr(startpos,str.size()-startpos+1));
        }
        lastchar = str[a];
    }

    return ret;
}
Пример #22
0
std::wstring SaveManager::getFileNameFromPath(const std::wstring& path)
{
	size_t pos = path.rfind(L'\\');
	if (pos != path.npos)
	{
		pos += 1;
		return path.substr(pos);
	}
	else
	{
		SDLOG(0, "ERROR: SaveManager could not extract file name from path %ls", path.c_str());
	}
	return path;
}
Пример #23
0
BOOL CSVPRarLib::SplitPath_STL(std::wstring fnSVPRarPath)
{
  std::wstring fnSVPExt = fnSVPRarPath.substr(0, 6);
  std::transform(fnSVPExt.begin(), fnSVPExt.end(), fnSVPExt.begin(), tolower);
  m_bIsRAR = (fnSVPExt == L"rar://");
  //SVP_LogMsg5(L"CAsyncFileReader File %s" , fn);
  BOOL ret = false;
  if(m_bIsRAR)
    //SVP_LogMsg5(L"This is RAR File %s" , fn);
  {
    //		SVP_LogMsg5(_T("rar library loaded"));
    int iPos = fnSVPRarPath.find('?');
    if(iPos != fnSVPRarPath.npos)
    {
      m_fnRAR = fnSVPRarPath.substr(6, iPos - 6).c_str();
      m_fnInsideRar = fnSVPRarPath.substr(iPos + 1,
        fnSVPRarPath.size() - iPos - 1).c_str();
      ret = true;
    }
  }

  return ret;
}
Пример #24
0
// from string to list of directories
void Path::parse_path (const std::wstring& pathStr)
{
  std::wstring::size_type from = 0;

  bool firstIsDrive = has_drive_letter ();

  while (from < pathStr.length ())
  {
    std::wstring::size_type pos = 
      pathStr.find_first_of (L"\\:", from);

    if (pos == std::wstring::npos)
    {
      path.push_back 
          (pathStr.substr (from, pathStr.length () - from));
      return;
    }

    if (from == pos) { from++; continue; } // ":\\"

    // FIXME check only one ':' in a path above
    if (pos > 0)
    {
      if (firstIsDrive)
      {
        std::wstring driveLetter = pathStr.substr 
          (from, pos - from);
        assert (driveLetter.length () == 1);
        drive = std::tolower (driveLetter.at (0), loc);
        firstIsDrive = false;
      }
      else
         path.push_back (pathStr.substr (from, pos - from));
      from = pos + 1;
    }
  }
}
Пример #25
0
// Functions of HTMLParsr
void HTMLParser::FindTag( const std::wstring& rHtml, const std::wstring& rTag, const std::map< std::wstring, boost::optional<std::wstring> >& rAttribute, size_t uStartPos )
{
	std::wstring	sTagBegin	= L"<" + rTag,
					sTagEnd		= L"</" + rTag + L">";
	
	// find the position of tag
	size_t uPos1 = rHtml.find( sTagBegin, uStartPos );
	if( uPos1 == std::string::npos )
	{
		return;
	}
	
	// find the end of the start tag
	size_t uPos2 = rHtml.find( L">", uPos1 + sTagBegin.length() );
	if( uPos2 == std::string::npos )
	{
		return;
	}

	if( rAttribute.size() > 0 )
	{
		// get attributes
		std::wstring sAttributes = rHtml.substr( uPos1 + sTagBegin.length(), uPos2 - ( uPos1 + sTagBegin.length() ) );

		// TODO: check attribute
	}

	// TODO: check nested tag?

	// find close tag
	size_t uPos3 = rHtml.find( sTagEnd, uPos2 + 1 );
	if( uPos3 != std::string::npos )
	{
		std::wstring sContent = rHtml.substr( uPos2 + 1, uPos3 - uPos2 - 1 );
	}
}
Пример #26
0
void readRealList( const std::wstring& str, std::vector<double>& vec )
{
	const wchar_t* ch = str.c_str();
	const size_t argsize = str.size();
	if( argsize == 0 )
	{
		return;
	}
	size_t i=0;
	size_t last_token = 0;
	while( i<argsize )
	{
		if( ch[i] == '(' )
		{
			++i;
			last_token = i;
			break;
		}
		++i;
	}

	while( i<argsize )
	{
		if( ch[i] == ',' )
		{
			vec.push_back( std::stod( str.substr( last_token, i-last_token ).c_str() ) );
			last_token = i+1;
		}
		else if( ch[i] == ')' )
		{
			vec.push_back( std::stod( str.substr( last_token, i-last_token ).c_str() ) );
			return;
		}
		++i;
	}
}
Пример #27
0
static std::wstring RemoveStringByDELETE(const std::wstring& str, int& spos, int& epos)
{
	_ASSERT(spos <= (int) str.length());

	int acp = spos;
	int len = str.length();

	if (acp < len)
	{
		int rmlen = max(1, epos - spos);

		auto s1 = str.substr(0, acp);

		if (0 < (len - (acp + rmlen)))
		{
			auto s2 = str.substr(acp + rmlen, (len - (acp + rmlen)));
			s1 += s2;
		}

		epos = spos;
		return s1;
	}
	return str;
}
Пример #28
0
std::wstring GetFilePath( const std::wstring& wsFullName )
{
	std::wstring::size_type nIndex1 = wsFullName.find_last_of(L"\\");
	std::wstring::size_type nIndex2 = wsFullName.find_last_of(L"/");
	if (std::wstring::npos == nIndex1)
	{
		nIndex1 = 0;
	}
	if (std::wstring::npos == nIndex2)
	{
		nIndex2 = 0;
	}
	std::wstring::size_type nIndex = max(nIndex1, nIndex2);
	return wsFullName.substr(0, nIndex);
}
Пример #29
0
bool CServerPath::Segmentize(std::wstring const& str, tSegmentList& segments)
{
	bool append = false;
	size_t start = 0;

	size_t pos;
	while (true) {
		pos = str.find_first_of(traits[m_type].separators, start);
		if (pos == std::string::npos) {
			break;
		}
		if (start == pos) {
			++start;
			continue;
		}

		std::wstring segment = str.substr(start, pos - start);
		start = pos + 1;

		if (!SegmentizeAddSegment(segment, segments, append)) {
			return false;
		}
	}

	if (start < str.size()) {
		std::wstring segment = str.substr(start);
		if (!SegmentizeAddSegment(segment, segments, append)) {
			return false;
		}
	}

	if (append)
		return false;

	return true;
}
Пример #30
0
std::vector<std::wstring> utils::wtokenize(const std::wstring& str, std::wstring delimiters) {
	/*
	 * This function tokenizes a string by the delimiters. Plain and simple.
	 */
	std::vector<std::wstring> tokens;
	std::wstring::size_type last_pos = str.find_first_not_of(delimiters, 0);
	std::wstring::size_type pos = str.find_first_of(delimiters, last_pos);

	while (std::string::npos != pos || std::string::npos != last_pos) {
		tokens.push_back(str.substr(last_pos, pos - last_pos));
		last_pos = str.find_first_not_of(delimiters, pos);
		pos = str.find_first_of(delimiters, last_pos);
	}
	return tokens;
}