
This example illustrates how use data scramblers in GizmoDistribution. It also illustrates how to create and use customized data encoders. using GizmoDistribution. The example shows a simple byte substitution i.e. it just switches every character for another.
The source code can also be found in the examples directory of the GizmoDistribution installation.
.
00001 //***************************************************************************** 00002 // File : encoder.cpp 00003 // Module : encoder 00004 // Description : encoder (example application) 00005 // Author : Christian Andersson 00006 // Product : GizmoDistribution 00007 // 00008 // Copyright © 2004- Saab Training Systems AB, Sweden 00009 // 00010 // NOTE: GizmoDistribution is a toolkit used for implementing distributed 00011 // objects and events in C++ 00012 // 00013 // 00014 // Revision History... 00015 // 00016 // Who Date Description 00017 // 00018 // CAN 040803 Created file 00019 // 00020 //***************************************************************************** 00021 00022 // Includes 00023 #include "gzDistributionLibrary.h" 00024 00025 //------------------------- myCustomEncoderClass ----------------------------- 00026 /* 00027 This class illustrates how to create a customized data encoder/decoder 00028 using GizmoDistribution. The example shows a simple byte substitution 00029 i.e. it just swithes a character to another. 00030 */ 00031 00032 class myCustomEncoderClass : public gzDistEncoderInterface 00033 { 00034 public: 00035 // Constructor. By putting a gzDistEncoderInterface* as in argument it's possible to cascade connect several data scramblers. 00036 myCustomEncoderClass(gzDistEncoderInterface* parent = NULL) : gzDistEncoderInterface(parent) {} 00037 00038 // Destructor 00039 virtual ~myCustomEncoderClass() {} 00040 00041 // My custom encoding. 00042 // Here you can put any scramble algorithm. 00043 gzUInt onEncode(const gzUByte* source, gzInt sourceLength, gzArray<gzUByte>& destination) 00044 { 00045 // Set size of destination buffer. 00046 destination.setSize(sourceLength); 00047 00048 // Go through data and make a simple substitution. 00049 for (gzUInt i = 0; i < sourceLength; ++i) 00050 { 00051 destination[i] = source[i] ^ 123; // Substitute! 00052 } 00053 00054 // Return the length of my coded data. In this case the same as the source length. 00055 return destination.getSize(); 00056 } 00057 00058 // My custom decoding. 00059 gzUInt onDecode(const gzUByte* source, gzInt sourceLength, gzArray<gzUByte>& destination) 00060 { 00061 // Set size of destination buffer. 00062 destination.setSize(sourceLength); 00063 00064 for (gzUInt i = 0; i < sourceLength; ++i) 00065 { 00066 destination[i] = source[i] ^ 123; // Substitute back to original. 00067 } 00068 00069 // Return the length of my decoded data. In this case the same as the source length. 00070 return destination.getSize(); 00071 } 00072 }; 00073 00074 00075 //------------------------ myMessageTransceiver ------------------------------ 00076 00077 // A client that send events 00078 class myMessageTransceiver : public gzDistClientInterface 00079 { 00080 public: 00081 00082 // Constructor. 00083 myMessageTransceiver(); 00084 00085 // Destructor. 00086 virtual ~myMessageTransceiver(); 00087 00088 // Just send a message. 00089 gzVoid sendMessage(); 00090 00091 protected: 00092 00093 // Reimplemented from gzDistClientInterface 00094 gzVoid onEvent(gzDistEvent* event); 00095 00096 private: 00097 00098 // members 00099 00100 gzDistSessionPtr m_session; 00101 }; 00102 00103 00104 myMessageTransceiver::myMessageTransceiver() : gzDistClientInterface("Transceiver") 00105 { 00106 // Initialize client. 00107 initialize(); 00108 00109 // Create a global session. 00110 m_session = getSession("session", TRUE, TRUE); 00111 00112 // Join the session 00113 joinSession(m_session); 00114 00115 // Subscribe all events in session 00116 subscribeEvents(gzDistEvent::getClassType(), m_session); 00117 } 00118 00119 myMessageTransceiver::~myMessageTransceiver() 00120 { 00121 // Uninitialize client 00122 uninitialize(); 00123 } 00124 00125 gzVoid myMessageTransceiver::onEvent(gzDistEvent* event) 00126 { 00127 // Get the attribute value. 00128 gzString attributeValue = event->getAttributeString("message"); 00129 00130 // Add some information about where the message comes from. 00131 attributeValue += " From "; 00132 attributeValue += event->getAttributeString("id"); 00133 // Note: It's possible to get the number as a string event if it's stored as a number. 00134 // If you want to use the number, use getAttributeNumber(...) instead. 00135 00136 // Display it! 00137 GZMESSAGE(GZ_MESSAGE_NOTICE, attributeValue); 00138 } 00139 00140 gzVoid myMessageTransceiver::sendMessage() 00141 { 00142 // Create a event 00143 gzDistEvent* event = new gzDistEvent; 00144 00145 // Put some data in it. 00146 event->setAttributeValue("message", "Hello world!"); 00147 00148 // Put an id in the message. 00149 event->setAttributeValue("id", gzDistGetCurrentProcessID()); 00150 00151 // Send the event! 00152 sendEvent(event, m_session); 00153 } 00154 00155 //--------------------------------- main -------------------------------------- 00156 00157 // Application entry point 00158 int main(int argc, char* argv[]) 00159 { 00160 // Create the manager. 00161 gzDistManagerPtr manager = gzDistManager::getManager(TRUE); 00162 00163 // Create your customized encoder.... 00164 gzDistEncoderInterface* encoder = new myCustomEncoderClass(); 00165 00166 // ...or use a default encoder provided by GizmoDistribution. 00167 // gzDistEncoderInterface* encoder = new gzDistDefaultEncoder(12345); 00168 00169 // You can stack any type of data scramblers etc. by putting them as parent to each other. 00170 // For example you can add a compressor after the encoder. 00171 // In this case, the message will first go through the encoder class, and after that it will be compressed by the gzDistDefaultCompressor. 00172 // encoder = new gzDistDefaultCompressor(encoder); /* Just remove this line if you don't want the compressor. */ 00173 00174 // Create session channel using my customized encoder. 00175 gzDistRemoteChannel* sessionChannel = gzDistCreateDefaultSessionChannel(0, GZ_DIST_MULTICAST, encoder); 00176 00177 // Create server channel. You don't have to decode the server channel if you don't want to. 00178 // All relevant data is transmitted on the session channel anyway. 00179 gzDistRemoteChannel* serverChannel = gzDistCreateDefaultServerChannel(0, GZ_DIST_MULTICAST); 00180 00181 // Start the manager. 00182 manager->start(sessionChannel, serverChannel); 00183 00184 // Create transceiver client 00185 myMessageTransceiver* transceiver = new myMessageTransceiver; 00186 00187 // Print my ID. 00188 GZMESSAGE(GZ_MESSAGE_NOTICE, "My ID is %d", gzDistGetCurrentProcessID()); 00189 00190 // Sleep a while... 00191 gzSleep(5 * GZ_SLEEP_SECOND); 00192 00193 // Send some messages... 00194 for (gzUInt i = 0; i < 10; i++) 00195 { 00196 transceiver->sendMessage(); 00197 gzSleep(GZ_SLEEP_SECOND); 00198 } 00199 00200 // Delete the transceiver 00201 delete transceiver; 00202 00203 // shut down and release manager 00204 manager->shutDown(); 00205 manager = NULL; 00206 00207 return 0; 00208 } 00209