X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FString-inl.h;h=dbfefa010fb6f97ac530ce280b74f086996b7ec0;hb=5810472278e75f70a1c9e930280dc7111fa66a0c;hp=28aead22360baa8e9b64ccf5218960f1b0f17f8c;hpb=5899b4ed30afe2355024ba08ca316545928272d6;p=folly.git diff --git a/folly/String-inl.h b/folly/String-inl.h index 28aead22..dbfefa01 100644 --- a/folly/String-inl.h +++ b/folly/String-inl.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,12 @@ * limitations under the License. */ -#ifndef FOLLY_STRING_INL_H_ -#define FOLLY_STRING_INL_H_ +#pragma once #include #include -#ifndef FOLLY_BASE_STRING_H_ +#ifndef FOLLY_STRING_H_ #error This file may only be included from String.h #endif @@ -51,7 +50,7 @@ void cEscape(StringPiece str, String& out) { if (e == 'P') { // printable ++p; } else if (e == 'O') { // octal - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); esc[1] = '0' + ((v >> 6) & 7); esc[2] = '0' + ((v >> 3) & 7); esc[3] = '0' + (v & 7); @@ -59,14 +58,14 @@ void cEscape(StringPiece str, String& out) { ++p; last = p; } else { // special 1-character escape - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); esc[1] = e; out.append(esc, 2); ++p; last = p; } } - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); } namespace detail { @@ -178,12 +177,12 @@ void uriEscape(StringPiece str, String& out, UriEscapeMode mode) { if (LIKELY(discriminator <= minEncode)) { ++p; } else if (mode == UriEscapeMode::QUERY && discriminator == 3) { - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); out.push_back('+'); ++p; last = p; } else { - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); esc[1] = hexValues[v >> 4]; esc[2] = hexValues[v & 0x0f]; out.append(esc, 3); @@ -191,7 +190,7 @@ void uriEscape(StringPiece str, String& out, UriEscapeMode mode) { last = p; } } - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); } template @@ -203,7 +202,6 @@ void uriUnescape(StringPiece str, String& out, UriEscapeMode mode) { // this is faster than calling push_back repeatedly. while (p != str.end()) { char c = *p; - unsigned char v = static_cast(v); switch (c) { case '%': { @@ -215,7 +213,7 @@ void uriUnescape(StringPiece str, String& out, UriEscapeMode mode) { if (UNLIKELY(h1 == 16 || h2 == 16)) { throw std::invalid_argument("invalid percent encode sequence"); } - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); out.push_back((h1 << 4) | h2); p += 3; last = p; @@ -223,7 +221,7 @@ void uriUnescape(StringPiece str, String& out, UriEscapeMode mode) { } case '+': if (mode == UriEscapeMode::QUERY) { - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); out.push_back(' '); ++p; last = p; @@ -235,7 +233,7 @@ void uriUnescape(StringPiece str, String& out, UriEscapeMode mode) { break; } } - out.append(&*last, p - last); + out.append(&*last, size_t(p - last)); } namespace detail { @@ -265,29 +263,6 @@ inline char delimFront(StringPiece s) { return *s.start(); } -/* - * These output conversion templates allow us to support multiple - * output string types, even when we are using an arbitrary - * OutputIterator. - */ -template struct OutputConverter {}; - -template<> struct OutputConverter { - std::string operator()(StringPiece sp) const { - return sp.toString(); - } -}; - -template<> struct OutputConverter { - fbstring operator()(StringPiece sp) const { - return sp.toFbstring(); - } -}; - -template<> struct OutputConverter { - StringPiece operator()(StringPiece sp) const { return sp; } -}; - /* * Shared implementation for all the split() overloads. * @@ -306,11 +281,9 @@ void internalSplit(DelimT delim, StringPiece sp, OutputIterator out, const size_t strSize = sp.size(); const size_t dSize = delimSize(delim); - OutputConverter conv; - if (dSize > strSize || dSize == 0) { if (!ignoreEmpty || strSize > 0) { - *out++ = conv(sp); + *out++ = to(sp); } return; } @@ -320,12 +293,12 @@ void internalSplit(DelimT delim, StringPiece sp, OutputIterator out, ignoreEmpty); } - int tokenStartPos = 0; - int tokenSize = 0; + size_t tokenStartPos = 0; + size_t tokenSize = 0; for (size_t i = 0; i <= strSize - dSize; ++i) { if (atDelim(&s[i], delim)) { if (!ignoreEmpty || tokenSize > 0) { - *out++ = conv(StringPiece(&s[tokenStartPos], tokenSize)); + *out++ = to(sp.subpiece(tokenStartPos, tokenSize)); } tokenStartPos = i + dSize; @@ -337,7 +310,7 @@ void internalSplit(DelimT delim, StringPiece sp, OutputIterator out, } tokenSize = strSize - tokenStartPos; if (!ignoreEmpty || tokenSize > 0) { - *out++ = conv(StringPiece(&s[tokenStartPos], tokenSize)); + *out++ = to(sp.subpiece(tokenStartPos, tokenSize)); } } @@ -346,36 +319,25 @@ template StringPiece prepareDelim(const String& s) { } inline char prepareDelim(char c) { return c; } -template -struct convertTo { - template - static Dst from(const Src& src) { return folly::to(src); } - static Dst from(const Dst& src) { return src; } -}; - -template -typename std::enable_if::value, bool>::type -splitFixed(const Delim& delimiter, - StringPiece input, - OutputType& out) { +template +bool splitFixed(const Delim& delimiter, StringPiece input, OutputType& output) { + static_assert( + exact || std::is_same::value || + IsSomeString::value, + "split() requires that the last argument be a string type"); if (exact && UNLIKELY(std::string::npos != input.find(delimiter))) { return false; } - out = convertTo::from(input); + output = folly::to(input); return true; } -template -typename std::enable_if::value, bool>::type -splitFixed(const Delim& delimiter, - StringPiece input, - OutputType& outHead, - OutputTypes&... outTail) { +template +bool splitFixed( + const Delim& delimiter, + StringPiece input, + OutputType& outHead, + OutputTypes&... outTail) { size_t cut = input.find(delimiter); if (UNLIKELY(cut == std::string::npos)) { return false; @@ -384,7 +346,7 @@ splitFixed(const Delim& delimiter, StringPiece tail(input.begin() + cut + detail::delimSize(delimiter), input.end()); if (LIKELY(splitFixed(delimiter, tail, outTail...))) { - outHead = convertTo::from(head); + outHead = folly::to(head); return true; } return false; @@ -431,20 +393,13 @@ void splitTo(const Delim& delimiter, ignoreEmpty); } -template -typename std::enable_if::value, bool>::type -split(const Delim& delimiter, - StringPiece input, - OutputType& outHead, - OutputTypes&... outTail) { +template +typename std::enable_if< + AllConvertible::value && sizeof...(OutputTypes) >= 1, + bool>::type +split(const Delim& delimiter, StringPiece input, OutputTypes&... outputs) { return detail::splitFixed( - detail::prepareDelim(delimiter), - input, - outHead, - outTail...); + detail::prepareDelim(delimiter), input, outputs...); } namespace detail { @@ -567,8 +522,8 @@ void backslashify(const String1& input, String2& output, bool hex_style) { template void humanify(const String1& input, String2& output) { - int numUnprintable = 0; - int numPrintablePrefix = 0; + size_t numUnprintable = 0; + size_t numPrintablePrefix = 0; for (unsigned char c : input) { if (c < 0x20 || c > 0x7e || c == '\\') { ++numUnprintable; @@ -615,7 +570,7 @@ bool hexlify(const InputString& input, OutputString& output, if (!append_output) output.clear(); static char hexValues[] = "0123456789abcdef"; - int j = output.size(); + auto j = output.size(); output.resize(2 * input.size() + output.size()); for (size_t i = 0; i < input.size(); ++i) { int ch = input[i]; @@ -632,17 +587,12 @@ bool unhexlify(const InputString& input, OutputString& output) { } output.resize(input.size() / 2); int j = 0; - auto unhex = [](char c) -> int { - return c >= '0' && c <= '9' ? c - '0' : - c >= 'A' && c <= 'F' ? c - 'A' + 10 : - c >= 'a' && c <= 'f' ? c - 'a' + 10 : - -1; - }; for (size_t i = 0; i < input.size(); i += 2) { - int highBits = unhex(input[i]); - int lowBits = unhex(input[i + 1]); - if (highBits < 0 || lowBits < 0) { + int highBits = detail::hexTable[static_cast(input[i])]; + int lowBits = detail::hexTable[static_cast(input[i + 1])]; + if ((highBits | lowBits) & 0x10) { + // One of the characters wasn't a hex digit return false; } output[j++] = (highBits << 4) + lowBits; @@ -670,5 +620,3 @@ void hexDump(const void* ptr, size_t size, OutIt out) { } } // namespace folly - -#endif /* FOLLY_STRING_INL_H_ */