FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

/* * StringUtils.cpp * * Copyright (C) 2009-17 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include #endif #ifndef CP_ACP # define CP_ACP 0 #endif namespace rstudio { namespace core { namespace string_utils { bool isSubsequence(std::string const& self, std::string const& other, std::string::size_type other_n) { std::string::size_type self_n = self.length(); if (other_n == 0) return true; if (other_n > other.length()) other_n = other.length(); if (other_n > self_n) return false; std::string::size_type self_idx = 0; std::string::size_type other_idx = 0; while (self_idx < self_n) { char selfChar = self[self_idx]; char otherChar = other[other_idx]; if (otherChar == selfChar) { ++other_idx; if (other_idx == other_n) { return true; } } ++self_idx; } return false; } bool isSubsequence(std::string const& self, std::string const& other, std::string::size_type other_n, bool caseInsensitive) { return caseInsensitive ? isSubsequence(boost::algorithm::to_lower_copy(self), boost::algorithm::to_lower_copy(other), other_n) : isSubsequence(self, other, other_n) ; } bool isSubsequence(std::string const& self, std::string const& other) { return isSubsequence(self, other, other.length()); } bool isSubsequence(std::string const& self, std::string const& other, bool caseInsensitive) { return isSubsequence(self, other, other.length(), caseInsensitive); } std::vector subsequenceIndices(std::string const& sequence, std::string const& query) { std::string::size_type querySize = query.length(); std::vector result; result.reserve(querySize); std::string::size_type prevMatchIndex = -1; for (std::string::size_type i = 0; i < querySize; i++) { std::string::size_type index = sequence.find(query[i], prevMatchIndex + 1); if (index == std::string::npos) continue; result.push_back(index); prevMatchIndex = index; } return result; } bool subsequenceIndices(std::string const& sequence, std::string const& query, std::vector *pIndices) { pIndices->clear(); pIndices->reserve(query.length()); int query_n = query.length(); int prevMatchIndex = -1; for (int i = 0; i < query_n; i++) { int index = sequence.find(query[i], prevMatchIndex + 1); if (index == -1) return false; pIndices->push_back(index); prevMatchIndex = index; } return true; } std::string getExtension(std::string const& x) { std::size_t lastDotIndex = x.rfind('.'); if (lastDotIndex != std::string::npos) return x.substr(lastDotIndex); else return std::string(); } void convertLineEndings(std::string* pStr, LineEnding type) { std::string replacement; switch (type) { case LineEndingWindows: replacement = "\r\n"; break; case LineEndingPosix: replacement = "\n"; break; case LineEndingNative: #if _WIN32 replacement = "\r\n"; #else replacement = "\n"; #endif break; case LineEndingPassthrough: default: return; } *pStr = boost::regex_replace(*pStr, boost::regex("\\r?\\n|\\r|\\xE2\\x80[\\xA8\\xA9]"), replacement); } bool detectLineEndings(const FilePath& filePath, LineEnding* pType) { if (!filePath.exists()) return false; boost::shared_ptr pIfs; Error error = filePath.open_r(&pIfs); if (error) { LOG_ERROR(error); return false; } // read file character-by-character using a streambuf try { std::istream::sentry se(*pIfs, true); std::streambuf* sb = pIfs->rdbuf(); while(true) { int ch = sb->sbumpc(); if (ch == '\n') { // using posix line endings *pType = string_utils::LineEndingPosix; return true; } else if (ch == '\r' && sb->sgetc() == '\n') { // using windows line endings *pType = string_utils::LineEndingWindows; return true; } else if (ch == EOF) { break; } else if (pIfs->fail()) { LOG_WARNING_MESSAGE("I/O Error reading file " + filePath.absolutePath()); break; } } } CATCH_UNEXPECTED_EXCEPTION // no detection possible (perhaps the file is empty or has only one line) return false; } std::string utf8ToSystem(const std::string& str, bool escapeInvalidChars) { if (str.empty()) return std::string(); #ifdef _WIN32 wchar_t wide[str.length() + 1]; int chars = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wide, sizeof(wide)); if (chars < 0) { LOG_ERROR(systemError(::GetLastError(), ERROR_LOCATION)); return str; } std::ostringstream output; char mbbuf[10]; // Only go up to chars - 1 because last char is \0 for (int i = 0; i < chars - 1; i++) { int mbc = wctomb(mbbuf, wide[i]); if (mbc == -1) { if (escapeInvalidChars) output at(len-1) == '"')) *pStr = pStr->substr(0, len -1); } std::string strippedOfQuotes(const std::string& string) { std::string::size_type n = string.length(); if (n < 2) return string; char first = string[0]; char last = string[n - 1]; if ((first == '\'' && last == '\'') || (first == '"' && last == '"') |\ (first == '`' && last == '`')) { return string.substr(1, n - 2); } return string; } template Iter countNewlinesImpl(Iter begin, Iter end, const U& CR, const U& LF, std::size_t* pNewlineCount) { std::size_t newlineCount = 0; Iter it = begin; Iter lastNewline = end; for (; it != end; ++it) { // Detect '\r\n' if (*it == CR) { if (it + 1 != end && *(it + 1) == LF) { lastNewline = it; ++it; ++newlineCount; continue; } } // Detect '\n' if (*it == LF) { lastNewline = it; ++newlineCount; } } *pNewlineCount = newlineCount; return lastNewline; } std::size_t countNewlines(const std::wstring& string) { std::size_t count = 0; countNewlinesImpl(string.begin(), string.end(), L'\r', L'\n', &count); return count; } std::size_t countNewlines(const std::string& string) { std::size_t count = 0; countNewlinesImpl(string.begin(), string.end(), '\r', '\n', &count); return count; } std::size_t countNewlines(std::string::iterator begin, std::string::iterator end) { std::size_t count = 0; countNewlinesImpl(begin, end, '\r', '\n', &count); return count; } std::size_t countNewlines(std::wstring::iterator begin, std::wstring::iterator end) { std::size_t count = 0; countNewlinesImpl(begin, end, '\r', '\n', &count); return count; } std::wstring::const_iterator countNewlines(std::wstring::const_iterator begin, std::wstring::const_iterator end, std::size_t* pCount) { return countNewlinesImpl(begin, end, '\r', '\n', pCount); } bool isPrefixOf(const std::string& self, const std::string& prefix) { return boost::algorithm::starts_with(self, prefix); } std::string makeRandomByteString(std::size_t n) { std::string result; result.resize(n); for (std::size_t i = 0; i < n; ++i) result[i] = (unsigned char) (::rand() % UCHAR_MAX); return result; } } // namespace string_utils } // namespace core } // namespace rstudio

Back | FazBrowse Home | New Git URL