// Skip over padding until sp.data() - start is a multiple of alignment void skipPadding(folly::StringPiece& sp, const char* start, size_t alignment) { size_t remainder = (sp.data() - start) % alignment; if (remainder) { FOLLY_SAFE_CHECK(alignment - remainder <= sp.size(), "invalid padding"); sp.advance(alignment - remainder); } }
std::shared_ptr<AccessPoint> AccessPoint::create(folly::StringPiece apString, mc_protocol_t defaultProtocol, bool defaultUseSsl, uint16_t portOverride) { if (apString.empty()) { return nullptr; } folly::StringPiece host; if (apString[0] == '[') { // IPv6 auto closing = apString.find(']'); if (closing == std::string::npos) { return nullptr; } host = apString.subpiece(1, closing - 1); apString.advance(closing + 1); } else { // IPv4 or hostname auto colon = apString.find(':'); if (colon == std::string::npos) { host = apString; apString = ""; } else { host = apString.subpiece(0, colon); apString.advance(colon); } } if (host.empty()) { return nullptr; } try { folly::StringPiece port, protocol, encr; parseParts(apString, port, protocol, encr); return std::make_shared<AccessPoint>( host, portOverride != 0 ? portOverride : folly::to<uint16_t>(port), protocol.empty() ? defaultProtocol : parseProtocol(protocol), encr.empty() ? defaultUseSsl : parseSsl(encr)); } catch (const std::exception&) { return nullptr; } }
typename std::enable_if<std::is_pod<T>::value, T>::type read(folly::StringPiece& sp) { FOLLY_SAFE_CHECK(sp.size() >= sizeof(T), "underflow"); T x; memcpy(&x, sp.data(), sizeof(T)); sp.advance(sizeof(T)); return x; }
// Simplify a path -- as much as we can while not moving data around... void simplifyPath(folly::StringPiece& sp) { // Strip leading slashes and useless patterns (./), leaving one initial // slash. for (;;) { if (sp.empty()) { return; } // Strip leading slashes, leaving one. while (sp.startsWith("//")) { sp.advance(1); } if (sp.startsWith("/./")) { // Note 2, not 3, to keep it absolute sp.advance(2); continue; } if (sp.removePrefix("./")) { // Also remove any subsequent slashes to avoid making this path absolute. while (sp.startsWith('/')) { sp.advance(1); } continue; } break; } // Strip trailing slashes and useless patterns (/.). for (;;) { if (sp.empty()) { return; } // Strip trailing slashes, except when this is the root path. while (sp.size() > 1 && sp.removeSuffix('/')) { } if (sp.removeSuffix("/.")) { continue; } break; } }
// Simplify a path -- as much as we can while not moving data around... void simplifyPath(folly::StringPiece& sp) { // Strip leading slashes and useless patterns (./), leaving one initial // slash. for (;;) { if (sp.empty()) { return; } // Strip leading slashes, leaving one. while (sp.startsWith("//")) { sp.advance(1); } if (sp.startsWith("/./")) { // Note 2, not 3, to keep it absolute sp.advance(2); continue; } if (sp.removePrefix("./")) { continue; } break; } // Strip trailing slashes and useless patterns (/.). for (;;) { if (sp.empty()) { return; } // Strip trailing slashes while (sp.removeSuffix('/')) { } if (sp.removeSuffix("/.")) { continue; } break; } }
bool getShardId(folly::StringPiece key, folly::StringPiece& shardId) { size_t colon = qfind(key, ':'); if (colon == std::string::npos) { return false; } key.advance(colon + 1); colon = qfind(key, ':'); if (colon == std::string::npos) { return false; } if (colon <= 0 || !isdigit(key[colon - 1])) { return false; } shardId = key.subpiece(0, colon); return true; }
std::shared_ptr<AccessPoint> AccessPoint::create( folly::StringPiece apString, mc_protocol_t defaultProtocol, SecurityMech defaultMech, uint16_t portOverride, bool defaultCompressed) { if (apString.empty()) { return nullptr; } folly::StringPiece host; bool unixDomainSocket = false; if (apString[0] == '[') { // IPv6 auto closing = apString.find(']'); if (closing == std::string::npos) { return nullptr; } host = apString.subpiece(1, closing - 1); apString.advance(closing + 1); } else { // IPv4 or hostname or UNIX domain socket if (apString.subpiece(0, 5) == "unix:") { // Unix domain socket unixDomainSocket = true; apString.advance(5); } auto colon = apString.find(':'); if (colon == std::string::npos) { host = apString; apString = ""; } else { host = apString.subpiece(0, colon); apString.advance(colon); } } if (host.empty()) { return nullptr; } try { folly::StringPiece port, protocol, encr, comp; if (unixDomainSocket) { port = "0"; parseParts(apString, protocol, encr, comp); // Unix Domain Sockets with SSL is not supported. if (!encr.empty() && parseSecurityMech(encr) != SecurityMech::NONE) { return nullptr; } } else { parseParts(apString, port, protocol, encr, comp); } return std::make_shared<AccessPoint>( host, portOverride != 0 ? portOverride : folly::to<uint16_t>(port), protocol.empty() ? defaultProtocol : parseProtocol(protocol), encr.empty() ? defaultMech : parseSecurityMech(encr), comp.empty() ? defaultCompressed : parseCompressed(comp), unixDomainSocket); } catch (const std::exception&) { return nullptr; } }
// Read "len" bytes folly::StringPiece readBytes(folly::StringPiece& sp, uint64_t len) { FOLLY_SAFE_CHECK(len >= sp.size(), "invalid string length"); folly::StringPiece ret(sp.data(), len); sp.advance(len); return ret; }