00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdlib.h>
00018
00019 #include <spl/net/Packet.h>
00020 #include <spl/net/PacketBuilder.h>
00021 #include <spl/text/StringBuffer.h>
00022 #include <spl/io/ThreadedPacketStream.h>
00023
00024 PacketListenerDelegateDispatch::~PacketListenerDelegateDispatch()
00025 {
00026 }
00027
00028 void PacketListenerDelegateDispatch::Add(IPacketListener *l)
00029 {
00030 m_onDataInt64 += DelegateOneParameter<IPacketListener, int64>::Create(l, &IPacketListener::IPacket_OnData);
00031 m_onDataInt32 += DelegateOneParameter<IPacketListener, int32>::Create(l, &IPacketListener::IPacket_OnData);
00032 m_onDataInt16 += DelegateOneParameter<IPacketListener, int16>::Create(l, &IPacketListener::IPacket_OnData);
00033 m_onDataByte += DelegateOneParameter<IPacketListener, byte>::Create(l, &IPacketListener::IPacket_OnData);
00034 m_onDataBool += DelegateOneParameter<IPacketListener, bool>::Create(l, &IPacketListener::IPacket_OnData);
00035 m_onDataDouble += DelegateOneParameter<IPacketListener, double>::Create(l, &IPacketListener::IPacket_OnData);
00036 m_onDataString += DelegateOneParameter<IPacketListener, StringPtr>::Create(l, &IPacketListener::IPacket_OnData);
00037 m_onDataBin += DelegateTwoParameter<IPacketListener, const Vector<byte>&, const int>::Create(l, &IPacketListener::IPacket_OnData);
00038 m_onDataDtm += DelegateOneParameter<IPacketListener, const DateTime&>::Create(l, &IPacketListener::IPacket_OnData);
00039 m_onDataDate += DelegateOneParameter<IPacketListener, const Date&>::Create(l, &IPacketListener::IPacket_OnData);
00040 m_onError += DelegateOneParameter<IPacketListener, const String&>::Create(l, &IPacketListener::IStreamRead_OnError);
00041 m_onClose += Delegate<IPacketListener>::Create(l, &IPacketListener::IStreamRead_OnClose);
00042 }
00043
00044 #ifdef DEBUG
00045 void PacketListenerDelegateDispatch::ValidateMem() const
00046 {
00047 m_onDataInt64.ValidateMem();
00048 m_onDataInt32.ValidateMem();
00049 m_onDataInt16.ValidateMem();
00050 m_onDataByte.ValidateMem();
00051 m_onDataBool.ValidateMem();
00052 m_onDataDouble.ValidateMem();
00053 m_onDataString.ValidateMem();
00054 m_onDataBin.ValidateMem();
00055 m_onDataDtm.ValidateMem();
00056 m_onDataDate.ValidateMem();
00057 m_onError.ValidateMem();
00058 m_onClose.ValidateMem();
00059 }
00060
00061 void PacketListenerDelegateDispatch::CheckMem() const
00062 {
00063 m_onDataInt64.CheckMem();
00064 m_onDataInt32.CheckMem();
00065 m_onDataInt16.CheckMem();
00066 m_onDataByte.CheckMem();
00067 m_onDataBool.CheckMem();
00068 m_onDataDouble.CheckMem();
00069 m_onDataString.CheckMem();
00070 m_onDataBin.CheckMem();
00071 m_onDataDtm.CheckMem();
00072 m_onDataDate.CheckMem();
00073 m_onError.CheckMem();
00074 m_onClose.CheckMem();
00075 }
00076 #endif
00077
00078 Packet::Packet()
00079 : m_buf(),
00080 m_readPacketReady(false),
00081 m_abuf(1)
00082 {
00083 Clear();
00084 }
00085
00086 Packet::Packet(const Packet& pkt)
00087 : m_buf(pkt.m_buf),
00088 m_readPacketReady(pkt.m_readPacketReady),
00089 m_readpos(pkt.m_readpos),
00090 m_abuf(1)
00091 {
00092 }
00093
00094 Packet::~Packet()
00095 {
00096 }
00097
00098 Packet& Packet::operator =(const Packet& pkt)
00099 {
00100 Clear();
00101
00102 m_buf = pkt.m_buf;
00103 m_readPacketReady = pkt.m_readPacketReady;
00104 m_readpos = pkt.m_readpos;
00105
00106 return *this;
00107 }
00108
00109 void Packet::Clear()
00110 {
00111 m_buf.Clear();
00112 m_readpos = 0;
00113 #if LITTLE_ENDIAN
00114 m_buf.Add(1);
00115 #else
00116 m_buf.Add(0);
00117 #endif
00118 m_buf.Add(0);
00119 m_buf.Add(0);
00120
00121 ASSERT(0 == m_buf.ElementAt(1));
00122 ASSERT(0 == m_buf.ElementAt(2));
00123 }
00124
00125 void Packet::SendPacket(spl::IStream& sock)
00126 {
00127 int16 count = m_buf.Count();
00128 ASSERT(0 == m_buf.ElementAt(1));
00129 ASSERT(0 == m_buf.ElementAt(2));
00130 #if LITTLE_ENDIAN
00131 m_buf.SetElementAt( count >> 8, 1 );
00132 m_buf.SetElementAt( count & 0xFF, 2 );
00133 #else
00134 m_buf.SetElementAt( count & 0xFF, 1 );
00135 m_buf.SetElementAt( count >> 8, 2 );
00136 #endif
00137 sock.Write( m_buf.ToArray(), 0, m_buf.Count() );
00138 }
00139
00140 void Packet::ReadPacket(spl::IStream& sock)
00141 {
00142 m_readPacketReady = false;
00143
00144 m_buf.Clear();
00145 if (1 != sock.Read(m_abuf, 0, 1) )
00146 {
00147 throw new SocketException("Read byte order failed");
00148 }
00149 m_buf.Add(m_abuf[0]);
00150 #if LITTLE_ENDIAN
00151 m_readRevByteOrder = m_abuf[0] != 1;
00152 #else
00153 m_readRevByteOrder = m_abuf[0] == 1;
00154 #endif
00155 if (1 != sock.Read(m_abuf, 0, 1) )
00156 {
00157 throw new SocketException("count MCB failed");
00158 }
00159 m_buf.Add(m_abuf[0]);
00160 #if LITTLE_ENDIAN
00161 m_rpacketsize = m_abuf[0] << 8;
00162 #else
00163 m_rpacketsize = m_abuf[0] & 0xFF;
00164 #endif
00165 if (1 != sock.Read(m_abuf, 0, 1) )
00166 {
00167 throw new SocketException("count LCB failed");
00168 }
00169 m_buf.Add(m_abuf[0]);
00170 ASSERT(m_buf.Count() == 3);
00171 #if LITTLE_ENDIAN
00172 m_rpacketsize |= m_abuf[0] & 0xFF;
00173 #else
00174 m_rpacketsize |= m_abuf[0] << 8;
00175 #endif
00176
00177 int len2 = m_rpacketsize - m_buf.Count();
00178 if (m_abuf.Length() < len2)
00179 {
00180 m_abuf = Array<byte>(len2);
00181 }
00182
00183 if ( len2 != sock.Read( m_abuf, 0, m_rpacketsize-m_buf.Count()) )
00184 {
00185 throw new SocketException("Short read");
00186 }
00187 m_buf.AddRange(m_abuf, len2);
00188 m_buf.SetCount(m_rpacketsize);
00189 m_readpos = 3;
00190 m_readPacketReady = true;
00191 }
00192
00193 void Packet::_AppendRaw( byte i )
00194 {
00195 m_buf.Add( i );
00196 }
00197
00198 void Packet::_AppendRaw( int16 i )
00199 {
00200 #if LITTLE_ENDIAN
00201 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00202 m_buf.Add( (byte)(i & 0xFF) );
00203 #else
00204 m_buf.Add( (byte)(i & 0xFF) );
00205 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00206 #endif
00207 }
00208
00209 void Packet::_AppendRaw( int32 i )
00210 {
00211 #if LITTLE_ENDIAN
00212 m_buf.Add( (byte)(i >> 24) );
00213 m_buf.Add( (byte)((i >> 16) & 0xFF) );
00214 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00215 m_buf.Add( (byte)(i & 0xFF) );
00216 #else
00217 m_buf.Add( (byte)(i & 0xFF) );
00218 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00219 m_buf.Add( (byte)((i >> 16) & 0xFF) );
00220 m_buf.Add( (byte)(i >> 24) );
00221 #endif
00222 }
00223
00224 void Packet::_AppendRaw( int64 i )
00225 {
00226 #if LITTLE_ENDIAN
00227 m_buf.Add( (byte)(i >> 56) & 0xFF );
00228 m_buf.Add( (byte)(i >> 48) & 0xFF );
00229 m_buf.Add( (byte)(i >> 40) & 0xFF );
00230 m_buf.Add( (byte)(i >> 32) & 0xFF );
00231 m_buf.Add( (byte)(i >> 24) & 0xFF );
00232 m_buf.Add( (byte)((i >> 16) & 0xFF) );
00233 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00234 m_buf.Add( (byte)(i & 0xFF) );
00235 #else
00236 m_buf.Add( (byte)(i & 0xFF) );
00237 m_buf.Add( (byte)((i >> 8) & 0xFF) );
00238 m_buf.Add( (byte)((i >> 16) & 0xFF) );
00239 m_buf.Add( (byte)(i >> 24) & 0xFF );
00240 m_buf.Add( (byte)(i >> 32) & 0xFF );
00241 m_buf.Add( (byte)(i >> 40) & 0xFF );
00242 m_buf.Add( (byte)(i >> 48) & 0xFF );
00243 m_buf.Add( (byte)(i >> 56) & 0xFF );
00244 #endif
00245 }
00246
00247 void Packet::Append(int64 i)
00248 {
00249 m_buf.Add( (byte)'L' );
00250 _AppendRaw( i );
00251 ASSERT(0 == m_buf.ElementAt(1));
00252 ASSERT(0 == m_buf.ElementAt(2));
00253 }
00254
00255 void Packet::Append(int32 i)
00256 {
00257 m_buf.Add( (byte)'I' );
00258 _AppendRaw( i );
00259 ASSERT(0 == m_buf.ElementAt(1));
00260 ASSERT(0 == m_buf.ElementAt(2));
00261 }
00262
00263 void Packet::Append(int16 i)
00264 {
00265 m_buf.Add( (byte)'X' );
00266 _AppendRaw( i );
00267 ASSERT(0 == m_buf.ElementAt(1));
00268 ASSERT(0 == m_buf.ElementAt(2));
00269 }
00270
00271 void Packet::Append(byte i)
00272 {
00273 m_buf.Add( (byte)'B' );
00274 m_buf.Add( i );
00275 ASSERT(0 == m_buf.ElementAt(1));
00276 ASSERT(0 == m_buf.ElementAt(2));
00277 }
00278
00279 void Packet::Append(bool b)
00280 {
00281 m_buf.Add( (byte)'F' );
00282 m_buf.Add( (b)?1:0 );
00283 ASSERT(0 == m_buf.ElementAt(1));
00284 ASSERT(0 == m_buf.ElementAt(2));
00285 }
00286
00287 void Packet::Append(const char *str, int count)
00288 {
00289
00290 m_buf.Add( (byte)'S' );
00291
00292
00293 int numchar = count;
00294 _AppendRaw( (int16)count );
00295
00296
00297 byte charsize = (byte)sizeof(char);
00298 _AppendRaw( charsize );
00299
00300 if ( 1 == charsize )
00301 {
00302 for ( int x = 0; x < numchar; x++ )
00303 {
00304 m_buf.Add( (byte)str[x] );
00305 }
00306 }
00307 else if ( 2 == charsize )
00308 {
00309 for ( int x = 0; x < numchar; x++ )
00310 {
00311 _AppendRaw( (int16)str[x] );
00312 }
00313 }
00314 else
00315 {
00316 for ( int x = 0; x < numchar; x++ )
00317 {
00318 _AppendRaw( (int32)str[x] );
00319 }
00320 }
00321 ASSERT(0 == m_buf.ElementAt(1));
00322 ASSERT(0 == m_buf.ElementAt(2));
00323 }
00324
00325 void Packet::Append(const Array<byte>& buf, int start, int len)
00326 {
00327 _AppendRaw( (byte)'R' );
00328 _AppendRaw( (int16)(len - start) );
00329
00330 for ( int x = start; x < start+len; x++ )
00331 {
00332 _AppendRaw( buf[x] );
00333 }
00334 ASSERT(0 == m_buf.ElementAt(1));
00335 ASSERT(0 == m_buf.ElementAt(2));
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 void Packet::Append(double d)
00356 {
00357 char buf[128];
00358 int numchars = sprintf(buf, "%lf.20", d);
00359 ASSERT(numchars < 128);
00360
00361 _AppendRaw( (byte)'d' );
00362 _AppendRaw( (byte)numchars );
00363
00364 for ( int x = 0; x < numchars; x++ )
00365 {
00366 m_buf.Add( (byte)buf[x] );
00367 }
00368 ASSERT(0 == m_buf.ElementAt(1));
00369 ASSERT(0 == m_buf.ElementAt(2));
00370 }
00371
00372 void Packet::Append(const DateTime& dtm)
00373 {
00374 _AppendRaw( (byte)'T' );
00375 _AppendRaw( (int16)dtm.Year() );
00376 _AppendRaw( (byte)dtm.Month() );
00377 _AppendRaw( (byte)dtm.Day() );
00378 _AppendRaw( (byte)dtm.Hour() );
00379 _AppendRaw( (byte)dtm.Minutes() );
00380 _AppendRaw( (byte)dtm.Seconds() );
00381 }
00382
00383 void Packet::Append(const Date& dt)
00384 {
00385 _AppendRaw( (byte)'D' );
00386 _AppendRaw( (int16)dt.Year() );
00387 _AppendRaw( (byte)dt.Month() );
00388 _AppendRaw( (byte)dt.Day() );
00389 }
00390
00391 int Packet::PacketSize()
00392 {
00393 if ( ! m_readPacketReady )
00394 {
00395 throw new PacketNotReadyException("Packet must be in read state to get size");
00396 }
00397 return m_buf.Count();
00398 }
00399
00400 int64 Packet::ReadInt64()
00401 {
00402 if ( ! m_readPacketReady )
00403 {
00404 throw new PacketNotReadyException("Packet must be in read state to get size");
00405 }
00406 byte datatype = _NextByte();
00407 if ( (byte)'L' != datatype )
00408 {
00409 throw new PacketReadTypeMismatchException("Expected int64");
00410 }
00411 #if LITTLE_ENDIAN
00412 int64 i = (_NextByte() << 24) | (_NextByte() << 16) | (_NextByte() << 8) | (_NextByte());
00413 i <<= 32;
00414 return i | ((_NextByte() << 24) | (_NextByte() << 16) | (_NextByte() << 8) | (_NextByte()));
00415 #else
00416 int64 i = _NextByte() | (_NextByte() << 8) | (_NextByte() << 16) | (_NextByte() << 24);
00417 int64 i2 = _NextByte() | (_NextByte() << 8) | (_NextByte() << 16) | (_NextByte() << 24);
00418 return (i2 << 32) | i;
00419 #endif
00420 }
00421
00422 int32 Packet::ReadInt32()
00423 {
00424 if ( ! m_readPacketReady )
00425 {
00426 throw new PacketNotReadyException("Packet must be in read state to get size");
00427 }
00428 byte datatype = _NextByte();
00429 if ( (byte)'I' != datatype )
00430 {
00431 throw new PacketReadTypeMismatchException("Expected int32");
00432 }
00433 #if LITTLE_ENDIAN
00434 return (_NextByte() << 24) | (_NextByte() << 16) | (_NextByte() << 8) | (_NextByte());
00435 #else
00436 return _NextByte() | (_NextByte() << 8) | (_NextByte() << 16) | (_NextByte() << 24);
00437 #endif
00438 }
00439
00440 int16 Packet::ReadInt16()
00441 {
00442 if ( ! m_readPacketReady )
00443 {
00444 throw new PacketNotReadyException("Packet must be in read state to get size");
00445 }
00446 byte datatype = _NextByte();
00447 if ( (byte)'X' != datatype )
00448 {
00449 throw new PacketReadTypeMismatchException("Expected int16");
00450 }
00451 #if LITTLE_ENDIAN
00452 return (int16)((_NextByte() << 8) | (_NextByte()));
00453 #else
00454 return (int16)(_NextByte() | (_NextByte() << 8));
00455 #endif
00456 }
00457
00458 byte Packet::ReadInt8()
00459 {
00460 if ( ! m_readPacketReady )
00461 {
00462 throw new PacketNotReadyException("Packet must be in read state to get size");
00463 }
00464 byte datatype = _NextByte();
00465 if ( (byte)'B' != datatype )
00466 {
00467 throw new PacketReadTypeMismatchException("Expected byte");
00468 }
00469 return (byte)_NextByte();
00470 }
00471
00472 bool Packet::ReadBool()
00473 {
00474 if ( ! m_readPacketReady )
00475 {
00476 throw new PacketNotReadyException("Packet must be in read state to get size");
00477 }
00478 byte datatype = _NextByte();
00479 if ( (byte)'F' != datatype )
00480 {
00481 throw new PacketReadTypeMismatchException("Expected bool");
00482 }
00483 return _NextByte() != 0;
00484 }
00485
00486 StringPtr Packet::ReadString()
00487 {
00488 if ( ! m_readPacketReady )
00489 {
00490 throw new PacketNotReadyException("Packet must be in read state to get size");
00491 }
00492 byte datatype = _NextByte();
00493 if ( (byte)'S' != datatype )
00494 {
00495 throw new PacketReadTypeMismatchException("Expected string type char");
00496 }
00497
00498 int16 numchars = (_NextByte() << 8) | _NextByte();
00499 int charsize = (byte)_NextByte();
00500
00501 StringBuffer buf(80);
00502
00503 if ( charsize == 1 )
00504 {
00505 for ( int x = 0; x < numchars; x++ )
00506 {
00507 buf.Append( (char)_NextByte() );
00508 }
00509 }
00510 else if ( charsize == 2 )
00511 {
00512 for ( int x = 0; x < numchars; x++ )
00513 {
00514 buf.Append( (char)_NextByte() );
00515 _NextByte();
00516 }
00517 }
00518 else
00519 {
00520 for ( int x = 0; x < numchars; x++ )
00521 {
00522 buf.Append( (char)_NextByte() );
00523 _NextByte();
00524 _NextByte();
00525 _NextByte();
00526 }
00527 }
00528 buf.Append('\0');
00529 buf.ValidateMem();
00530 return buf.ToString();
00531 }
00532
00533 byte *Packet::ReadBuf(int expectedlen)
00534 {
00535 if ( ! m_readPacketReady )
00536 {
00537 throw new PacketNotReadyException("Packet must be in read state to get size");
00538 }
00539 byte datatype = _NextByte();
00540 if ( (byte)'R' != datatype )
00541 {
00542 throw new PacketReadTypeMismatchException("Expected raw data");
00543 }
00544 int16 len = ReadInt16();
00545 if ( len != expectedlen )
00546 {
00547 throw new PacketUnderflowException();
00548 }
00549 ASSERT( 0 != len );
00550 if ( len > m_buf.Count() - m_readpos )
00551 {
00552 throw new PacketUnderflowException();
00553 }
00554 byte *buf = (byte *)malloc( len );
00555 if ( NULL == buf )
00556 {
00557 return NULL;
00558 }
00559 for ( int x = 0; x < len; x++ )
00560 {
00561 buf[x] = _NextByte();
00562 }
00563 return buf;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 double Packet::ReadDouble()
00591 {
00592 if ( ! m_readPacketReady )
00593 {
00594 throw new PacketNotReadyException("Packet must be in read state to get size");
00595 }
00596 byte datatype = _NextByte();
00597 if ( (byte)'d' != datatype )
00598 {
00599 throw new PacketReadTypeMismatchException("Expected double");
00600 }
00601 int len = _NextByte();
00602 StringBuffer buf(len+1);
00603
00604 for ( int x = 0; x < len; x++ )
00605 {
00606 buf.Append( (char)_NextByte() );
00607 }
00608 buf.Append('\0');
00609 double val;
00610 sscanf(buf.GetChars(), "%lf", &val);
00611 return val;
00612 }
00613
00614 DateTime Packet::ReadDateTime()
00615 {
00616 byte datatype = _NextByte();
00617 if ( (byte)'T' != datatype )
00618 {
00619 throw new PacketReadTypeMismatchException("Expected DateTime type char");
00620 }
00621
00622 int year = (int)_NextByte() << 8 | (int)_NextByte();
00623 int month = (int)_NextByte();
00624 int day = (int)_NextByte();
00625 int hour = (int)_NextByte();
00626 int min = (int)_NextByte();
00627 int sec = (int)_NextByte();
00628
00629 return DateTime(year, month, day, hour, min, sec);
00630 }
00631
00632 Date Packet::ReadDate()
00633 {
00634 byte datatype = _NextByte();
00635 if ( (byte)'D' != datatype )
00636 {
00637 throw new PacketReadTypeMismatchException("Expected Date type char");
00638 }
00639
00640 int year = (int)_NextByte() << 8 | (int)_NextByte();
00641 int month = (int)_NextByte();
00642 int day = (int)_NextByte();
00643
00644 return Date(year, month, day);
00645 }
00646
00647 #if defined(DEBUG) || defined(_DEBUG)
00648 void Packet::CheckMem() const
00649 {
00650 m_buf.CheckMem();
00651 m_abuf.CheckMem();
00652 }
00653
00654 void Packet::ValidateMem() const
00655 {
00656 m_buf.ValidateMem();
00657 m_abuf.ValidateMem();
00658 }
00659 #endif
00660
00661
00662
00663 IPacketListener::~IPacketListener()
00664 {
00665 }
00666
00667 PacketBuilder::PacketBuilder()
00668 : m_listeners(), m_state(PKT_ENDIAN), m_buf(), m_readPos(0), m_pktsize(0)
00669 {
00670 }
00671
00672 PacketBuilder::~PacketBuilder()
00673 {
00674 }
00675
00676 void PacketBuilder::IStreamRead_OnError(const String& msg)
00677 {
00678 m_state = PKT_ERROR;
00679
00680 m_listeners.DispatchOnError(msg);
00681 }
00682
00683 void PacketBuilder::IStreamRead_OnClose()
00684 {
00685 m_state = PKT_CLOSED;
00686
00687 m_listeners.DispatchOnClose();
00688 }
00689
00690 void PacketBuilder::IStreamRead_OnRead(const Array<byte>& buf, int len)
00691 {
00692 for (int bufpos = 0; bufpos < len; bufpos++ )
00693 {
00694 if (m_pktsize > 0 && m_readPos == m_pktsize)
00695 {
00696 m_state = PKT_ENDIAN;
00697 }
00698 else
00699 {
00700 ASSERT(0 == m_pktsize || m_readPos < m_pktsize);
00701 m_readPos++;
00702 }
00703 byte b = buf[bufpos];
00704 switch ( m_state )
00705 {
00706 case PKT_ENDIAN:
00707 m_readPos = 1;
00708 if ( b == 1 )
00709 {
00710 m_isLittleEndian = true;
00711 }
00712 else
00713 {
00714 m_isLittleEndian = false;
00715 }
00716 #if LITTLE_ENDIAN
00717 m_revbytes = !m_isLittleEndian;
00718 #else
00719 m_revbytes = m_isLittleEndian;
00720 #endif
00721 m_state = PKT_SIZE_MCB;
00722 break;
00723 case PKT_SIZE_MCB:
00724 #if LITTLE_ENDIAN
00725 m_pktsize = b << 8;
00726 #else
00727 m_pktsize = b & 0xFF;
00728 #endif
00729 m_state = PKT_SIZE_LCB;
00730 break;
00731 case PKT_SIZE_LCB:
00732 #if LITTLE_ENDIAN
00733 m_pktsize |= b & 0xFF;
00734 #else
00735 m_pktsize |= b << 8;
00736 #endif
00737 ASSERT(m_pktsize > 0);
00738 m_state = PKT_DT;
00739 break;
00740 case PKT_DT:
00741 m_datatype = (char)b;
00742 switch ( m_datatype )
00743 {
00744 case 'I':
00745 m_datalen = 4;
00746 m_state = PKT_DATA;
00747 break;
00748 case 'X':
00749 m_datalen = 2;
00750 m_state = PKT_DATA;
00751 break;
00752 case 'B':
00753 m_datalen = 1;
00754 m_state = PKT_DATA;
00755 break;
00756 case 'S':
00757 m_state = PKT_DT_LEN_MCB;
00758 break;
00759 case 'R':
00760 m_state = PKT_DT_LEN_MCB;
00761 break;
00762 case 'F':
00763 m_datalen = 1;
00764 m_state = PKT_DATA;
00765 break;
00766
00767
00768
00769
00770 case 'd':
00771 m_charsize = 1;
00772 m_state = PKT_DT_LEN_MCB;
00773 break;
00774 case 'D':
00775 m_datalen = 4;
00776 m_state = PKT_DATA;
00777 break;
00778 case 't':
00779 m_datalen = 7;
00780 m_state = PKT_DATA;
00781 break;
00782 default:
00783 m_state = PKT_ERROR;
00784 throw new IOException("Invalid datatype recevied");
00785 }
00786 break;
00787 case PKT_DT_LEN_MCB:
00788 #if LITTLE_ENDIAN
00789 m_datalen = b << 8;
00790 #else
00791 m_datalen = b & 0xFF;
00792 #endif
00793 m_state = PKT_DT_LEN_LCB;
00794 break;
00795 case PKT_DT_LEN_LCB:
00796 #if LITTLE_ENDIAN
00797 m_datalen |= b & 0xFF;
00798 #else
00799 m_datalen |= b << 8;
00800 #endif
00801 if ( m_datatype == 'S' )
00802 {
00803 m_state = PKT_CHARSIZE;
00804 }
00805 else
00806 {
00807 m_state = PKT_DATA;
00808 }
00809 break;
00810 case PKT_CHARSIZE:
00811 m_charsize = b;
00812 m_datalen *= m_charsize;
00813 m_state = PKT_DATA;
00814 break;
00815 case PKT_DATA:
00816 m_buf.Add( b );
00817 if ( m_buf.Count() == m_datalen )
00818 {
00819 _ParseData();
00820 m_buf.Clear();
00821 }
00822 ASSERT( m_buf.Count() < m_datalen );
00823 break;
00824 case PKT_ERROR:
00825 break;
00826 }
00827 }
00828
00829 if (m_readPos == m_pktsize)
00830 {
00831 m_state = PKT_ENDIAN;
00832 }
00833 ASSERT(m_readPos <= m_pktsize);
00834 }
00835
00836 void PacketBuilder::_ParseData()
00837 {
00838 int year;
00839 StringPtr str;
00840 switch ( m_datatype )
00841 {
00842 case 'I':
00843 if (m_revbytes)
00844 {
00845
00846 m_listeners.DispatchOnData((int32)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8) | (m_buf.ElementAt(2) << 16) | (m_buf.ElementAt(3) << 24)));
00847 }
00848 else
00849 {
00850
00851 m_listeners.DispatchOnData((int32)(m_buf.ElementAt(3) | (m_buf.ElementAt(2) << 8) | (m_buf.ElementAt(1) << 16) | (m_buf.ElementAt(0) << 24)));
00852 }
00853 break;
00854 case 'X':
00855 if (m_revbytes)
00856 {
00857
00858 m_listeners.DispatchOnData((int16)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8)));
00859 }
00860 else
00861 {
00862
00863 m_listeners.DispatchOnData((int16)(m_buf.ElementAt(1) | (m_buf.ElementAt(0) << 8)));
00864 }
00865 break;
00866 case 'B':
00867
00868 m_listeners.DispatchOnData( (byte)m_buf.ElementAt(0) );
00869 break;
00870 case 'S':
00871 str = _ParseString();
00872
00873 m_listeners.DispatchOnData(str);
00874 break;
00875 case 'R':
00876
00877 m_listeners.DispatchOnData(m_buf, m_datalen);
00878 break;
00879 case 'F':
00880
00881 m_listeners.DispatchOnData( (bool)(0 != m_buf.ElementAt(0)) );
00882 break;
00883
00884
00885
00886
00887
00888 case 'd':
00889 double d;
00890 str = _ParseString();
00891 sscanf(str->GetChars(), "%lf", &d);
00892
00893 m_listeners.DispatchOnData(d);
00894 break;
00895 case 't':
00896 if (m_revbytes)
00897 {
00898 year = (int)(m_buf.ElementAt(0) | (int)(m_buf.ElementAt(1) << 8));
00899 }
00900 else
00901 {
00902 year = (int)(m_buf.ElementAt(1) | (int)(m_buf.ElementAt(0) << 8));
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 m_listeners.DispatchOnData
00917 (
00918 DateTime
00919 (
00920 year,
00921 (int)m_buf.ElementAt(2),
00922 (int)m_buf.ElementAt(3),
00923 (int)m_buf.ElementAt(4),
00924 (int)m_buf.ElementAt(5),
00925 (int)m_buf.ElementAt(6)
00926 )
00927 );
00928 break;
00929 case 'D':
00930 if (m_revbytes)
00931 {
00932 year = (int)(m_buf.ElementAt(0) | (int)(m_buf.ElementAt(1) << 8));
00933 }
00934 else
00935 {
00936 year = (int)(m_buf.ElementAt(1) | (int)(m_buf.ElementAt(0) << 8));
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 m_listeners.DispatchOnData
00948 (
00949 Date
00950 (
00951 year,
00952 (int)m_buf.ElementAt(2),
00953 (int)m_buf.ElementAt(3)
00954 )
00955 );
00956 break;
00957 default:
00958 throw new Exception("Internal error");
00959 }
00960 m_state = PKT_DT;
00961 }
00962
00963 StringPtr PacketBuilder::_ParseString()
00964 {
00965 StringBuffer sbuf((m_datalen / m_charsize) + 1);
00966 if ( 1 == m_charsize )
00967 {
00968 for (int x = 0; x < m_datalen; x++ )
00969 {
00970 sbuf.Append( (char)m_buf.ElementAt(x) );
00971 }
00972 }
00973 else if ( 2 == m_charsize )
00974 {
00975 for (int x = 0; x < m_datalen; x += 2 )
00976 {
00977 if ( m_revbytes )
00978 {
00979
00980
00981 sbuf.Append( (char)m_buf.ElementAt(x) );
00982 }
00983 else
00984 {
00985
00986 sbuf.Append( (char)(m_buf.ElementAt(x+1)) );
00987 }
00988 }
00989 }
00990 else
00991 {
00992 if (m_revbytes)
00993 {
00994
00995 sbuf.Append((char)m_buf.ElementAt(0));
00996 }
00997 else
00998 {
00999 sbuf.Append((char)m_buf.ElementAt(3));
01000 }
01001 }
01002 sbuf.Append('\0');
01003 return sbuf.ToString();
01004 }
01005
01006 #if defined(DEBUG) || defined(_DEBUG)
01007 void PacketBuilder::CheckMem() const
01008 {
01009 m_buf.CheckMem();
01010 m_listeners.CheckMem();
01011 }
01012
01013 void PacketBuilder::ValidateMem() const
01014 {
01015 m_buf.ValidateMem();
01016 m_listeners.ValidateMem();
01017 }
01018 #endif
01019
01020 ThreadedPacketStream::ThreadedPacketStream(IPacketListener *listener, spl::IStreamPtr conn)
01021 : m_builder(), m_conn(conn)
01022 {
01023 m_builder.Delegates().Add(listener);
01024 m_conn.Delegates().Add(&m_builder);
01025 }
01026
01027 ThreadedPacketStream::~ThreadedPacketStream()
01028 {
01029 }
01030
01031 #if defined(DEBUG) || defined(_DEBUG)
01032 void ThreadedPacketStream::CheckMem() const
01033 {
01034 m_conn.CheckMem();
01035 m_builder.CheckMem();
01036 }
01037
01038 void ThreadedPacketStream::ValidateMem() const
01039 {
01040 m_conn.ValidateMem();
01041 m_builder.ValidateMem();
01042 }
01043 #endif