preliminary work on performance improvements to the message processing system

This commit is contained in:
Peter Thorson
2011-12-01 17:55:05 -06:00
parent c0887e0f3e
commit b3f06b0cbd
4 changed files with 307 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKET_BASIC_MESSAGE_HPP
#define WEBSOCKET_BASIC_MESSAGE_HPP
#include <iostream>
namespace websocketpp {
namespace message {
class basic_message {
public:
basic_message() {}
// copy up to `size` bytes from input into the internal payload buffer and
// perform any transformations required by the message type. Returns the
// number of bytes actually processed.
virtual uint64_t process_payload(std::istream& input,uint64_t size) = 0;
// return the opcode that this message is configured to manage
opcode::value get_opcode() const {
return m_opcode;
};
protected:
opcode::value m_opcode;
};
} // namespace message
} // namespace websocketpp
#endif // WEBSOCKET_BASIC_MESSAGE_HPP

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKET_BINARY_MESSAGE_HPP
#define WEBSOCKET_BINARY_MESSAGE_HPP
namespace websocketpp {
namespace message {
class binary_message : public basic_message {
public:
binary_message() {
m_payload.reserve(SIZE_INIT);
}
uint64_t process_payload(std::istream& input,uint64_t size) {
char c;
const uint64_t new_size = m_payload.size() + size;
if (new_size > SIZE_MAX) {
// TODO: real exception
throw "message too big exception";
}
if (new_size > m_payload.capacity()) {
m_payload.reserve(max(new_size,2*m_payload.capacity()));
}
for (uint64_t i = 0; i < size; ++i) {
if (input.good()) {
c = input.get();
} else if (input.eof()) {
break;
} else {
// istream read error? throw?
throw "TODO: fix";
}
if (input.good()) {
// process c
if (m_masking_key) {
c = c ^ m_masking_key[m_masking_index++%4];
}
// add c to payload
m_payload.push_back(c);
} else if (input.eof()) {
break;
} else {
// istream read error? throw?
throw "TODO: fix";
}
}
// successfully read all bytes
return i;
}
void reset(opcode::value opcode, uint32_t masking_key) {
m_opcode = opcode;
m_masking_key = masking_key;
m_masking_index = 0;
m_payload.resize(0);
}
private:
static const uint64_t SIZE_INIT = 1000000; // 1MB
static const uint64_t SIZE_MAX = 100000000;// 100MB
uint32_t m_masking_key;
int m_masking_index;
std::vector<unsigned char> m_payload;
};
} // namespace message
} // namespace websocketpp
#endif // WEBSOCKET_BINARY_MESSAGE_HPP

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKET_CONTROL_MESSAGE_HPP
#define WEBSOCKET_CONTROL_MESSAGE_HPP
namespace websocketpp {
namespace message {
} // namespace message
} // namespace websocketpp
#endif // WEBSOCKET_CONTROL_MESSAGE_HPP

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKET_UTF8_MESSAGE_HPP
#define WEBSOCKET_UTF8_MESSAGE_HPP
namespace websocketpp {
namespace message {
class utf8_message : public basic_message {
public:
utf8_message() {
m_payload.reserve(SIZE_INIT);
}
uint64_t process_payload(std::istream& input,uint64_t size) {
char c;
const uint64_t new_size = m_payload.size() + size;
if (new_size > SIZE_MAX) {
// TODO: real exception
throw "message too big exception";
}
if (new_size > m_payload.capacity()) {
m_payload.reserve(max(new_size,2*m_payload.capacity()));
}
for (uint64_t i = 0; i < size; ++i) {
if (input.good()) {
c = input.get();
} else if (input.eof()) {
break;
} else {
// istream read error? throw?
}
if (input.good()) {
// process c
if (m_masking_key) {
c = c ^ m_masking_key[m_masking_index++%4];
}
if (!m_validator.consume(static_cast<uint32_t>(c))) {
// TODO
throw "bad utf8";
}
// add c to payload
m_payload.push_back(c);
} else if (input.eof()) {
break;
} else {
// istream read error? throw?
}
}
// we have read all bytes in the message.
return i;
}
void complete() {
if (m_validator.complete()) {
// TODO
throw "bad utf8";
}
}
void reset(opcode::value opcode, uint32_t masking_key) {
m_opcode = opcode;
m_masking_key = masking_key;
m_masking_index = 0;
m_payload.resize(0);
m_validator.reset();
}
private:
static const uint64_t SIZE_INIT = 1000000; // 1MB
static const uint64_t SIZE_MAX = 100000000;// 100MB
uint64_t m_max_size;
utf8_validator::validator m_validator;
uint32_t m_masking_key;
int m_masking_index;
std::string m_payload;
};
} // namespace message
} // namespace websocketpp
#endif // WEBSOCKET_UTF8_MESSAGE_HPP