Mercurial > hg > orthanc
diff OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp @ 4652:0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 05 May 2021 11:50:14 +0200 |
parents | c1f36fd13730 |
children | 3d5d6e2dcf3f |
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Wed May 05 09:47:39 2021 +0200 +++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Wed May 05 11:50:14 2021 +0200 @@ -37,10 +37,11 @@ namespace Orthanc { static void ParseHeaders(MultipartStreamReader::HttpHeaders& headers, - StringMatcher::Iterator start, - StringMatcher::Iterator end) + const char* start, + const char* end /* exclusive */) { - std::string tmp(start, end); + assert(start <= end); + std::string tmp(start, end - start); std::vector<std::string> lines; Toolbox::TokenizeString(lines, tmp, '\n'); @@ -108,8 +109,13 @@ std::string corpus; buffer_.Flatten(corpus); - StringMatcher::Iterator current = corpus.begin(); - StringMatcher::Iterator corpusEnd = corpus.end(); + if (corpus.empty()) + { + return; + } + + const char* current = corpus.c_str(); + const char* corpusEnd = corpus.c_str() + corpus.size(); if (state_ == State_UnusedArea) { @@ -128,15 +134,18 @@ else { // We have not seen the end of the unused area yet - buffer_.AddChunk(current, corpusEnd); + assert(current <= corpusEnd); + buffer_.AddChunk(current, corpusEnd - current); return; } } for (;;) { + assert(current <= corpusEnd); + size_t patternSize = boundaryMatcher_.GetPattern().size(); - size_t remainingSize = std::distance(current, corpusEnd); + size_t remainingSize = corpusEnd - current; if (remainingSize < patternSize + 2) { break; // Not enough data available @@ -155,7 +164,7 @@ "Garbage between two items in a multipart stream"); } - StringMatcher::Iterator start = current + patternSize + 2; + const char* start = current + patternSize + 2; if (!headersMatcher_.Apply(start, corpusEnd)) { @@ -170,7 +179,8 @@ { if (boundaryMatcher_.Apply(headersMatcher_.GetMatchEnd(), corpusEnd)) { - size_t d = std::distance(headersMatcher_.GetMatchEnd(), boundaryMatcher_.GetMatchBegin()); + assert(headersMatcher_.GetMatchEnd() <= boundaryMatcher_.GetMatchBegin()); + size_t d = boundaryMatcher_.GetMatchBegin() - headersMatcher_.GetMatchEnd(); if (d <= 1) { throw OrthancException(ErrorCode_NetworkProtocol); @@ -186,14 +196,14 @@ } } - // Explicit conversion to avoid warning about signed vs. unsigned comparison - std::iterator_traits<StringMatcher::Iterator>::difference_type d = contentLength + 2; - if (d > std::distance(headersMatcher_.GetMatchEnd(), corpusEnd)) + // "static_cast<>" to avoid warning about signed vs. unsigned comparison + assert(headersMatcher_.GetMatchEnd() <= corpusEnd); + if (contentLength + 2 > static_cast<size_t>(corpusEnd - headersMatcher_.GetMatchEnd())) { break; // Not enough data available to have a full part } - const char* p = headersMatcher_.GetPointerEnd() + contentLength; + const char* p = headersMatcher_.GetMatchEnd() + contentLength; if (p[0] != '\r' || p[1] != '\n') { @@ -201,13 +211,14 @@ "No endline at the end of a part"); } - handler_->HandlePart(headers, headersMatcher_.GetPointerEnd(), contentLength); + handler_->HandlePart(headers, headersMatcher_.GetMatchEnd(), contentLength); current = headersMatcher_.GetMatchEnd() + contentLength + 2; } if (current != corpusEnd) { - buffer_.AddChunk(current, corpusEnd); + assert(current < corpusEnd); + buffer_.AddChunk(current, corpusEnd - current); } }