Skip to content

Commit

Permalink
preliminary work on performance improvements to the message processin…
Browse files Browse the repository at this point in the history
…g system
  • Loading branch information
Peter Thorson committed Dec 1, 2011
1 parent c0887e0 commit b3f06b0
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/messages/basic_message.hpp
Original file line number Diff line number Diff line change
@@ -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
100 changes: 100 additions & 0 deletions src/messages/binary_message.hpp
Original file line number Diff line number Diff line change
@@ -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
37 changes: 37 additions & 0 deletions src/messages/control_message.hpp
Original file line number Diff line number Diff line change
@@ -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
114 changes: 114 additions & 0 deletions src/messages/utf8_message.hpp
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit b3f06b0

Please sign in to comment.