2015-04-13 12:09:26 -04:00
|
|
|
// Licensed to the Software Freedom Conservancy (SFC) under one
|
|
|
|
|
// or more contributor license agreements. See the NOTICE file
|
|
|
|
|
// distributed with this work for additional information
|
|
|
|
|
// regarding copyright ownership. The SFC licenses this file
|
|
|
|
|
// to you under the Apache License, Version 2.0 (the "License");
|
2013-03-21 13:58:47 -04:00
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
#include "StringUtilities.h"
|
|
|
|
|
|
2013-11-07 12:27:41 -05:00
|
|
|
#define WHITESPACE " \n\r\t"
|
|
|
|
|
#define WIDE_WHITESPACE L" \n\r\t"
|
|
|
|
|
|
2013-03-21 13:58:47 -04:00
|
|
|
namespace webdriver {
|
|
|
|
|
|
|
|
|
|
StringUtilities::StringUtilities(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StringUtilities::~StringUtilities(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring StringUtilities::ToWString(const std::string& input) {
|
|
|
|
|
// Assumption: The wstring character count will be the same as the length of
|
|
|
|
|
// the string character count. Allocate the buffer with that many wchar_t items
|
|
|
|
|
// so that the first MultiByteToWideChar call will succeed most of the time as
|
|
|
|
|
// an optimization.
|
|
|
|
|
std::wstring output = L"";
|
|
|
|
|
int input_string_byte_count = static_cast<int>(input.size()) + 1;
|
|
|
|
|
int wide_string_length = input_string_byte_count;
|
|
|
|
|
std::vector<wchar_t> output_buffer(wide_string_length);
|
|
|
|
|
bool convert_failed = (0 == ::MultiByteToWideChar(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
input_string_byte_count,
|
|
|
|
|
&output_buffer[0],
|
|
|
|
|
wide_string_length));
|
|
|
|
|
if (convert_failed) {
|
|
|
|
|
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
|
|
|
// Buffer wasn't big enough. Call MultiByteToWideChar again with
|
|
|
|
|
// NULL values to determine how big the buffer should be.
|
|
|
|
|
wide_string_length = ::MultiByteToWideChar(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
input_string_byte_count,
|
|
|
|
|
NULL,
|
|
|
|
|
0);
|
|
|
|
|
output_buffer.resize(wide_string_length);
|
|
|
|
|
convert_failed = (0 == ::MultiByteToWideChar(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
input_string_byte_count,
|
|
|
|
|
&output_buffer[0],
|
|
|
|
|
wide_string_length));
|
|
|
|
|
if (!convert_failed) {
|
|
|
|
|
output = &output_buffer[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
output = &output_buffer[0];
|
|
|
|
|
}
|
2018-05-01 13:02:45 -07:00
|
|
|
|
2013-03-21 13:58:47 -04:00
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string StringUtilities::ToString(const std::wstring& input) {
|
|
|
|
|
// Assumption: The byte count of the resulting narrow string will be at most
|
|
|
|
|
// four times the character count of the input wstring. Allocate the buffer
|
|
|
|
|
// with that many char items (bytes) so that the first WideCharToMultiByte
|
|
|
|
|
// call will succeed most of the time as an optimization.
|
|
|
|
|
std::string output = "";
|
|
|
|
|
int wide_string_length = static_cast<int>(input.size()) + 1;
|
|
|
|
|
int output_string_byte_count = wide_string_length * 4;
|
|
|
|
|
std::vector<char> string_buffer(output_string_byte_count);
|
|
|
|
|
bool convert_failed = (0 == ::WideCharToMultiByte(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
wide_string_length,
|
|
|
|
|
&string_buffer[0],
|
|
|
|
|
output_string_byte_count,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL));
|
|
|
|
|
if (convert_failed) {
|
|
|
|
|
if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
|
|
|
// Buffer wasn't big enough. Call WideCharToMultiByte again with
|
|
|
|
|
// NULL values to determine how big the buffer should be.
|
|
|
|
|
output_string_byte_count = ::WideCharToMultiByte(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
wide_string_length,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
string_buffer.resize(output_string_byte_count);
|
|
|
|
|
convert_failed = (0 == ::WideCharToMultiByte(CP_UTF8,
|
|
|
|
|
0,
|
|
|
|
|
input.c_str(),
|
|
|
|
|
wide_string_length,
|
|
|
|
|
&string_buffer[0],
|
|
|
|
|
output_string_byte_count,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL));
|
|
|
|
|
if (!convert_failed) {
|
|
|
|
|
output = &string_buffer[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
output = &string_buffer[0];
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-11 17:17:50 -04:00
|
|
|
std::string StringUtilities::Format(const char* format, ...) {
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, format);
|
|
|
|
|
size_t buffer_size = _vscprintf(format, args);
|
|
|
|
|
std::vector<char> buffer(buffer_size + 1);
|
|
|
|
|
_vsnprintf_s(&buffer[0], buffer.size(), buffer_size + 1, format, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
std::string formatted = &buffer[0];
|
|
|
|
|
return formatted;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-30 15:28:15 -04:00
|
|
|
std::wstring StringUtilities::Format(const wchar_t* format, ...) {
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, format);
|
|
|
|
|
size_t buffer_size = _vscwprintf(format, args);
|
|
|
|
|
std::vector<wchar_t> buffer(buffer_size + 1);
|
|
|
|
|
_vsnwprintf_s(&buffer[0], buffer.size(), buffer_size + 1, format, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
std::wstring formatted = &buffer[0];
|
|
|
|
|
return formatted;
|
|
|
|
|
}
|
|
|
|
|
|
Added Proxy support to the IE driver native code.
This commit adds proxy support to the native code of the IE driver,
having it recognize the proxy capability in the WebDriver JSON wire
protocol. The default behavior will change the system proxy when a new
instance of the IE driver is created.
This means that from that point forward, all IE instances, including
those *not* started by WebDriver, will use the same proxy information.
The driver will attempt to reset the system proxy to the previous
settings when the session is properly exited by use of the quit method.
Be aware that this means that crashes in the driver may leave the
system's proxy settings in an inconsistent state, and it further
implies that attempting to drive multiple instances of IE using proxy
settings will likely do the same.
The driver sets the proxy settings by means of the Windows WinINet API,
which explicitly cannot be used from within a Windows service. This
implies that IEDriverServer.exe cannot be used from within a Windows
service.
This commit also introduces a new capability, "ie.usePerProcessProxy".
This capability takes a boolean value, and defaults to false. When set
to true, it attempts to only set the proxy information for a single IE
process, and does not affect the proxy settings of other instances of
IE. Use of this capability should be considered extremely experimental
at present,and may cause IE to behave inconsistently when attempting to
use a proxy with this capability set.
2013-07-28 23:41:52 -04:00
|
|
|
void StringUtilities::ToBuffer(const std::string& input, std::vector<char>* buffer) {
|
|
|
|
|
buffer->resize(input.size() + 1);
|
|
|
|
|
strcpy_s(&((*buffer)[0]), buffer->size(), input.c_str());
|
|
|
|
|
(*buffer)[buffer->size() - 1] = L'\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StringUtilities::ToBuffer(const std::wstring& input, std::vector<wchar_t>* buffer) {
|
|
|
|
|
buffer->resize(input.size() + 1);
|
|
|
|
|
wcscpy_s(&((*buffer)[0]), buffer->size(), input.c_str());
|
|
|
|
|
(*buffer)[buffer->size() - 1] = L'\0';
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-07 12:27:41 -05:00
|
|
|
std::string StringUtilities::Trim(const std::string& input) {
|
|
|
|
|
return TrimRight(TrimLeft(input));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string StringUtilities::TrimLeft(const std::string& input) {
|
|
|
|
|
size_t startpos = input.find_first_not_of(WHITESPACE);
|
|
|
|
|
return (startpos == std::string::npos) ? "" : input.substr(startpos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string StringUtilities::TrimRight(const std::string& input) {
|
|
|
|
|
size_t endpos = input.find_last_not_of(WHITESPACE);
|
|
|
|
|
return (endpos == std::string::npos) ? "" : input.substr(0, endpos + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring StringUtilities::Trim(const std::wstring& input) {
|
|
|
|
|
return TrimRight(TrimLeft(input));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring StringUtilities::TrimLeft(const std::wstring& input) {
|
|
|
|
|
size_t startpos = input.find_first_not_of(WIDE_WHITESPACE);
|
|
|
|
|
return (startpos == std::wstring::npos) ? L"" : input.substr(startpos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring StringUtilities::TrimRight(const std::wstring& input) {
|
|
|
|
|
size_t endpos = input.find_last_not_of(WIDE_WHITESPACE);
|
|
|
|
|
return (endpos == std::wstring::npos) ? L"" : input.substr(0, endpos + 1);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-23 18:18:18 -04:00
|
|
|
void StringUtilities::Split(const std::string& input,
|
|
|
|
|
const std::string& delimiter,
|
|
|
|
|
std::vector<std::string>* tokens) {
|
|
|
|
|
std::string input_copy = input;
|
|
|
|
|
while (input_copy.size() > 0) {
|
|
|
|
|
size_t delimiter_pos = input_copy.find(delimiter);
|
|
|
|
|
std::string token = input_copy.substr(0, delimiter_pos);
|
|
|
|
|
if (delimiter_pos == std::string::npos) {
|
|
|
|
|
input_copy = "";
|
|
|
|
|
} else {
|
|
|
|
|
input_copy = input_copy.substr(delimiter_pos + delimiter.size());
|
|
|
|
|
}
|
|
|
|
|
tokens->push_back(token);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StringUtilities::Split(const std::wstring& input,
|
|
|
|
|
const std::wstring& delimiter,
|
|
|
|
|
std::vector<std::wstring>* tokens) {
|
|
|
|
|
std::wstring input_copy = input;
|
|
|
|
|
while (input_copy.size() > 0) {
|
|
|
|
|
size_t delimiter_pos = input_copy.find(delimiter);
|
|
|
|
|
std::wstring token = input_copy.substr(0, delimiter_pos);
|
|
|
|
|
if (delimiter_pos == std::wstring::npos) {
|
|
|
|
|
input_copy = L"";
|
|
|
|
|
} else {
|
|
|
|
|
input_copy = input_copy.substr(delimiter_pos + delimiter.size());
|
|
|
|
|
}
|
|
|
|
|
tokens->push_back(token);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-06 06:40:39 -08:00
|
|
|
std::wstring StringUtilities::CreateGuid() {
|
|
|
|
|
UUID guid;
|
|
|
|
|
RPC_WSTR guid_string = NULL;
|
|
|
|
|
RPC_STATUS status = ::UuidCreate(&guid);
|
|
|
|
|
if (status != RPC_S_OK) {
|
|
|
|
|
// If we encounter an error, not bloody much we can do about it.
|
|
|
|
|
// Just log it and continue.
|
|
|
|
|
// LOG(WARN) << "UuidCreate returned a status other then RPC_S_OK: " << status;
|
|
|
|
|
}
|
|
|
|
|
status = ::UuidToString(&guid, &guid_string);
|
|
|
|
|
if (status != RPC_S_OK) {
|
|
|
|
|
// If we encounter an error, not bloody much we can do about it.
|
|
|
|
|
// Just log it and continue.
|
|
|
|
|
// LOG(WARN) << "UuidToString returned a status other then RPC_S_OK: " << status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RPC_WSTR is currently typedef'd in RpcDce.h (pulled in by rpc.h)
|
|
|
|
|
// as unsigned short*. It needs to be typedef'd as wchar_t*
|
|
|
|
|
wchar_t* cast_guid_string = reinterpret_cast<wchar_t*>(guid_string);
|
|
|
|
|
std::wstring returned_guid(cast_guid_string);
|
|
|
|
|
|
|
|
|
|
::RpcStringFree(&guid_string);
|
|
|
|
|
return returned_guid;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-22 16:47:23 -08:00
|
|
|
void StringUtilities::ComposeUnicodeString(std::wstring* input) {
|
|
|
|
|
StringUtilities::NormalizeUnicodeString(NormalizationC, input);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StringUtilities::DecomposeUnicodeString(std::wstring* input) {
|
|
|
|
|
StringUtilities::NormalizeUnicodeString(NormalizationD, input);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StringUtilities::NormalizeUnicodeString(NORM_FORM normalization_form,
|
|
|
|
|
std::wstring* input) {
|
|
|
|
|
if (FALSE == ::IsNormalizedString(normalization_form, input->c_str(), -1)) {
|
|
|
|
|
int required = ::NormalizeString(normalization_form,
|
|
|
|
|
input->c_str(),
|
|
|
|
|
-1,
|
|
|
|
|
NULL,
|
|
|
|
|
0);
|
|
|
|
|
std::vector<wchar_t> buffer(required);
|
|
|
|
|
::NormalizeString(normalization_form,
|
|
|
|
|
input->c_str(),
|
|
|
|
|
-1,
|
|
|
|
|
&buffer[0],
|
|
|
|
|
static_cast<int>(buffer.size()));
|
|
|
|
|
*input = &buffer[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-06 06:40:39 -08:00
|
|
|
} // namespace webdriver
|