Panda3D

buffered_datagramwriter.h

00001 #ifndef __BufferedWriter_H__
00002 #define __BufferedWriter_H__
00003 
00004 #include "ringbuffer.h"
00005 ////////////////////////////////////////////////////////////////////
00006 //   Class : Buffered_DatagramWriter
00007 // Description : This is the buffered writer.. it is used to buffer up
00008 //               Coremessages and arbitrary data.. 
00009 //
00010 //              GmCoreMessage
00011 //
00012 //
00013 //              You must commit all rights to a socket with flush and 
00014 //              flush may be called internall if the buffersize is about
00015 //              to overrun.. This class does guaranty no partial message 
00016 //              rights at least to the TCP layer..
00017 //
00018 ////////////////////////////////////////////////////////////////////
00019 class   Buffered_DatagramWriter  :  public RingBuffer
00020 {
00021     int     _flush_point;
00022 public:
00023     inline void ReSet(void);            // destroy all buffered data
00024 
00025     Buffered_DatagramWriter( size_t in_size , int in_flush_point = -1);
00026     inline int AddData(const void * data, size_t len, Socket_TCP &sck);
00027     inline int AddData(const void * data, size_t len);
00028 // THE FUNCTIONS THAT TAKE A SOCKET NEED TO BE TEMPLATED TO WORK..
00029   
00030         template < class SOCK_TYPE>
00031         int  FlushNoBlock(SOCK_TYPE &sck) {  // this is the ugly part
00032     
00033           int answer = 0;
00034           size_t Writesize = AmountBuffered();
00035 
00036           if(Writesize > 0) {
00037             int Writen = sck.SendData(GetMessageHead(),(int)Writesize);
00038             if(Writen > 0) {
00039               _StartPos += Writen;
00040               FullCompress();
00041               if(AmountBuffered() > 0) // send 0 if empty else send 1 for more to do
00042                 answer = 1;
00043             }
00044             else if(Writen < 0) {
00045               if(!sck.ErrorIs_WouldBlocking(Writen))
00046                 answer = -1;
00047               else
00048                 answer = 1;  // 1 = more to do.....
00049             }
00050           }
00051           return answer;
00052         };
00053 
00054 
00055         template < class SOCK_TYPE>
00056         inline int  Flush(SOCK_TYPE &sck) {
00057           int answer = 0;
00058           size_t Writesize = AmountBuffered();
00059           
00060           if(Writesize > 0) {
00061             int Writen = sck.SendData(GetMessageHead(),(int)Writesize);
00062             
00063             if(Writen > 0) {
00064               _StartPos += Writen;
00065               FullCompress();
00066               if(AmountBuffered() > 0) //send 0 if empty else send 1 for more to do
00067                 answer = 1;
00068             }
00069             else if(Writen < 0) {
00070               if(sck.ErrorIs_WouldBlocking(Writen) != true)
00071                 answer = -1;
00072             }
00073           }
00074       
00075           return answer;
00076         };
00077 };
00078 
00079 ///////////////////////////////////////////////////////
00080 // Function name    : Buffered_DatagramWriter::ReSet
00081 // Description      : used to clear the buffrers ...
00082 //                    use of this in mid stream is a very bad thing as 
00083 //                    you can not guarany network writes are message alligned
00084 // Return type      : void 
00085 ///////////////////////////////////////////////////////
00086 inline void Buffered_DatagramWriter::ReSet(void) {
00087   ResetContent();
00088 }
00089 ////////////////////////////////////////////////
00090 //  Buffered_DatagramWriter::Buffered_DatagramWriter
00091 //
00092 //
00093 ////////////////////////////////////////////////
00094 inline Buffered_DatagramWriter::Buffered_DatagramWriter( size_t in_size , int in_flush_point) : RingBuffer(in_size) {
00095   _flush_point = in_flush_point;
00096 }
00097 
00098 //////////////////////////////////////////////////////////////
00099 // Function name    : Buffered_DatagramWriter::AddData
00100 // Description      : 
00101 // Return type      : inline int 
00102 // Argument         : const void * data
00103 // Argument         : int len
00104 // Argument         : Socket_TCP &sck
00105 //////////////////////////////////////////////////////////////
00106 inline int Buffered_DatagramWriter::AddData(const void * data, size_t len, Socket_TCP &sck) {
00107   int answer = 0;
00108   
00109   if(len >  BufferAvailabe())
00110     answer = Flush(sck);
00111 
00112   if(answer >= 0)
00113     answer = AddData(data,len);
00114   
00115   
00116   if(answer >= 0 && _flush_point != -1)
00117     if(_flush_point <  (int)AmountBuffered())
00118       if(Flush(sck) < 0)
00119         answer = -1;
00120   
00121   return answer;
00122 }
00123 
00124 //////////////////////////////////////////////////////////////
00125 // Function name    : Buffered_DatagramWriter::AddData
00126 // Description      : 
00127 // Return type      : inline int 
00128 // Argument         : const char * data
00129 // Argument         : int len
00130 //////////////////////////////////////////////////////////////
00131 inline int Buffered_DatagramWriter::AddData(const void * data, size_t len)
00132 {
00133   int answer = -1;
00134   if(BufferAvailabe() > len+2) {
00135     unsigned short len1(len);
00136     TS_GetInteger(len1,(char *)&len1);
00137     if(Put((char *)&len1,sizeof(len1)) == true) {
00138       if(Put((char *)data,len) == true) {
00139         answer = 1;
00140       }
00141     }
00142   }
00143 
00144   return answer;
00145 }
00146 #endif //__BufferedWriter_H__
00147 
 All Classes Functions Variables Enumerations