Panda3D
|
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