]> git.mxchange.org Git - simgear.git/blob - simgear/io/sg_netBuffer.hxx
Terrasync: implement HTTP service lookup via DNS
[simgear.git] / simgear / io / sg_netBuffer.hxx
1 /*
2     Copied from PLIB into SimGear
3     
4      PLIB - A Suite of Portable Game Libraries
5      Copyright (C) 1998,2002  Steve Baker
6  
7      This library is free software; you can redistribute it and/or
8      modify it under the terms of the GNU Library General Public
9      License as published by the Free Software Foundation; either
10      version 2 of the License, or (at your option) any later version.
11  
12      This library is distributed in the hope that it will be useful,
13      but WITHOUT ANY WARRANTY; without even the implied warranty of
14      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15      Library General Public License for more details.
16  
17      You should have received a copy of the GNU Library General Public
18      License along with this library; if not, write to the Free Software
19      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
20  
21      For further information visit http://plib.sourceforge.net
22
23      $Id: netBuffer.h 1901 2004-03-21 18:19:11Z sjbaker $
24 */
25
26 /****
27 * NAME
28 *   netBuffer - network buffer class
29 *
30 * DESCRIPTION
31 *   Clients and servers built on top of netBufferChannel
32 *   automatically support pipelining.
33 *
34 *   Pipelining refers to a protocol capability. Normally,
35 *   a conversation with a server has a back-and-forth
36 *   quality to it.  The client sends a command, and
37 *   waits for the response. If a client needs to send
38 *   many commands over a high-latency connection,
39 *   waiting for each response can take a long time. 
40 *
41 *   For example, when sending a mail message to many recipients
42 *   with SMTP, the client will send a series of RCPT commands, one
43 *   for each recipient. For each of these commands, the server will
44 *   send back a reply indicating whether the mailbox specified is
45 *   valid. If you want to send a message to several hundred recipients,
46 *   this can be rather tedious if the round-trip time for each command
47 *   is long. You'd like to be able to send a bunch of RCPT commands
48 *   in one batch, and then count off the responses to them as they come. 
49 *
50 *   I have a favorite visual when explaining the advantages of
51 *   pipelining. Imagine each request to the server is a boxcar on a train.
52 *   The client is in Los Angeles, and the server is in New York.
53 *   Pipelining lets you hook all your cars in one long chain; send
54 *   them to New York, where they are filled and sent back to you.
55 *   Without pipelining you have to send one car at a time. 
56 *
57 *   Not all protocols allow pipelining. Not all servers support it;
58 *   Sendmail, for example, does not support pipelining because it tends
59 *   to fork unpredictably, leaving buffered data in a questionable state.
60 *   A recent extension to the SMTP protocol allows a server to specify
61 *   whether it supports pipelining. HTTP/1.1 explicitly requires that
62 *   a server support pipelining. 
63 *
64 * NOTES
65 *   When a user passes in a buffer object, it belongs to
66 *   the user.  When the library gives a buffer to the user,
67 *   the user should copy it.
68 *
69 * AUTHORS
70 *   Sam Rushing <rushing@nightmare.com> - original version for Medusa
71 *   Dave McClurg <dpm@efn.org> - modified for use in PLIB
72 *
73 * CREATION DATE
74 *   Dec-2000
75 *
76 ****/
77
78 #ifndef SG_NET_BUFFER_H
79 #define SG_NET_BUFFER_H
80
81 #include <simgear/io/sg_netChannel.hxx>
82
83 namespace simgear
84 {
85
86 // ===========================================================================
87 // NetBuffer
88 // ===========================================================================
89
90 class NetBuffer
91 {
92 protected:
93   int length ;
94   int max_length ;
95   char* data ;
96
97 public:
98   NetBuffer( int _max_length );
99   ~NetBuffer ();
100   int getLength() const { return length ; }
101   int getMaxLength() const { return max_length ; }
102
103   /*
104   **  getData() returns a pointer to the data
105   **  Note: a zero (0) byte is appended for convenience
106   **  but the data may have internal zero (0) bytes already
107   */
108   char* getData() { data [length] = 0 ; return data ; }
109   const char* getData() const { ((char*)data) [length] = 0 ; return data ; }
110
111   void remove ();
112   void remove (int pos, int n);
113   bool append (const char* s, int n);
114   bool append (int n);
115 };
116
117 // ===========================================================================
118 // NetBufferChannel
119 // ===========================================================================
120
121 class NetBufferChannel : public NetChannel
122 {
123   NetBuffer in_buffer;
124   NetBuffer out_buffer;
125   int should_close ;
126   
127   virtual bool readable (void)
128   {
129     return (NetChannel::readable() &&
130       (in_buffer.getLength() < in_buffer.getMaxLength()));
131   }
132
133   virtual void handleRead (void) ;
134
135   virtual bool writable (void)
136   {
137     return (out_buffer.getLength() || should_close);
138   }
139
140   virtual void handleWrite (void) ;
141
142 public:
143
144   NetBufferChannel (int in_buffer_size = 4096, int out_buffer_size = 16384);
145   virtual void handleClose ( void );
146   
147   void closeWhenDone (void) { should_close = 1 ; }
148
149   virtual bool bufferSend (const char* msg, int msg_len);
150   virtual void handleBufferRead (NetBuffer& buffer);
151 };
152
153 } // namespace simgear
154
155 #endif // SG_NET_BUFFER_H