#include "net/tools/balsa/balsa_frame.h"
+// Visual C++ defines _M_IX86_FP as 2 if the /arch:SSE2 compiler option is
+// specified.
+#if !defined(__SSE2__) && _M_IX86_FP == 2
+#define __SSE2__ 1
+#endif
+
#include <assert.h>
#if __SSE2__
#include <emmintrin.h>
#endif // __SSE2__
-#include <strings.h>
#include <limits>
#include <string>
#include "net/tools/balsa/split.h"
#include "net/tools/balsa/string_piece_utils.h"
+#if defined(COMPILER_MSVC)
+#include <intrin.h>
+#include <string.h>
+
+#pragma intrinsic(_BitScanForward)
+
+static int ffs(int i) {
+ unsigned long index;
+ return _BitScanForward(&index, i) ? index + 1 : 0;
+}
+
+#define strncasecmp _strnicmp
+#else
+#include <strings.h>
+#endif
+
namespace net {
// Constants holding some header names for headers which can affect the way the
}
if (is_request_) {
- int version_length =
+ size_t version_length =
headers_->whitespace_4_idx_ - headers_->non_whitespace_3_idx_;
visitor_->ProcessRequestFirstLine(
begin + headers_->non_whitespace_1_idx_,
// The last line is always just a newline (and is uninteresting).
const Lines::size_type lines_size_m1 = lines_.size() - 1;
#if __SSE2__
- const __v16qi colons = { ':', ':', ':', ':', ':', ':', ':', ':',
- ':', ':', ':', ':', ':', ':', ':', ':'};
+ const __m128i colons = _mm_set1_epi8(':');
const char* header_lines_end_m16 = headers_->OriginalHeaderStreamEnd() - 16;
#endif // __SSE2__
const char* current = stream_begin + lines_[1].first;
while (current < header_lines_end_m16) {
__m128i header_bytes =
_mm_loadu_si128(reinterpret_cast<const __m128i *>(current));
- __m128i colon_cmp =
- _mm_cmpeq_epi8(header_bytes, reinterpret_cast<__m128i>(colons));
+ __m128i colon_cmp = _mm_cmpeq_epi8(header_bytes, colons);
int colon_msk = _mm_movemask_epi8(colon_cmp);
if (colon_msk == 0) {
current += 16;
}
}
-// TODO(phython): Fix this function to properly deal with quoted values.
-// E.g. ";;foo", "\";;\"", or \"aa;
-// The last example, the semi-colon is a separator between extensions.
-void ProcessChunkExtensionsGoogle3(const char* input, size_t size,
- BalsaHeaders* extensions) {
- std::vector<base::StringPiece> key_values;
- SplitStringPieceToVector(base::StringPiece(input, size), ";",
- &key_values, true);
- for (unsigned int i = 0; i < key_values.size(); ++i) {
- base::StringPiece key = key_values[i].substr(0, key_values[i].find('='));
- base::StringPiece value;
- if (key.length() < key_values[i].length()) {
- value = key_values[i].substr(key.length() + 1);
- // Remove any leading and trailing whitespace.
- StringPieceUtils::RemoveWhitespaceContext(&value);
-
- // Strip quotation marks if they exist.
- if (!value.empty() && value[0] == '"')
- value.remove_prefix(1);
- if (!value.empty() && value[value.length() - 1] == '"')
- value.remove_suffix(1);
- }
-
- // Strip the key whitespace after checking that there is a value.
- StringPieceUtils::RemoveWhitespaceContext(&key);
- extensions->AppendHeader(key, value);
- }
-}
-
} // anonymous namespace
void BalsaFrame::ProcessChunkExtensions(const char* input, size_t size,
BalsaHeaders* extensions) {
-#if 0
- ProcessChunkExtensionsGoogle3(input, size, extensions);
-#else
ProcessChunkExtensionsManual(base::StringPiece(input, size), extensions);
-#endif
}
void BalsaFrame::ProcessHeaderLines() {
#if __SSE2__
{
const char* const message_end_m16 = message_end - 16;
- __v16qi newlines = { '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
- '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' };
+ __m128i newlines = _mm_set1_epi8('\n');
while (message_current < message_end_m16) {
// What this does (using compiler intrinsics):
//
__m128i msg_bytes =
_mm_loadu_si128(const_cast<__m128i *>(
reinterpret_cast<const __m128i *>(message_current)));
- __m128i newline_cmp =
- _mm_cmpeq_epi8(msg_bytes, reinterpret_cast<__m128i>(newlines));
+ __m128i newline_cmp = _mm_cmpeq_epi8(msg_bytes, newlines);
int newline_msk = _mm_movemask_epi8(newline_cmp);
if (newline_msk == 0) {
message_current += 16;
return current - input;
}
-const uint32 BalsaFrame::kValidTerm1;
-const uint32 BalsaFrame::kValidTerm1Mask;
-const uint32 BalsaFrame::kValidTerm2;
-const uint32 BalsaFrame::kValidTerm2Mask;
-
} // namespace net