/// Check if this string ends with the given \p Suffix. bool StringRef::endswith(StringRef pSuffix) const { return (m_Length >= pSuffix.length() && 0 == compareMemory(end() - pSuffix.length(), pSuffix.data(), pSuffix.length())); }
bool String::startsWith(const StringRef& strRef) const { if (len < strRef.length()) { return false; } return ::memcmp(data(), strRef.data(), strRef.length()) == 0; }
bool String::endsWith(const StringRef& strRef) const { if (len < strRef.length()) { return false; } size_t refLen = strRef.length(); return ::memcmp(data() + len - refLen, strRef.data(), refLen) == 0; }
void split(const StringRef & txt, const StringRef & splitter, tStringVector & list, bool all) { unsigned int start = 0, end; list.clear(); while (start < txt.length()) { // dopóki jest co kopiowaæ end = txt.find(splitter, start); if (all || start != end) list.push_back(txt.substr(start, (end == -1 ? end : end - start)) ); if (end == -1) break; start = end + splitter.length(); } }
int TILParser::toInteger(StringRef s) { char* end = nullptr; long long val = strtol(s.c_str(), &end, 0); // FIXME: some proper error handling here? assert(end == s.c_str() + s.length() && "Could not parse string."); return static_cast<int>(val); }
bool ff::Value::CreateString(StringRef str, Value **ppValue) { assertRetVal(ppValue, false); if (!str.length()) { static Value::StaticValue s_data; static Value *s_val = nullptr; if (!s_val) { ScopeStaticValueAlloc scopeAlloc; if (!s_val) { s_val = s_data.AsValue(); s_val->Value::Value(); s_val->SetType(Type::String); s_val->InternalGetString().String::String(); } } *ppValue = s_val; } else { *ppValue = NewValueOneRef(); (*ppValue)->SetType(Type::String); (*ppValue)->InternalGetString().String::String(str); } return true; }
double TILParser::toDouble(StringRef s) { char* end = nullptr; double val = strtod(s.c_str(), &end); // FIXME: some proper error handling here? assert(end == s.c_str() + s.length() && "Could not parse string."); return val; }
int32 String::compare(const StringRef& strRef) const { size_t strRefLen = strRef.length(); const char* localData = data(); const char* strRefData = strRef.data(); // Emulate behavior of strcmp. That is, do comparison as if the StringRef // was nul terminated. if (len == strRefLen) { return ::memcmp(localData, strRefData, len); } else if (len < strRefLen) { int32 partial = ::memcmp(localData, strRefData, len); if (partial != 0) return partial; return 1; } else { int32 partial = ::memcmp(localData, strRefData, strRefLen); if (partial != 0) return partial; return -1; } }
String format(const StringRef& fmt, Args... args) { const size_t num_args = sizeof...(args); String converted[num_args]; convert_variadic_arguments_to_strings(converted, args...); StringBuffer buffer; const char* c = fmt.c_str(); bool escaping = false; for (size_t i = 0; i < fmt.length(); ++i) { switch (c[i]) { case '\\': { if (escaping) { escaping = false; buffer.push('\\'); continue; } escaping = true; continue; } case '{': { if (!escaping) { size_t idx = 0; bool valid = true; bool anything = false; size_t j = i + 1; for (; j < fmt.length(); ++j) { if (is_numeric(c[j])) { idx *= 10; idx += c[j] - '0'; anything = true; } else if (c[j] == '}') { break; } else { // non-numeric, non-terminator valid = false; break; } } if (valid && anything && idx < num_args) { buffer << converted[idx]; i = j; continue; } } } } escaping = false; buffer.push(c[i]); } return buffer.to_string(); }
const String operator+(const String& str, const StringRef& strRef) { String ret; ret.reserve(str.length() + strRef.length()); ret.append(str); ret.append(strRef); return ret; }
double Double::parseLocaleDouble(StringRef strRef, bool* ok) { std::stringstream ss; float ret; ss.write(strRef.data(), strRef.length()); ss >> ret; // Check that parsing did not fail and that every character was used if (!ss.fail() && (ss.tellg() == (std::streampos)strRef.length())) { Bool::setBool(ok, true); return ret; } else { Bool::setBool(ok, false); return 0.0; } }
static void createLines (Array<CodeDocumentLine*>& newLines, StringRef text) { String::CharPointerType t (text.text); int charNumInFile = 0; bool finished = false; while (! (finished || t.isEmpty())) { String::CharPointerType startOfLine (t); int startOfLineInFile = charNumInFile; int lineLength = 0; int numNewLineChars = 0; for (;;) { const juce_wchar c = t.getAndAdvance(); if (c == 0) { finished = true; break; } ++charNumInFile; ++lineLength; if (c == '\r') { ++numNewLineChars; if (*t == '\n') { ++t; ++charNumInFile; ++lineLength; ++numNewLineChars; } break; } if (c == '\n') { ++numNewLineChars; break; } } newLines.add (new CodeDocumentLine (startOfLine, t, lineLength, numNewLineChars, startOfLineInFile)); } jassert (charNumInFile == text.length()); }
String::String(const StringRef strRef) { len = strRef.length(); if (len < SMALL_STR_MAX) { strData = shortStr; reserved = SMALL_STR_LEN; ::memcpy(shortStr, strRef.data(), len); shortStr[len] = '\0'; } else { size_t refLen = strRef.length(); size_t newLen = refLen+1; reserved = newLen; strData = new char[newLen]; ::memcpy(strData, strRef.data(), refLen); strData[refLen] = '\0'; } }
// Tests basic chunked writer functionality bool test_chunkedwriter_basic() { WriteTestSource streamSource; ChunkedWriter writer; writer.init(&streamSource); HttpError err = writer.write("0123456789", 10); if (err != HttpError::Ok) { testf("Write failed"); return false; } err = writer.write("abcd", 4); if (err != HttpError::Ok) { testf("Write failed"); return false; } err = writer.close(); if (err != HttpError::Ok) { testf("Close failed"); return false; } const StringRef expected = "A\r\n" "0123456789\r\n" "4\r\n" "abcd\r\n" "0\r\n" "\r\n"; if (streamSource.dataWritten.size() != expected.length() || std::memcmp(&streamSource.dataWritten[0], expected.data(), expected.length()) != 0) { testf("Did not write expected data"); return false; } return true; }
void BinaryWriter::writeString(const StringRef& str, ln::TextEncoding* encoding) { if (encoding) { LN_NOTIMPLEMENTED(); return; } if (ln::Environment::byteOrder() == ByteOrder::BigEndian) { LN_NOTIMPLEMENTED(); return; } write(str.data(), str.length() * sizeof(Char)); }
size_t StringRef::findLastNotOf(StringRef charList, size_t from) const { std::bitset<1 << CHAR_BIT> charBits; for (size_t i = 0; charList.length() != i; ++i) charBits.set(static_cast<uchar>(charList[i])); for (size_t i = std::min(from, mLength) - 1; npos != i; --i) if (!charBits.test(static_cast<uchar>(mData[i]))) return i; return npos; }
bool unescapeUrl(const StringRef& str, String& dest) { size_t strLen = str.length(); ShortList<char, 256> buffer(strLen); buffer.addBlockBack(str.data(), strLen); // Delegate to the in-place function if (!unescapeUrlInPlace(buffer.data(), &strLen)) return false; dest.append(buffer.data(), strLen); return true; }
String Internet::combineUrl(const StringRef& url, const StringRef& parent) { Stamina::RegEx regex; if (url.empty() || regex.match("#^\\w+://#", url.c_str())) { return url; } // wyci¹gamy poszczególne elementy URLa if (!regex.match("#^(\\w+://[^/]+/)([^\\?]+/)?([^\\?/]*)(\\?.*)?$#", parent.c_str())) return url; if (url.a_str()[0] == '.' && (url.length() < 2 || url.a_str()[1] != '.')) { // (http://..../) + (katalog/) + url bez kropki return regex[1] + regex[2] + url.substr(1); } else if (url.a_str()[0] == '/') { // (http://..../) + url bez kreski return regex[1] + url.substr(1); } else { // (http://..../) + (katalog/) + url return regex[1] + regex[2] + url; } }
bool Bool::parseBool(StringRef strRef, bool* ok) { uint32 len = strRef.length(); if (len == 4) { bool ret = strRef.engEqualsIgnoreCase("true"); setBool(ok, ret); return ret; } else if (len == 5) { bool ret = strRef.engEqualsIgnoreCase("false"); setBool(ok, ret); return ret; } else { setBool(ok, false); return false; } }
String escapeUrl(const StringRef& str) { String res; size_t strPos = 0; size_t strLen = str.length(); while (strPos < strLen) { unsigned char uc = (unsigned char)str.charAt(strPos); if (safeUrlChars[uc]) { res.appendChar(uc); } else if (uc == ' ') { res.appendChar('+'); } else { unsigned char hexHigh = uc / 16; unsigned char hexLow = uc % 16; char hex1 = hexHigh > 9 ? hexHigh + ('A'-10) : hexHigh + '0'; char hex2 = hexLow > 9 ? hexLow + ('A'-10) : hexLow + '0'; res.appendChar('%'); res.appendChar(hex1); res.appendChar(hex2); } strPos++; } return res; }
bool test_http1_1_keepalive() { Socket acceptSocket; SocketError socketErr; HttpServer server; HttpError serverError; std::mutex serverMutex; std::condition_variable serverCond; bool isShutdown = false; std::tie(acceptSocket, socketErr) = getAcceptingSocket(Addrinfo::getLoopback(INet::Protocol::Ipv6, 0)); if (socketErr != SocketError::Ok) { testf("Failed to bind socket for accept with: %d", socketErr); return false; } uint16_t boundPort = acceptSocket.getLocalAddress().getPort(); StreamSourceSocket streamSource(std::move(acceptSocket)); server.addHandler("/index.html", [](HttpRequest& request, HttpResponse& response) { response.setStatus(200, "OK"); response.addHeader("Content-Length", "11"); HttpOutputStream* outputStream; std::tie(outputStream, std::ignore) = response.getOutputStream(); outputStream->write("Hello World", 11); outputStream->close(); }); Async::runAsync([&streamSource, &server, &serverError, &serverMutex, &serverCond, &isShutdown] { HttpError err = server.start(&streamSource); std::unique_lock<std::mutex> lock(serverMutex); isShutdown = true; serverError = err; serverCond.notify_one(); }); std::vector<StringRef> requests = { "GET /index.html HTTP/1.1\r\n" "Connection: keep-alive\r\n" "Host: localhost\r\n" "\r\n" "GET /index.html HTTP/1.1\r\n" "Host: localhost\r\n" "\r\n" "GET /index.html HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: close\r\n" "\r\n", "GET /index.html HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: close\r\n" "\r\n" "GET /index.html HTTP/1.1\r\n" "Host: localhost\r\n" "\r\n", }; std::vector<StringRef> expectedResponses = { "HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World" "HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World" "HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World", "HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World", }; for (size_t i = 0; i < requests.size(); i++) { StringRef request = requests[i]; StringRef expectedResponse = expectedResponses[i]; char responseBuffer[1024]; Socket requestSocket; std::tie(requestSocket, socketErr) = getConnectedSocket(Addrinfo::getLoopback(INet::Protocol::Ipv6, boundPort)); if (socketErr != SocketError::Ok) { testf("Failed to connect to HTTP socket with: %d", socketErr); return false; } socketErr = requestSocket.write(request.data(), request.length()); if (socketErr != SocketError::Ok) { testf("Failed to write to HTTP socket with: %d", socketErr); return false; } uint32_t totalBytesRead = 0; std::tie(totalBytesRead, socketErr) = readFully(&requestSocket, responseBuffer, sizeof(responseBuffer)); if (socketErr != SocketError::Ok) { testf("Failed to read from HTTP socket with: %d", socketErr); return false; } if (StringRef(responseBuffer, totalBytesRead) != expectedResponse) { testf("Did not receive expected response. Got:\n%.*s", (size_t)totalBytesRead, responseBuffer); return false; } } server.shutdown(); // Wait for server shutdown and check its error std::unique_lock<std::mutex> lock(serverMutex); serverCond.wait(lock, [&isShutdown] {return isShutdown; }); if (serverError != HttpError::Ok) { testf("Failed to start HTTP server with: %d", serverError); return false; } return true; }
bool test_http1_1_chunked_request() { Socket acceptSocket; SocketError socketErr; HttpServer server; HttpError serverError; std::mutex serverMutex; std::condition_variable serverCond; bool isShutdown = false; bool gotExpectedPost = false; HttpError postError = HttpError::Ok; bool hadCorrectHeader = false; std::tie(acceptSocket, socketErr) = ::getAcceptingSocket(Addrinfo::getLoopback(INet::Protocol::Ipv6, 0)); if (socketErr != SocketError::Ok) { testf("Failed to bind socket for accept with: %d", socketErr); return false; } uint16_t boundPort = acceptSocket.getLocalAddress().getPort(); StreamSourceSocket streamSource(std::move(acceptSocket)); server.addHandler("/formthingy", [&gotExpectedPost, &postError, &hadCorrectHeader](HttpRequest& request, HttpResponse& response) { char readBuffer[1024]; HttpInputStream& httpInputStream = request.getInputStream(); HttpError readErr; uint32_t readBytes; uint32_t totalRead = 0; do { std::tie(readBytes, readErr) = httpInputStream.read(readBuffer + totalRead, 3); // Intentionally small reads totalRead += readBytes; } while (readErr == HttpError::Ok); if (readErr != HttpError::Eof) { postError = readErr; return; } postError = httpInputStream.close(); const StringRef postData = "Some form post data"; if (totalRead != postData.length()) { gotExpectedPost = false; } else { gotExpectedPost = std::memcmp(postData.data(), readBuffer, postData.length()) == 0; } StringRef transferEncodingHeader; bool hasHeader; std::tie(transferEncodingHeader, hasHeader) = request.getHeader("Transfer-Encoding"); if (!hasHeader) { hadCorrectHeader = false; } else { hadCorrectHeader = transferEncodingHeader.equals("chunked"); } response.setStatus(200, "OK"); }); Async::runAsync([&streamSource, &server, &serverError, &serverMutex, &serverCond, &isShutdown] { HttpError err = server.start(&streamSource); std::unique_lock<std::mutex> lock(serverMutex); isShutdown = true; serverError = err; serverCond.notify_one(); }); StringRef request = "POST /formthingy HTTP/1.1\r\n" "Host: localhost\r\n" "Transfer-Encoding: chunked\r\n" "Connection: close\r\n" "\r\n" "5\r\n" "Some \r\n" "e\r\n" "form post data\r\n" "0\r\n" "\r\n"; StringRef expectedResponse = "HTTP/1.1 200 OK\r\n\r\n"; char responseBuffer[1024]; Socket requestSocket; std::tie(requestSocket, socketErr) = getConnectedSocket(Addrinfo::getLoopback(INet::Protocol::Ipv6, boundPort)); if (socketErr != SocketError::Ok) { testf("Failed to connect to HTTP socket with: %d", socketErr); return false; } socketErr = requestSocket.write(request.data(), request.length()); if (socketErr != SocketError::Ok) { testf("Failed to write to HTTP socket with: %d", socketErr); return false; } uint32_t totalBytesRead = 0; std::tie(totalBytesRead, socketErr) = readFully(&requestSocket, responseBuffer, sizeof(responseBuffer)); if (socketErr != SocketError::Ok) { testf("Failed to read from HTTP socket with: %d", socketErr); return false; } if (StringRef(responseBuffer, totalBytesRead) != expectedResponse) { testf("Did not receive expected response. Got:\n%.*s", totalBytesRead, responseBuffer); return false; } server.shutdown(); // Wait for server shutdown and check its error std::unique_lock<std::mutex> lock(serverMutex); serverCond.wait(lock, [&isShutdown] {return isShutdown; }); if (serverError != HttpError::Ok) { testf("Failed to start HTTP server with: %d", serverError); return false; } if (!gotExpectedPost) { testf("Did not read back expected post data"); return false; } if (postError != HttpError::Ok) { testf("Received error when reading post data: %d", postError); return false; } if (!hadCorrectHeader) { testf("Http request did not have expected Transfer-Encoding header"); return false; } return true; }
ptrdiff_t StringRef::lastIndexOf(const StringRef strRef, size_t endIndex) const { assert(endIndex >= 0 && endIndex <= len); size_t strRefLen = strRef.length(); // Deal with zero length strings by always reporting a match at index // zero. Nothing is always present. if (strRefLen == 0) { return 0; } ptrdiff_t searchLen = (ptrdiff_t)endIndex - (ptrdiff_t)strRefLen; // Return -1 for overlong strings as there can be no match. if (searchLen < 0) { return -1; } // For short search areas, brute force. It's not worth building a table // to speed things up. if (searchLen < 256) { for (ptrdiff_t i = searchLen; i >= 0; i--) { bool match = true; for (size_t j = 0; match && j < strRefLen; j++) { if (strData[i+j] != strRef.strData[j]) match = false; } if (match) return i; } return -1; } // Like indexOf, using the Boyer-Moore-Horspool algorithm, but reversed. // This also changes how the 'skip' indexes are generated. const char* strRefData = strRef.strData; size_t strRefLast = strRefLen - 1; // Create an array of "skip" offsets when searching the string size_t skip[255]; for (uint32_t i = 0; i < 255; i++) { skip[i] = strRefLen; } for (uint32_t i = 0; i < strRefLen; i++) { skip[(unsigned)strRefData[i]] = strRefLast - (strRefLast - i); } // Do the reverse search const char* searchStart = strData; const char* searchPtr = searchStart + endIndex - strRefLen; while (searchPtr >= searchStart) { if (std::memcmp(searchPtr, strRefData, strRefLen) == 0) { return searchPtr - searchStart; } searchPtr -= skip[(uint8_t)searchPtr[0]]; } // No match found return -1; }
ptrdiff_t StringRef::indexOf(const StringRef strRef, size_t startIndex) const { assert(startIndex >= 0 && startIndex <= len); size_t strRefLen = strRef.length(); // Deal with zero length strings by always reporting a match at index // zero. Nothing is always present. if (strRefLen == 0) { return 0; } size_t searchLen = len - startIndex; // Return -1 for overlong strings as there can be no match. if (strRefLen > searchLen) { return -1; } // For short search areas, brute force. It's not worth building a table // to speed things up. if (searchLen < 256) { for (size_t i = startIndex; i < len - strRefLen + 1; i++) { bool match = true; for (size_t j = 0; match && j < strRefLen; j++) { if (strData[i+j] != strRef.strData[j]) match = false; } if (match) return i; } return -1; } // In the general case, use the Boyer-Moore-Horspool algorithm. This has // average case of O(n) and worst case O(n*m), which is worse than the // Boyer-Moore algorithm, but has the advantage of not requiring memory // allocation. const char* strRefData = strRef.strData; size_t endIndex = strRefLen - 1; // Create an array of "skip" offsets when searching the string size_t badCharSkip[256]; for (uint32_t i = 0; i < 256; i++) { badCharSkip[i] = strRefLen; } for (uint32_t i = 0; i < endIndex; i++) { badCharSkip[(unsigned)strRefData[i]] = endIndex - i; } const char* searchEnd = strData + len - strRefLen; const char* searchPtr = strData + startIndex; while (searchPtr <= searchEnd) { for (size_t scan = endIndex; searchPtr[scan] == strRef.strData[scan]; scan--) { if (scan == 0) // If complete match return searchPtr - strData; } searchPtr += badCharSkip[(uint8_t)searchPtr[endIndex]]; } // No match found return -1; }
inline bool ends_with(const StringRef& input, const StringRef& target) { return input.length() >= target.length() && cass::compare(input.data() + (input.length() - target.length()), target.data(), target.size(), StringRef::IsEqual()) == 0; }
void AioFile::open(StringRef fileName, OpenMode_Enum mode, int permissions) { // TODO: Properly convert filename size_t fileNameLen = fileName.length(); ShortList<char, 256> charBuf(fileNameLen+1); charBuf.addBlockBack(fileName.data(), fileNameLen); charBuf.addBack('\0'); // Don't inherit any fd int flags = O_CLOEXEC; // Build permission flags // It's legal, if normally pointless, to have no read or write access. // You can still access the file length. if ((permissions & IO_READ_ACCESS) && (permissions & IO_WRITE_ACCESS)) { flags |= O_RDWR; } else if (permissions & IO_READ_ACCESS) { flags |= O_WRONLY; } else if (permissions & IO_WRITE_ACCESS) { flags |= O_RDONLY; } // Build file creation flags switch (mode) { case OPEN_MODE_CREATE_ONLY: flags |= O_CREAT; flags |= O_EXCL; break; case OPEN_MODE_CREATE_OR_OPEN: flags |= O_CREAT; break; case OPEN_MODE_CREATE_OR_TRUNCATE: flags |= O_CREAT; flags |= O_TRUNC; break; case OPEN_MODE_OPEN_ONLY: // No extra flags break; case OPEN_MODE_TRUNCATE_ONLY: flags |= O_TRUNC; break; } _fd = UnixUtil::sys_open(charBuf.data(), flags, 0666); if (_fd == -1) { Error error = UnixUtil::getError(errno, "open", "AioFile::open"); throw IOException(error); } }
inline StringRef TILParser::copyStr(StringRef s) { // Put all strings in the string arena, which must survive // for the duration of the compile. char* temp = reinterpret_cast<char*>(stringArena_.allocate(s.length()+1)); return copyStringRef(temp, s); }
/// Check if this string starts with the given \p Prefix. bool StringRef::startswith(StringRef pPrefix) const { return (m_Length >= pPrefix.length() && 0 == compareMemory(m_Data, pPrefix.data(), pPrefix.length())); }
int Connection::write(StringRef buf){ return write(buf->c_str(), buf->length()); }
bool Request::send(const StringRef& headers, const StringRef& data) { return HttpSendRequest(_hRequest, headers.c_str(), headers.length(), (void*)data.c_str(), data.length())!=0; }