const std::vector<std::pair<fbstring, fbstring>>& Uri::getQueryParams() { if (!query_.empty() && queryParams_.empty()) { // Parse query string static const boost::regex queryParamRegex( "(^|&)" /*start of query or start of parameter "&"*/ "([^=&]*)=?" /*parameter name and "=" if value is expected*/ "([^=&]*)" /*parameter value*/ "(?=(&|$))" /*forward reference, next should be end of query or start of next parameter*/); boost::cregex_iterator paramBeginItr( query_.data(), query_.data() + query_.size(), queryParamRegex); boost::cregex_iterator paramEndItr; for (auto itr = paramBeginItr; itr != paramEndItr; itr++) { if (itr->length(2) == 0) { // key is empty, ignore it continue; } queryParams_.emplace_back( fbstring((*itr)[2].first, (*itr)[2].second), // parameter name fbstring((*itr)[3].first, (*itr)[3].second) // parameter value ); } } return queryParams_; }
fbstring exception_wrapper::what() const { if (item_) { return exceptionStr(*item_); } else if (eptr_) { return estr_; } else { return fbstring(); } }
fbstring exception_wrapper::class_name() const { if (item_) { auto& i = *item_; return demangle(typeid(i)); } else if (eptr_) { return ename_; } else { return fbstring(); } }
fbstring demangle(const char* name) { int status; size_t len = 0; // malloc() memory for the demangled type name char* demangled = abi::__cxa_demangle(name, nullptr, &len, &status); if (status != 0) { return name; } // len is the length of the buffer (including NUL terminator and maybe // other junk) return fbstring(demangled, strlen(demangled), len, AcquireMallocatedString()); }