#include #include #include #include #include #include #include #include #include #include "util/util.h" #include "note/070423/SylphideStream.h" #include "note/070423/SylphideProcessor.h" using namespace std; class ProtocolTestSuite : public Test::Suite{ string src; public: ProtocolTestSuite() : src() { TEST_ADD(ProtocolTestSuite::test_encode_decode); TEST_ADD(ProtocolTestSuite::test_encode_decode2); } protected: template static void raw_out(_Elem &buf, unsigned int length){ cout << hex; for(int i(0); length--; i++){ cout << setfill('0') << setw(2) << (unsigned int)((unsigned char)buf[i]) << ' '; } cout << dec << endl; } template static void raw_out(_Elem &buf){ raw_out(buf, buf.size()); } virtual void setup(){ rand_init(0); src.clear(); for(int i(0); i < 0x1000; i++){ src.push_back((char)(rand() & 0xFF)); } raw_out(src, src.length()); } virtual void tear_down(){ } private: void test_encode_decode(){ stringstream pipe; SylphideOStream out(pipe); SylphideIStream in(pipe); string dist; vector payload_sizes_orig, payload_sizes; for(int i(0); i < src.length(); ){ unsigned int payload_size( min(src.length() - i, ((unsigned int)rand() & 0x3F) + 1)); out.set_payload_size(payload_size); out << src.substr(i, payload_size); i += payload_size; payload_sizes_orig.push_back(payload_size); } while(true){ char buf[0x40]; buf[0] = in.get(); if(!in.good()){break;} unsigned int payload_size(in.readsome(&buf[1], sizeof(buf) - 1) + 1); dist.append(buf, payload_size); payload_sizes.push_back(payload_size); } raw_out(dist, dist.length()); //raw_out(pipe.str(), pipe.str().length()); for(vector::iterator it1(payload_sizes_orig.begin()), it2(payload_sizes.begin()); it1 != payload_sizes_orig.end(); ++it1, ++it2){ TEST_ASSERT(*it1 == *it2); } TEST_ASSERT(strcmp(src.c_str(), dist.c_str()) == 0); } class StreamProcessor : public AbstractSylphideProcessor { public: unsigned int invoked; protected: typedef AbstractSylphideProcessor super_t; typedef Sylphide_Packet_Observer observer_t; struct Handler : public observer_t { bool previous_seek; unsigned int invoked; vector &payload; Handler(vector &_payload) : observer_t(0x400), invoked(0), payload(_payload) { previous_seek = ready(); } ~Handler(){} void operator()(const observer_t &observer){ if(!observer.validate()){return;} cout << payload.size() << "," << observer.current_payload_size() << "; "; raw_out(*this, observer.current_packet_size()); string s(observer.current_payload_size(), 0); SylphideProtocol::Decorder::extract_payload( *this, s, observer.current_packet_size(), observer.current_payload_size()); payload.push_back(s); } // override //bool seek_next(){return false;} } handler; public: StreamProcessor(vector &_payload) : super_t(), invoked(0), handler(_payload) { } virtual ~StreamProcessor(){} void process(char *buffer, int read_count){ super_t::process_packet( buffer, read_count, handler, handler.previous_seek, handler); } }; vector decode2_loop( const unsigned int &buf_size, const string &orig){ char *buf(new char[buf_size + 1]); vector payload; StreamProcessor processor(payload); buf[0] = 'D'; int buf_index(1); for(string::const_iterator it(orig.begin()); it != orig.end(); it++){ buf[buf_index++] = *it; if(buf_index >= buf_size + 1){ processor.process(buf, buf_size + 1); buf_index = 1; } } if((buf_index < buf_size + 1) && (buf_index > 1)){ processor.process(buf, buf_size + 1); } delete [] buf; return payload; } void test_encode_decode2(){ stringstream pipe; SylphideOStream out(pipe); vector payload_orig; for(int i(0); i < src.length(); ){ unsigned int payload_size( min(src.length() - i, ((unsigned int)rand() & 0x3F) + 1)); out.set_payload_size(payload_size); string s(src.substr(i, payload_size)); //raw_out(s); payload_orig.push_back(s); out << payload_orig.back(); i += payload_size; } for(int buf_size(1); buf_size <= 0x20; buf_size++){ vector payload(decode2_loop(buf_size, pipe.str())); int i(0); for(vector::iterator it1(payload_orig.begin()), it2(payload.begin()); it1 != payload_orig.end(); ++it1, ++it2){ cout << "(" << i++ << ")" << it1->size() << ", " << it2->size() << endl; if(*it1 != *it2){ raw_out(*it1); raw_out(*it2); TEST_FAIL(""); } } } } }; bool run_tests(){ ProtocolTestSuite test_suits; Test::TextOutput output(Test::TextOutput::Verbose); return test_suits.run(output, false); // Note the 'false' parameter } int main(){run_tests();return 0;}