Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1599)

Unified Diff: chrome/install_static/install_util.cc

Issue 2017853002: Add functionality to the install_static library to tokenize strings and compare versions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix windows gn builder redness Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/install_static/install_util.cc
diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc
index 2a8f83aed0707aadd9d629a91d4dcc206de98117..57aa7a0b25c2a662d9a78ea40158bc9e02f1ad14 100644
--- a/chrome/install_static/install_util.cc
+++ b/chrome/install_static/install_util.cc
@@ -7,7 +7,10 @@
#include <windows.h>
#include <assert.h>
#include <algorithm>
+#include <iostream>
+#include <iterator>
#include <memory>
+#include <sstream>
#include "base/macros.h"
#include "build/build_config.h"
@@ -255,41 +258,6 @@ base::string16 GetCurrentProcessExePath() {
return exe_path;
}
-// UTF8 to UTF16 and vice versa conversion helpers. We cannot use the base
-// string conversion utilities here as they bring about a dependency on
-// user32.dll which is not allowed in this file.
-
-// Convert a UTF16 string to an UTF8 string.
-std::string utf16_to_utf8(const base::string16 &source) {
- if (source.empty())
- return std::string();
- int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
- static_cast<int>(source.size()), nullptr, 0, nullptr, nullptr);
- std::string result(size, '\0');
- if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
- static_cast<int>(source.size()), &result[0], size, nullptr,
- nullptr) != size) {
- assert(false);
- return std::string();
- }
- return result;
-}
-
-// Convert a UTF8 string to a UTF16 string.
-base::string16 utf8_to_string16(const std::string &source) {
- if (source.empty())
- return base::string16();
- int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
- static_cast<int>(source.size()), nullptr, 0);
- base::string16 result(size, L'\0');
- if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
- static_cast<int>(source.size()), &result[0], size) != size) {
- assert(false);
- return base::string16();
- }
- return result;
-}
-
bool RecursiveDirectoryCreate(const base::string16& full_path) {
// If the path exists, we've succeeded if it's a directory, failed otherwise.
const wchar_t* full_path_str = full_path.c_str();
@@ -419,6 +387,29 @@ bool MatchPatternImpl(const base::string16& source,
return false;
}
+// Defines the type of whitespace characters typically found in strings.
+const char kWhiteSpaces[] = " \t\n\r\f\v";
grt (UTC plus 2) 2016/05/27 14:13:20 nit: constexpr
ananta 2016/05/27 20:05:25 Done.
+
+// Trim whitespaces from left.
+void ltrim(std::string* str) {
+ str->erase(0, str->find_first_not_of(kWhiteSpaces));
+}
+
+// Trim whitespaces from right
+void rtrim(std::string* str) {
+ str->erase(str->find_last_not_of(kWhiteSpaces) + 1);
+}
+
+// Trim whitespaces from left & right
+void trim(std::string* str) {
scottmg 2016/05/27 17:27:22 trim -> Trim
ananta 2016/05/27 20:05:25 Done.
+ rtrim(str);
scottmg 2016/05/27 17:27:22 Seems like over-functioning since ltrim() and rtri
ananta 2016/05/27 20:05:25 Done.
+ ltrim(str);
+}
+
+bool is_valid_number(const std::string &str) {
scottmg 2016/05/27 17:27:22 IsValidNumber
ananta 2016/05/27 20:05:25 Done.
+ return std::all_of(str.begin(), str.end(), ::isdigit);
grt (UTC plus 2) 2016/05/27 14:13:20 as implemented, this will return true if std.empty
ananta 2016/05/27 20:05:25 Done.
+}
+
} // namespace
bool IsSxSChrome(const wchar_t* exe_path) {
@@ -576,23 +567,23 @@ bool GetDefaultCrashDumpLocation(base::string16* crash_dir) {
std::string GetEnvironmentString(const std::string& variable_name) {
DWORD value_length = ::GetEnvironmentVariable(
- utf8_to_string16(variable_name).c_str(), NULL, 0);
+ utf8_to_utf16(variable_name).c_str(), NULL, 0);
if (value_length == 0)
return std::string();
std::unique_ptr<wchar_t[]> value(new wchar_t[value_length]);
- ::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
+ ::GetEnvironmentVariable(utf8_to_utf16(variable_name).c_str(),
value.get(), value_length);
return utf16_to_utf8(value.get());
}
bool SetEnvironmentString(const std::string& variable_name,
const std::string& new_value) {
- return !!SetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
- utf8_to_string16(new_value).c_str());
+ return !!SetEnvironmentVariable(utf8_to_utf16(variable_name).c_str(),
+ utf8_to_utf16(new_value).c_str());
}
bool HasEnvironmentVariable(const std::string& variable_name) {
- return !!::GetEnvironmentVariable(utf8_to_string16(variable_name).c_str(),
+ return !!::GetEnvironmentVariable(utf8_to_utf16(variable_name).c_str(),
NULL, 0);
}
@@ -743,4 +734,123 @@ bool MatchPattern(const base::string16& source,
return MatchPatternImpl(source, pattern, 0, 0);
}
+std::string utf16_to_utf8(const base::string16 &source) {
grt (UTC plus 2) 2016/05/27 14:13:20 nit: & before space. please use "git cl format" t
ananta 2016/05/27 20:05:25 Yeah. I had done that. It seems every time I copy
+ if (source.empty())
grt (UTC plus 2) 2016/05/27 14:13:20 || source.size() > std::numeric_limits<int>::max()
ananta 2016/05/27 20:05:25 Done.
+ return std::string();
+ int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), nullptr, 0, nullptr, nullptr);
+ std::string result(size, '\0');
+ if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), &result[0], size, nullptr,
+ nullptr) != size) {
+ assert(false);
+ return std::string();
+ }
+ return result;
+}
+
+base::string16 utf8_to_utf16(const std::string &source) {
+ if (source.empty())
grt (UTC plus 2) 2016/05/27 14:13:20 || source.size() > std::numeric_limits<int>::max()
ananta 2016/05/27 20:05:25 Done.
+ return base::string16();
+ int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), nullptr, 0);
+ base::string16 result(size, L'\0');
+ if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+ static_cast<int>(source.size()), &result[0], size) != size) {
+ assert(false);
+ return base::string16();
+ }
+ return result;
+}
+
+std::vector<std::string> TokenizeString(const std::string& str,
+ const char delimiter,
grt (UTC plus 2) 2016/05/27 14:13:20 no const
ananta 2016/05/27 20:05:25 Done.
+ bool trim_spaces) {
scottmg 2016/05/27 17:27:22 I only see trim_spaces=false calls other than in t
ananta 2016/05/27 20:05:25 Prefer to leave it as an argument. Just in case we
+ std::vector<std::string> tokens;
+ std::istringstream buffer(str);
+ for (std::string token; std::getline(buffer, token, delimiter); ) {
+ if (trim_spaces)
+ trim(&token);
+ tokens.push_back(token);
+ }
+ return tokens;
+}
+
+bool CompareVersionStrings(const std::string& version1,
+ const std::string& version2,
+ int* result) {
+ if (version1.empty() || version2.empty())
+ return false;
+
+ // Tokenize both version strings with "." as the separator. If either of
+ // the returned token lists are empty then bail.
+ std::vector<std::string> version1_components =
+ install_static::TokenizeString(version1, '.', false);
grt (UTC plus 2) 2016/05/27 14:13:20 omit "install_static::"
ananta 2016/05/27 20:05:25 Done.
+ if (version1_components.empty())
+ return false;
+
+ std::vector<std::string> version2_components =
+ install_static::TokenizeString(version2, '.', false);
+ if (version2_components.empty())
+ return false;
+
+ // You may have less tokens in either string. Use the minimum of the number
+ // of tokens as the initial count.
+ const size_t count = std::min(version1_components.size(),
scottmg 2016/05/27 17:27:22 nit; weird line break
ananta 2016/05/27 20:05:25 Done.
+ version2_components.size());
+ for (size_t i = 0; i < count; ++i) {
+ // If either of the version components don't contain valid numeric digits
+ // bail.
+ if (!is_valid_number(version1_components[i]) ||
+ !is_valid_number(version2_components[i])) {
+ return false;
+ }
+
+ int version1_component = std::stoi(version1_components[i]);
scottmg 2016/05/27 17:27:22 Ooh, this defaults to base=10, not =0, woohoo!
ananta 2016/05/27 20:05:25 Yeah
+ int version2_component = std::stoi(version2_components[i]);
+
+ if (version1_component > version2_component) {
+ *result = 1;
+ return true;
+ }
+
+ if (version1_component < version2_component) {
+ *result = -1;
+ return true;
+ }
+ }
+
+ // Handle remaining tokens. Here if we have non zero tokens remaining in the
+ // version 1 list then it means that the version1 string is larger. If the
+ // version 1 token list has tokens left, then if either of these tokens is
+ // greater than 0 then it means that the version1 string is smaller than the
+ // version2 string.
+ if (version1_components.size() > version2_components.size()) {
+ for (size_t i = count; i < version1_components.size(); ++i) {
+ // If the version components don't contain valid numeric digits bail.
+ if (!is_valid_number(version1_components[i]))
+ return false;
+
+ if (std::stoi(version1_components[i]) > 0) {
+ *result = 1;
+ return true;
+ }
+ }
+ } else if (version1_components.size() < version2_components.size()) {
+ for (size_t i = count; i < version2_components.size(); ++i) {
+ // If the version components don't contain valid numeric digits bail.
+ if (!is_valid_number(version2_components[i]))
+ return false;
+
+ if (std::stoi(version2_components[i]) > 0) {
+ *result = -1;
+ return true;
+ }
+ }
+ }
+ // Here it means that both versions are equal.
+ *result = 0;
+ return true;
+}
+
} // namespace install_static

Powered by Google App Engine
This is Rietveld 408576698