1
0
Fork 0

micro optimizations for case conversion (#10291)

This commit is contained in:
Jan 2019-10-22 09:39:16 +02:00 committed by GitHub
parent 19fad3f0df
commit 09134ee8d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 176 additions and 126 deletions

View File

@ -351,7 +351,7 @@ DateSelectionModifier parseDateModifierFlag(VPackSlice flag) {
} }
TRI_ASSERT(flagStr.size() >= 1); TRI_ASSERT(flagStr.size() >= 1);
std::transform(flagStr.begin(), flagStr.end(), flagStr.begin(), ::tolower); basics::StringUtils::tolowerInPlace(flagStr);
switch (flagStr.front()) { switch (flagStr.front()) {
case 'y': case 'y':
if (flagStr == "years" || flagStr == "year" || flagStr == "y") { if (flagStr == "years" || flagStr == "year" || flagStr == "y") {
@ -3401,7 +3401,7 @@ AqlValue Functions::DateTrunc(ExpressionContext* expressionContext,
} }
std::string duration = durationType.slice().copyString(); std::string duration = durationType.slice().copyString();
std::transform(duration.begin(), duration.end(), duration.begin(), ::tolower); basics::StringUtils::tolowerInPlace(duration);
year_month_day ymd{floor<days>(tp)}; year_month_day ymd{floor<days>(tp)};
auto day_time = make_time(tp - sys_days(ymd)); auto day_time = make_time(tp - sys_days(ymd));

View File

@ -1928,8 +1928,7 @@ int fetchEdgesFromEngines(
// Response has invalid format // Response has invalid format
return TRI_ERROR_HTTP_CORRUPTED_JSON; return TRI_ERROR_HTTP_CORRUPTED_JSON;
} }
read += Helper::getNumericValue<size_t>(resSlice, read += Helper::getNumericValue<size_t>(resSlice, "readIndex", 0);
"readIndex", 0);
bool allCached = true; bool allCached = true;
VPackSlice edges = resSlice.get("edges"); VPackSlice edges = resSlice.get("edges");
@ -1974,14 +1973,14 @@ void fetchVerticesFromEngines(
std::unordered_map<arangodb::velocypack::StringRef, VPackSlice>& result, std::unordered_map<arangodb::velocypack::StringRef, VPackSlice>& result,
std::vector<std::shared_ptr<VPackBufferUInt8>>& datalake, std::vector<std::shared_ptr<VPackBufferUInt8>>& datalake,
bool forShortestPath) { bool forShortestPath) {
// TODO map id => ServerID if possible // TODO map id => ServerID if possible
// And go fast-path // And go fast-path
// slow path, sharding not deducable from _id // slow path, sharding not deducable from _id
transaction::BuilderLeaser leased(&trx); transaction::BuilderLeaser leased(&trx);
leased->openObject(); leased->openObject();
leased->add(VPackValue("keys")); leased->add("keys", VPackValue(VPackValueType::Array));
leased->openArray();
for (auto const& v : vertexIds) { for (auto const& v : vertexIds) {
leased->add(VPackValuePair(v.data(), v.length(), VPackValueType::String)); leased->add(VPackValuePair(v.data(), v.length(), VPackValueType::String));
} }
@ -2025,7 +2024,7 @@ void fetchVerticesFromEngines(
} }
bool cached = false; bool cached = false;
for (auto pair : VPackObjectIterator(resSlice)) { for (auto pair : VPackObjectIterator(resSlice, true)) {
arangodb::velocypack::StringRef key(pair.key); arangodb::velocypack::StringRef key(pair.key);
if (vertexIds.erase(key) == 0) { if (vertexIds.erase(key) == 0) {
// We either found the same vertex twice, // We either found the same vertex twice,

View File

@ -120,7 +120,6 @@ template <SocketType T>
int HttpCommTask<T>::on_header_field(llhttp_t* p, const char* at, size_t len) { int HttpCommTask<T>::on_header_field(llhttp_t* p, const char* at, size_t len) {
HttpCommTask<T>* self = static_cast<HttpCommTask<T>*>(p->data); HttpCommTask<T>* self = static_cast<HttpCommTask<T>*>(p->data);
if (self->_lastHeaderWasValue) { if (self->_lastHeaderWasValue) {
StringUtils::tolowerInPlace(&self->_lastHeaderField);
self->_request->setHeaderV2(std::move(self->_lastHeaderField), self->_request->setHeaderV2(std::move(self->_lastHeaderField),
std::move(self->_lastHeaderValue)); std::move(self->_lastHeaderValue));
self->_lastHeaderField.assign(at, len); self->_lastHeaderField.assign(at, len);
@ -147,7 +146,6 @@ template <SocketType T>
int HttpCommTask<T>::on_header_complete(llhttp_t* p) { int HttpCommTask<T>::on_header_complete(llhttp_t* p) {
HttpCommTask<T>* self = static_cast<HttpCommTask<T>*>(p->data); HttpCommTask<T>* self = static_cast<HttpCommTask<T>*>(p->data);
if (!self->_lastHeaderField.empty()) { if (!self->_lastHeaderField.empty()) {
StringUtils::tolowerInPlace(&self->_lastHeaderField);
self->_request->setHeaderV2(std::move(self->_lastHeaderField), self->_request->setHeaderV2(std::move(self->_lastHeaderField),
std::move(self->_lastHeaderValue)); std::move(self->_lastHeaderValue));
} }
@ -695,11 +693,11 @@ void HttpCommTask<T>::sendResponse(std::unique_ptr<GeneralResponse> baseRes,
while (p < end) { while (p < end) {
if (capState == 1) { if (capState == 1) {
// upper case // upper case
header->push_back(::toupper(*p)); header->push_back(StringUtils::toupper(*p));
capState = 0; capState = 0;
} else if (capState == 0) { } else if (capState == 0) {
// normal case // normal case
header->push_back(::tolower(*p)); header->push_back(StringUtils::tolower(*p));
if (*p == '-') { if (*p == '-') {
capState = 1; capState = 1;
} else if (*p == ':') { } else if (*p == ':') {

View File

@ -1739,7 +1739,7 @@ arangodb::Result fromFuncExists(irs::boolean_filter* filter, QueryContext const&
} }
std::string strArg(arg); std::string strArg(arg);
arangodb::basics::StringUtils::tolowerInPlace(&strArg); // normalize user input arangodb::basics::StringUtils::tolowerInPlace(strArg); // normalize user input
irs::string_ref const TypeAnalyzer("analyzer"); irs::string_ref const TypeAnalyzer("analyzer");
typedef bool (*TypeHandler)(std::string&, arangodb::iresearch::IResearchLinkMeta::Analyzer const&); typedef bool (*TypeHandler)(std::string&, arangodb::iresearch::IResearchLinkMeta::Analyzer const&);

View File

@ -48,7 +48,7 @@ bool parseDirectionBool(arangodb::velocypack::Slice slice, bool& direction) {
bool parseDirectionString(arangodb::velocypack::Slice slice, bool& direction) { bool parseDirectionString(arangodb::velocypack::Slice slice, bool& direction) {
if (slice.isString()) { if (slice.isString()) {
std::string value = arangodb::iresearch::getStringRef(slice); std::string value = arangodb::iresearch::getStringRef(slice);
arangodb::basics::StringUtils::tolowerInPlace(&value); arangodb::basics::StringUtils::tolowerInPlace(value);
if (value == "asc") { if (value == "asc") {
direction = true; direction = true;

View File

@ -353,7 +353,7 @@ bool RestBatchHandler::getBoundaryHeader(std::string& result) {
// trim 2nd part and lowercase it // trim 2nd part and lowercase it
StringUtils::trimInPlace(parts[1]); StringUtils::trimInPlace(parts[1]);
std::string p = parts[1].substr(0, boundaryLength); std::string p = parts[1].substr(0, boundaryLength);
StringUtils::tolowerInPlace(&p); StringUtils::tolowerInPlace(p);
if (p != "boundary=") { if (p != "boundary=") {
return false; return false;
@ -501,7 +501,7 @@ bool RestBatchHandler::extractPart(SearchHelper& helper) {
if (key[0] == 'c' || key[0] == 'C') { if (key[0] == 'c' || key[0] == 'C') {
// got an interesting key. now process it // got an interesting key. now process it
StringUtils::tolowerInPlace(&key); StringUtils::tolowerInPlace(key);
// skip the colon itself // skip the colon itself
++colon; ++colon;

View File

@ -72,24 +72,19 @@ RestStatus RestEdgesHandler::execute() {
} }
bool RestEdgesHandler::parseDirection(TRI_edge_direction_e& direction) { bool RestEdgesHandler::parseDirection(TRI_edge_direction_e& direction) {
bool found; std::string const& dir = _request->value("direction");
std::string dir = _request->value("direction", found);
if (!found || dir.empty()) { if (dir.empty()) {
dir = "any";
}
std::string dirString(dir);
if (dirString == "any") {
direction = TRI_EDGE_ANY; direction = TRI_EDGE_ANY;
} else if (dirString == "out" || dirString == "outbound") { } else if (dir == "any") {
direction = TRI_EDGE_ANY;
} else if (dir == "out" || dir == "outbound") {
direction = TRI_EDGE_OUT; direction = TRI_EDGE_OUT;
} else if (dirString == "in" || dirString == "inbound") { } else if (dir == "in" || dir == "inbound") {
direction = TRI_EDGE_IN; direction = TRI_EDGE_IN;
} else { } else {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"<direction> must by any, in, or out, not: " + dirString); "<direction> must by any, in, or out, not: " + dir);
return false; return false;
} }
@ -154,7 +149,7 @@ bool RestEdgesHandler::readEdges() {
return false; return false;
} }
std::string collectionName = suffixes[0]; std::string const& collectionName = suffixes[0];
if (!validateCollection(collectionName)) { if (!validateCollection(collectionName)) {
return false; return false;
} }
@ -197,7 +192,7 @@ bool RestEdgesHandler::readEdges() {
resultBuilder.add(edges); resultBuilder.add(edges);
resultBuilder.add(StaticStrings::Error, VPackValue(false)); resultBuilder.add(StaticStrings::Error, VPackValue(false));
resultBuilder.add("code", VPackValue(200)); resultBuilder.add(StaticStrings::Code, VPackValue(200));
VPackSlice stats = extras.get("stats"); VPackSlice stats = extras.get("stats");
if (stats.isObject()) { if (stats.isObject()) {
resultBuilder.add(VPackValue("stats")); resultBuilder.add(VPackValue("stats"));
@ -241,7 +236,7 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() {
return false; return false;
} }
std::string collectionName = suffixes[0]; std::string const& collectionName = suffixes[0];
if (!validateCollection(collectionName)) { if (!validateCollection(collectionName)) {
return false; return false;
} }
@ -277,10 +272,8 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() {
VPackSlice edges = queryResult.data->slice(); VPackSlice edges = queryResult.data->slice();
for (VPackSlice edge : VPackArrayIterator(edges)) { for (VPackSlice edge : VPackArrayIterator(edges)) {
std::string key = transaction::helpers::extractKeyFromDocument(edge).copyString(); if (foundEdges.emplace(transaction::helpers::extractKeyFromDocument(edge).copyString()).second) {
if (foundEdges.find(key) == foundEdges.end()) {
resultBuilder.add(edge); resultBuilder.add(edge);
foundEdges.emplace(std::move(key));
} }
} }
ctx = queryResult.context; ctx = queryResult.context;
@ -288,7 +281,7 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() {
resultBuilder.close(); // </edges> resultBuilder.close(); // </edges>
resultBuilder.add(StaticStrings::Error, VPackValue(false)); resultBuilder.add(StaticStrings::Error, VPackValue(false));
resultBuilder.add("code", VPackValue(200)); resultBuilder.add(StaticStrings::Code, VPackValue(200));
resultBuilder.close(); resultBuilder.close();
// and generate a response // and generate a response

View File

@ -500,6 +500,11 @@ void SupervisedScheduler::sortoutLongRunningThreads() {
} }
bool SupervisedScheduler::canPullFromQueue(uint64_t queueIndex) const { bool SupervisedScheduler::canPullFromQueue(uint64_t queueIndex) const {
if (queueIndex == 0) {
// We can always! pull from high priority
return true;
}
// This function should ensure the following thread reservation: // This function should ensure the following thread reservation:
// 25% reserved for FastLane only // 25% reserved for FastLane only
// upto 75% of work can go on MedLane and FastLane // upto 75% of work can go on MedLane and FastLane
@ -514,17 +519,13 @@ bool SupervisedScheduler::canPullFromQueue(uint64_t queueIndex) const {
uint64_t jobsDequeued = _jobsDequeued.load(std::memory_order_relaxed); uint64_t jobsDequeued = _jobsDequeued.load(std::memory_order_relaxed);
TRI_ASSERT(jobsDequeued >= jobsDone); TRI_ASSERT(jobsDequeued >= jobsDone);
switch (queueIndex) { if (queueIndex == 1) {
case 0: // We can work on med if less than 75% of the workers are busy
// We can always! pull from high priority return (jobsDequeued - jobsDone) < (_maxNumWorker * 3 / 4);
return true;
case 1:
// We can work on med if less than 75% of the workers are busy
return (jobsDequeued - jobsDone) < (_maxNumWorker * 3 / 4);
default:
// We can work on low if less than 50% of the workers are busy
return (jobsDequeued - jobsDone) < (_maxNumWorker / 2);
} }
// We can work on low if less than 50% of the workers are busy
return (jobsDequeued - jobsDone) < (_maxNumWorker / 2);
} }
std::unique_ptr<SupervisedScheduler::WorkItem> SupervisedScheduler::getWork( std::unique_ptr<SupervisedScheduler::WorkItem> SupervisedScheduler::getWork(

View File

@ -140,7 +140,7 @@ Result arangodb::unregisterUserFunctionsGroup(TRI_vocbase_t& vocbase,
} }
std::string uc(functionFilterPrefix); std::string uc(functionFilterPrefix);
basics::StringUtils::toupperInPlace(&uc); basics::StringUtils::toupperInPlace(uc);
if ((uc.length() < 2) || (uc[uc.length() - 1] != ':') || (uc[uc.length() - 2] != ':')) { if ((uc.length() < 2) || (uc[uc.length() - 1] != ':') || (uc[uc.length() - 2] != ':')) {
uc += "::"; uc += "::";
@ -279,7 +279,7 @@ Result arangodb::registerUserFunction(TRI_vocbase_t& vocbase, velocypack::Slice
return res; return res;
} }
std::string _key(name); std::string _key(name);
basics::StringUtils::toupperInPlace(&_key); basics::StringUtils::toupperInPlace(_key);
VPackBuilder oneFunctionDocument; VPackBuilder oneFunctionDocument;
oneFunctionDocument.openObject(); oneFunctionDocument.openObject();
@ -336,7 +336,7 @@ Result arangodb::toArrayUserFunctions(TRI_vocbase_t& vocbase,
"@ucName RETURN function"; "@ucName RETURN function";
std::string uc(functionFilterPrefix); std::string uc(functionFilterPrefix);
basics::StringUtils::toupperInPlace(&uc); basics::StringUtils::toupperInPlace(uc);
if ((uc.length() < 2) || (uc[uc.length() - 1] != ':') || (uc[uc.length() - 2] != ':')) { if ((uc.length() < 2) || (uc[uc.length() - 1] != ':') || (uc[uc.length() - 2] != ':')) {
uc += "::"; uc += "::";

View File

@ -645,71 +645,97 @@ std::string replace(std::string const& sourceStr, std::string const& fromStr,
return std::string(ptr, k); return std::string(ptr, k);
} }
void tolowerInPlace(std::string* str) { void tolowerInPlace(std::string& str) {
// unrolled version of
// for (auto& c : str) {
// c = StringUtils::tolower(c);
// }
auto pos = str.data();
auto end = pos + str.size();
if (str->empty()) { while (pos != end) {
return; size_t len = end - pos;
} if (len > 4) {
len = 4;
}
for (std::string::iterator i = str->begin(); i != str->end(); ++i) { switch (len) {
*i = ::tolower(*i); case 4:
pos[3] = StringUtils::tolower(pos[3]);
[[fallthrough]];
case 3:
pos[2] = StringUtils::tolower(pos[2]);
[[fallthrough]];
case 2:
pos[1] = StringUtils::tolower(pos[1]);
[[fallthrough]];
case 1:
pos[0] = StringUtils::tolower(pos[0]);
}
pos += len;
} }
} }
std::string tolower(std::string&& str) { std::string tolower(std::string&& str) {
tolowerInPlace(str);
std::transform(
str.begin(), str.end(), str.begin(), [](unsigned char c){ return ::tolower(c); });
return std::move(str); return std::move(str);
} }
std::string tolower(std::string const& str) { std::string tolower(std::string const& str) {
size_t len = str.length();
if (len == 0) {
return "";
}
std::string result; std::string result;
result.reserve(len); result.resize(str.size());
char const* ptr = str.c_str(); size_t i = 0;
for (auto& c : result) {
for (; 0 < len; len--, ptr++) { c = StringUtils::tolower(str[i++]);
result.push_back(static_cast<char>(::tolower(*ptr)));
} }
return result; return result;
} }
void toupperInPlace(std::string* str) { void toupperInPlace(std::string& str) {
size_t len = str->length(); // unrolled version of
// for (auto& c : str) {
// c = StringUtils::toupper(c);
// }
auto pos = str.data();
auto end = pos + str.size();
if (len == 0) { while (pos != end) {
return; size_t len = end - pos;
} if (len > 4) {
len = 4;
}
for (std::string::iterator i = str->begin(); i != str->end(); ++i) { switch (len) {
*i = ::toupper(*i); case 4:
pos[3] = StringUtils::toupper(pos[3]);
[[fallthrough]];
case 3:
pos[2] = StringUtils::toupper(pos[2]);
[[fallthrough]];
case 2:
pos[1] = StringUtils::toupper(pos[1]);
[[fallthrough]];
case 1:
pos[0] = StringUtils::toupper(pos[0]);
}
pos += len;
} }
} }
std::string toupper(std::string&& str) {
toupperInPlace(str);
return std::move(str);
}
std::string toupper(std::string const& str) { std::string toupper(std::string const& str) {
size_t len = str.length();
if (len == 0) {
return "";
}
std::string result; std::string result;
result.reserve(len); result.resize(str.size());
char const* ptr = str.c_str(); size_t i = 0;
for (auto& c : result) {
for (; 0 < len; len--, ptr++) { c = StringUtils::toupper(str[i++]);
result.push_back(static_cast<char>(::toupper(*ptr)));
} }
return result; return result;
@ -842,14 +868,6 @@ std::string urlEncode(std::string const& str) {
return urlEncode(str.c_str(), str.size()); return urlEncode(str.c_str(), str.size());
} }
std::string urlEncode(char const* src) {
if (src != nullptr) {
size_t len = strlen(src);
return urlEncode(src, len);
}
return "";
}
std::string urlEncode(char const* src, size_t const len) { std::string urlEncode(char const* src, size_t const len) {
static char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', static char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
@ -1401,7 +1419,7 @@ bool boolean(std::string const& str) {
return false; return false;
} }
std::string lower = trim(str); std::string lower = trim(str);
tolowerInPlace(&lower); tolowerInPlace(lower);
if (lower == "true" || lower == "yes" || lower == "on" || lower == "y" || if (lower == "true" || lower == "yes" || lower == "on" || lower == "y" ||
lower == "1" || lower == "") { lower == "1" || lower == "") {

View File

@ -159,17 +159,33 @@ std::vector<std::string> wrap(std::string const& sourceStr, size_t size,
std::string replace(std::string const& sourceStr, std::string const& fromString, std::string replace(std::string const& sourceStr, std::string const& fromString,
std::string const& toString); std::string const& toString);
/// @brief converts string to lower case in place static inline char tolower(char c) {
void tolowerInPlace(std::string* str); return c + ((static_cast<unsigned char>(c - 65) < 26U) << 5);
}
/// @brief converts string to lower case static inline unsigned char tolower(unsigned char c) {
return c + ((c - 65U < 26U) << 5);
}
static inline char toupper(char c) {
return c - ((static_cast<unsigned char>(c - 97) < 26U) << 5);
}
static inline unsigned char toupper(unsigned char c) {
return c - ((c - 97U < 26U) << 5);
}
/// @brief converts string to lower case in place - locale-independent, ASCII only!
void tolowerInPlace(std::string& str);
/// @brief converts string to lower case - locale-independent, ASCII only!
std::string tolower(std::string&& str); std::string tolower(std::string&& str);
std::string tolower(std::string const& str); std::string tolower(std::string const& str);
/// @brief converts string to upper case in place /// @brief converts string to upper case in place - locale-independent, ASCII only!
void toupperInPlace(std::string* str); void toupperInPlace(std::string& str);
/// @brief converts string to upper case /// @brief converts string to upper case - locale-independent, ASCII only!
std::string toupper(std::string const& str); std::string toupper(std::string const& str);
/// @brief checks for a prefix /// @brief checks for a prefix
@ -182,9 +198,6 @@ bool isSuffix(std::string const& str, std::string const& postfix);
std::string urlDecodePath(std::string const& str); std::string urlDecodePath(std::string const& str);
std::string urlDecode(std::string const& str); std::string urlDecode(std::string const& str);
/// @brief url encodes the string
std::string urlEncode(char const* src);
/// @brief url encodes the string /// @brief url encodes the string
std::string urlEncode(char const* src, size_t len); std::string urlEncode(char const* src, size_t len);

View File

@ -166,7 +166,8 @@ class SharedState {
[[fallthrough]]; [[fallthrough]];
case State::OnlyResult: case State::OnlyResult:
if (_state.compare_exchange_strong(state, State::Done, std::memory_order_release)) { // acquire is actually correct here
if (_state.compare_exchange_strong(state, State::Done, std::memory_order_acquire)) {
doCallback(); doCallback();
return; return;
} }
@ -202,7 +203,8 @@ class SharedState {
[[fallthrough]]; [[fallthrough]];
case State::OnlyCallback: case State::OnlyCallback:
if (_state.compare_exchange_strong(state, State::Done, std::memory_order_release)) { // acquire is actually correct here
if (_state.compare_exchange_strong(state, State::Done, std::memory_order_acquire)) {
doCallback(); doCallback();
return; return;
} }

View File

@ -35,6 +35,7 @@
#include <s2/s2polygon.h> #include <s2/s2polygon.h>
#include <s2/s2polyline.h> #include <s2/s2polyline.h>
#include "Basics/StringUtils.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Basics/debugging.h" #include "Basics/debugging.h"
#include "Geo/GeoParams.h" #include "Geo/GeoParams.h"
@ -56,7 +57,7 @@ const std::string kTypeStringGeometryCollection = "GeometryCollection";
namespace { namespace {
inline bool sameCharIgnoringCase(char a, char b) { inline bool sameCharIgnoringCase(char a, char b) {
return std::toupper(a) == std::toupper(b); return arangodb::basics::StringUtils::toupper(a) == arangodb::basics::StringUtils::toupper(b);
} }
} // namespace } // namespace

View File

@ -99,7 +99,7 @@ void HttpRequest::parseHeader(char* start, size_t length) {
char* e = lineBegin; char* e = lineBegin;
for (; e < end && *e != ' ' && *e != '\n'; ++e) { for (; e < end && *e != ' ' && *e != '\n'; ++e) {
*e = ::tolower(*e); *e = ::StringUtils::tolower(*e);
} }
// store key and value // store key and value
@ -325,7 +325,7 @@ void HttpRequest::parseHeader(char* start, size_t length) {
char* e = lineBegin; char* e = lineBegin;
for (; e < end && *e != ':' && *e != '\n'; ++e) { for (; e < end && *e != ':' && *e != '\n'; ++e) {
*e = ::tolower(*e); *e = StringUtils::tolower(*e);
} }
// store key and value // store key and value
@ -535,7 +535,7 @@ void HttpRequest::parseUrl(const char* path, size_t length) {
} }
void HttpRequest::setHeaderV2(std::string key, std::string value) { void HttpRequest::setHeaderV2(std::string key, std::string value) {
StringUtils::tolowerInPlace(&key); // always lowercase key StringUtils::tolowerInPlace(key); // always lowercase key
if (key == StaticStrings::ContentLength) { if (key == StaticStrings::ContentLength) {
_contentLength = NumberUtils::atoi_zero<int64_t>(value.c_str(), value.c_str() + value.size()); _contentLength = NumberUtils::atoi_zero<int64_t>(value.c_str(), value.c_str() + value.size());
@ -570,7 +570,7 @@ void HttpRequest::setHeaderV2(std::string key, std::string value) {
if (key == "x-http-method" || if (key == "x-http-method" ||
key == "x-method-override" || key == "x-method-override" ||
key == "x-http-method-override") { key == "x-http-method-override") {
StringUtils::tolowerInPlace(&value); StringUtils::tolowerInPlace(value);
_type = findRequestType(value.c_str(), value.size()); _type = findRequestType(value.c_str(), value.size());
// don't insert this header!! // don't insert this header!!
return; return;
@ -742,7 +742,7 @@ void HttpRequest::setHeader(char const* key, size_t keyLength,
(keyLength == 17 && memcmp(key, "x-method-override", keyLength) == 0) || (keyLength == 17 && memcmp(key, "x-method-override", keyLength) == 0) ||
(keyLength == 22 && memcmp(key, "x-http-method-override", keyLength) == 0)) { (keyLength == 22 && memcmp(key, "x-http-method-override", keyLength) == 0)) {
std::string overriddenType(value, valueLength); std::string overriddenType(value, valueLength);
StringUtils::tolowerInPlace(&overriddenType); StringUtils::tolowerInPlace(overriddenType);
_type = findRequestType(overriddenType.c_str(), overriddenType.size()); _type = findRequestType(overriddenType.c_str(), overriddenType.size());

View File

@ -189,11 +189,11 @@ void HttpResponse::writeHeader(StringBuffer* output) {
while (p < end) { while (p < end) {
if (capState == 1) { if (capState == 1) {
// upper case // upper case
output->appendCharUnsafe(::toupper(*p)); output->appendCharUnsafe(StringUtils::toupper(*p));
capState = 0; capState = 0;
} else if (capState == 0) { } else if (capState == 0) {
// normal case // normal case
output->appendCharUnsafe(::tolower(*p)); output->appendCharUnsafe(StringUtils::tolower(*p));
if (*p == '-') { if (*p == '-') {
capState = 1; capState = 1;
} else if (*p == ':') { } else if (*p == ':') {

View File

@ -129,11 +129,11 @@ void VstResponse::writeMessageHeader(VPackBuffer<uint8_t>& buffer) const {
for (auto& it : tmp) { for (auto& it : tmp) {
if (capState == 1) { if (capState == 1) {
// upper case // upper case
it = ::toupper(it); it = StringUtils::toupper(it);
capState = 0; capState = 0;
} else if (capState == 0) { } else if (capState == 0) {
// normal case // normal case
it = ::tolower(it); it = StringUtils::tolower(it);
if (it == '-') { if (it == '-') {
capState = 1; capState = 1;
} else if (it == ':') { } else if (it == ':') {

View File

@ -133,7 +133,7 @@ void SimpleHttpResult::addHeaderField(char const* key, size_t keyLength,
// lower-case key // lower-case key
std::string keyString(key, keyLength); std::string keyString(key, keyLength);
StringUtils::tolowerInPlace(&keyString); StringUtils::tolowerInPlace(keyString);
// trim value // trim value
{ {

View File

@ -2113,8 +2113,8 @@ static void JS_Log(v8::FunctionCallbackInfo<v8::Value> const& args) {
std::string prefix; std::string prefix;
StringUtils::tolowerInPlace(&ls); StringUtils::tolowerInPlace(ls);
StringUtils::tolowerInPlace(&ts); StringUtils::tolowerInPlace(ts);
LogTopic const* topicPtr = ts.empty() ? nullptr : LogTopic::lookup(ts); LogTopic const* topicPtr = ts.empty() ? nullptr : LogTopic::lookup(ts);
LogTopic const& topic = (topicPtr != nullptr) ? *topicPtr : Logger::FIXME; LogTopic const& topic = (topicPtr != nullptr) ? *topicPtr : Logger::FIXME;
@ -4007,7 +4007,7 @@ static void JS_PBKDF2(v8::FunctionCallbackInfo<v8::Value> const& args) {
SslInterface::Algorithm al = SslInterface::Algorithm::ALGORITHM_SHA1; SslInterface::Algorithm al = SslInterface::Algorithm::ALGORITHM_SHA1;
if (args.Length() > 4 && !args[4]->IsUndefined()) { if (args.Length() > 4 && !args[4]->IsUndefined()) {
std::string algorithm = TRI_ObjectToString(isolate, args[4]); std::string algorithm = TRI_ObjectToString(isolate, args[4]);
StringUtils::tolowerInPlace(&algorithm); StringUtils::tolowerInPlace(algorithm);
if (algorithm == "sha1") { if (algorithm == "sha1") {
al = SslInterface::Algorithm::ALGORITHM_SHA1; al = SslInterface::Algorithm::ALGORITHM_SHA1;
@ -4061,7 +4061,7 @@ static void JS_HMAC(v8::FunctionCallbackInfo<v8::Value> const& args) {
SslInterface::Algorithm al = SslInterface::Algorithm::ALGORITHM_SHA256; SslInterface::Algorithm al = SslInterface::Algorithm::ALGORITHM_SHA256;
if (args.Length() > 2 && !args[2]->IsUndefined()) { if (args.Length() > 2 && !args[2]->IsUndefined()) {
std::string algorithm = TRI_ObjectToString(isolate, args[2]); std::string algorithm = TRI_ObjectToString(isolate, args[2]);
StringUtils::tolowerInPlace(&algorithm); StringUtils::tolowerInPlace(algorithm);
if (algorithm == "sha1") { if (algorithm == "sha1") {
al = SslInterface::Algorithm::ALGORITHM_SHA1; al = SslInterface::Algorithm::ALGORITHM_SHA1;

View File

@ -131,13 +131,38 @@ TEST_F(StringUtilsTest, test_Split3) {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test_Tolower /// @brief test_tolower
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TEST_F(StringUtilsTest, test_Tolower) { TEST_F(StringUtilsTest, test_tolower) {
string lower = StringUtils::tolower("HaLlO WoRlD!"); EXPECT_EQ(StringUtils::tolower(""), "");
EXPECT_EQ(StringUtils::tolower(" "), " ");
EXPECT_EQ(StringUtils::tolower("12345"), "12345");
EXPECT_EQ(StringUtils::tolower("a"), "a");
EXPECT_EQ(StringUtils::tolower("A"), "a");
EXPECT_EQ(StringUtils::tolower("ä"), "ä");
EXPECT_EQ(StringUtils::tolower("Ä"), "Ä");
EXPECT_EQ(StringUtils::tolower("HeLlO WoRlD!"), "hello world!");
EXPECT_EQ(StringUtils::tolower("hello-world-nono "), "hello-world-nono ");
EXPECT_EQ(StringUtils::tolower("HELLo-world-NONO "), "hello-world-nono ");
EXPECT_EQ(StringUtils::tolower(" The quick \r\nbrown Fox"), " the quick \r\nbrown fox");
}
EXPECT_EQ(lower, "hallo world!"); ////////////////////////////////////////////////////////////////////////////////
/// @brief test_toupper
////////////////////////////////////////////////////////////////////////////////
TEST_F(StringUtilsTest, test_toupper) {
EXPECT_EQ(StringUtils::toupper(""), "");
EXPECT_EQ(StringUtils::toupper(" "), " ");
EXPECT_EQ(StringUtils::toupper("12345"), "12345");
EXPECT_EQ(StringUtils::toupper("a"), "A");
EXPECT_EQ(StringUtils::toupper("A"), "A");
EXPECT_EQ(StringUtils::toupper("ä"), "ä");
EXPECT_EQ(StringUtils::toupper("Ä"), "Ä");
EXPECT_EQ(StringUtils::toupper("HeLlO WoRlD!"), "HELLO WORLD!");
EXPECT_EQ(StringUtils::toupper("hello-world-nono "), "HELLO-WORLD-NONO ");
EXPECT_EQ(StringUtils::toupper("HELLo-world-NONO "), "HELLO-WORLD-NONO ");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////