• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/Packet.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
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);   // byte count MCB
00119         m_buf.Add(0);   // byte count LCB
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         // append datatype
00290         m_buf.Add( (byte)'S' );
00291 
00292         // append the number of characters
00293         int numchar = count;
00294         _AppendRaw( (int16)count );
00295 
00296         // append the size of each char
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 //void Packet::Append(float f)
00339 //{
00340 //      char buf[128];
00341 //      int numchars = sprintf(buf, "%f.12", f);
00342 //      ASSERT(numchars < 128);
00343 //      
00344 //      _AppendRaw( (byte)'f' );
00345 //      _AppendRaw( (byte)numchars );
00346 //
00347 //      for ( int x = 0; x < numchars; x++ )
00348 //      {
00349 //              m_buf.Add( (byte)buf[x] );
00350 //      }
00351 //      ASSERT(0 == m_buf.ElementAt(1));
00352 //      ASSERT(0 == m_buf.ElementAt(2));
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 //float Packet::ReadFloat()
00567 //{
00568 //      if ( ! m_readPacketReady )
00569 //      {
00570 //              throw new PacketNotReadyException("Packet must be in read state to get size");
00571 //      }
00572 //      byte datatype = _NextByte();
00573 //      if ( (byte)'f' != datatype )
00574 //      {
00575 //              throw new PacketReadTypeMismatchException("Expected float");
00576 //      }
00577 //      int len = _NextByte();
00578 //      StringBuffer buf(len+1);
00579 //
00580 //      for ( int x = 0; x < len; x++ )
00581 //      {
00582 //              buf.Append( (char)_NextByte() );
00583 //      }
00584 //      buf.Append('\0');
00585 //      float val;
00586 //      sscanf(buf.GetChars(), "%f", &val);
00587 //      return val;
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(/*IPacketListener *listener*/)
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         //m_listener->IStreamRead_OnError(msg);
00680         m_listeners.DispatchOnError(msg);
00681 }
00682 
00683 void PacketBuilder::IStreamRead_OnClose()
00684 {
00685         m_state = PKT_CLOSED;
00686         //m_listener->IStreamRead_OnClose();
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                         //case 'f':
00767                         //      m_charsize = 1;
00768                         //      m_state = PKT_DT_LEN_MCB;
00769                         //      break;
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                                 //m_listener->IPacket_OnData((int32)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8) | (m_buf.ElementAt(2) << 16) | (m_buf.ElementAt(3) << 24)));
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                                 //m_listener->IPacket_OnData((int32)(m_buf.ElementAt(3) | (m_buf.ElementAt(2) << 8) | (m_buf.ElementAt(1) << 16) | (m_buf.ElementAt(0) << 24)));
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                                 //m_listener->IPacket_OnData((int16)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8)));
00858                                 m_listeners.DispatchOnData((int16)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8)));
00859                         }
00860                         else
00861                         {
00862                                 //m_listener->IPacket_OnData((int16)(m_buf.ElementAt(1) | (m_buf.ElementAt(0) << 8)));
00863                                 m_listeners.DispatchOnData((int16)(m_buf.ElementAt(1) | (m_buf.ElementAt(0) << 8)));
00864                         }
00865                         break;
00866                 case 'B':
00867                         //m_listener->IPacket_OnData( (byte)m_buf.ElementAt(0) );
00868                         m_listeners.DispatchOnData( (byte)m_buf.ElementAt(0) );
00869                         break;
00870                 case 'S':
00871                         str = _ParseString();
00872                         //m_listener->IPacket_OnData(str);
00873                         m_listeners.DispatchOnData(str);
00874                         break;
00875                 case 'R':
00876                         //m_listener->IPacket_OnData(m_buf, m_datalen);
00877                         m_listeners.DispatchOnData(m_buf, m_datalen);
00878                         break;
00879                 case 'F':
00880                         //m_listener->IPacket_OnData( (bool)(0 != m_buf.ElementAt(0)) );
00881                         m_listeners.DispatchOnData( (bool)(0 != m_buf.ElementAt(0)) );
00882                         break;
00883                 //case 'f':
00884                 //      str = _ParseString();
00885                 //      sscanf(str->GetChars(), "%lf", &d);
00886                 //      m_listener->IPacket_OnData((float)d);
00887                 //      break;
00888                 case 'd':
00889                         double d;
00890                         str = _ParseString();
00891                         sscanf(str->GetChars(), "%lf", &d);
00892                         //m_listener->IPacket_OnData(d);
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                         //m_listener->IPacket_OnData
00905                         //(
00906                         //      DateTime
00907                         //      (
00908                         //              year, 
00909                         //              (int)m_buf.ElementAt(2),
00910                         //              (int)m_buf.ElementAt(3),
00911                         //              (int)m_buf.ElementAt(4),
00912                         //              (int)m_buf.ElementAt(5),
00913                         //              (int)m_buf.ElementAt(6)
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                         //m_listener->IPacket_OnData
00939                         //(
00940                         //      Date
00941                         //      (
00942                         //              year, 
00943                         //              (int)m_buf.ElementAt(2),
00944                         //              (int)m_buf.ElementAt(3)
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                                 //sbuf.Append( (char)((m_buf.ElementAt(x)) | (m_buf.ElementAt(x+1) << 8)) );
00980                                 //Just take the ascii
00981                                 sbuf.Append( (char)m_buf.ElementAt(x) );
00982                         }
00983                         else
00984                         {
00985                                 //sbuf.Append( (char)((m_buf.ElementAt(x+1)) | (m_buf.ElementAt(x) << 8)) );
00986                                 sbuf.Append( (char)(m_buf.ElementAt(x+1)) );
00987                         }
00988                 }
00989         }
00990         else
00991         {
00992                 if (m_revbytes)
00993                 {
00994                         //sbuf.Append((char)(m_buf.ElementAt(0) | (m_buf.ElementAt(1) << 8) | (m_buf.ElementAt(2) << 16) | (m_buf.ElementAt(3) << 24)));
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