#include <ACEXML/common/Mem_Map_Stream.h>
Collaboration diagram for ACEXML_Mem_Map_Stream:
Public Member Functions | |
ACEXML_Mem_Map_Stream (void) | |
Default constructor. | |
virtual int | open (Connector *connector, const ACE_INET_Addr &) |
Initialize this object. | |
virtual | ~ACEXML_Mem_Map_Stream (void) |
Destructor. | |
ACE_SOCK_Stream & | stream (void) |
Returns the underlying <ACE_SOCK_Stream>. | |
virtual ssize_t | send_n (const void *buf, size_t size, ACE_Time_Value *tv=0) |
virtual int | get_char (void) |
virtual const char * | recv (size_t &len) |
virtual const char * | recv (void) const |
virtual size_t | recv_len (void) const |
virtual size_t | available (void) const |
virtual void | rewind (void) |
virtual int | peek_char (size_t offset) |
virtual const char * | peek_str (size_t offset, size_t size) |
virtual ACE_OFF_T | seek (ACE_OFF_T offset, int whence=SEEK_CUR) |
virtual int | eof (void) const |
Returns 1 if we're at the end of the HTTP stream, else 0. | |
Svc_Handler * | svc_handler (void) |
Returns the underlying service handler. | |
Private Member Functions | |
int | grow_file_and_remap (void) |
Private Attributes | |
Svc_Handler * | svc_handler_ |
ACE_Mem_Map | mem_map_ |
Memory-mapped file that we're iterating over. | |
char * | recv_pos_ |
Pointer to the address where the next <recv> method will start. | |
char * | get_pos_ |
char * | end_of_mapping_plus1_ |
Address at the end of the file mapping. |
This class makes it possible to treat an connection as a stream of bytes, similar to the C library stdio streams. The contents of the connection are buffered incrementally in a memory-mapped file. This class maintains pointers to two positions in the stream:
1. The <recv> position, which keeps track of the beginning of a token that is in the stream.
2. The <get> position, which moves along character-by-character until the end of the token is reached.
Once a token has been located, it can be extracted from the stream by calling the <recv>. The length of the token, i.e., the <recv_len>, is the length in bytes between the <get> position and the <recv> position. Once the token has been extracted, the <recv> and <get> positions can be updated by the <seek> method.
Definition at line 55 of file Mem_Map_Stream.h.
ACEXML_Mem_Map_Stream::ACEXML_Mem_Map_Stream | ( | void | ) |
Default constructor.
Definition at line 9 of file Mem_Map_Stream.cpp.
00010 : svc_handler_ (0) 00011 { 00012 00013 }
ACEXML_Mem_Map_Stream::~ACEXML_Mem_Map_Stream | ( | void | ) | [virtual] |
Destructor.
Definition at line 258 of file Mem_Map_Stream.cpp.
References mem_map_, ACE_Mem_Map::remove(), and svc_handler_.
00259 { 00260 // Remove the mapping and the file. 00261 this->mem_map_.remove (); 00262 delete this->svc_handler_; 00263 }
size_t ACEXML_Mem_Map_Stream::available | ( | void | ) | const [virtual] |
Returns the no. of bytes available in the stream.
Definition at line 137 of file Mem_Map_Stream.cpp.
References end_of_mapping_plus1_, and get_pos_.
Referenced by ACEXML_HttpCharStream::available().
00138 { 00139 return this->end_of_mapping_plus1_ - this->get_pos_; 00140 }
int ACEXML_Mem_Map_Stream::eof | ( | void | ) | const [virtual] |
Returns 1 if we're at the end of the HTTP stream, else 0.
Definition at line 29 of file Mem_Map_Stream.cpp.
References end_of_mapping_plus1_, and get_pos_.
00030 { 00031 return this->get_pos_ >= this->end_of_mapping_plus1_; 00032 }
int ACEXML_Mem_Map_Stream::get_char | ( | void | ) | [virtual] |
Return the next character in the stream and advance the <get> position. Returns EOF when the <get> position reaches the end of the HTTP stream.
Definition at line 35 of file Mem_Map_Stream.cpp.
References get_pos_, and grow_file_and_remap().
00036 { 00037 if (this->eof () && this->grow_file_and_remap () == -1) 00038 return EOF; 00039 return *this->get_pos_++; 00040 }
int ACEXML_Mem_Map_Stream::grow_file_and_remap | ( | void | ) | [private] |
Grow the file by reading another chunk from the HTTP socket and extend the mapping to cover this chunk. Returns -1 on failure or EOF, else 0.
Definition at line 188 of file Mem_Map_Stream.cpp.
References ACE_DEFAULT_TIMEOUT, ACE_ERROR, ACE_ERROR_RETURN, ACE_MAP_PRIVATE, ACE_Mem_Map::addr(), end_of_mapping_plus1_, get_pos_, LM_ERROR, MAP_FAILED, mem_map_, ACE_Svc_Handler<, >::peer(), PROT_RDWR, recv_pos_, svc_handler_, and ACE::write_n().
Referenced by get_char(), and recv().
00189 { 00190 char buf[8192]; 00191 00192 // Copy the next chunk of bytes from the socket into the temporary 00193 // file. 00194 ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT); 00195 ssize_t bytes = 0; 00196 ssize_t n = 0; 00197 while (1) 00198 { 00199 n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv); 00200 if (n < 0) 00201 { 00202 if (errno != EWOULDBLOCK) 00203 { 00204 ACE_ERROR ((LM_ERROR, "%p\n", "recv")); 00205 } 00206 00207 return -1; 00208 } 00209 bytes += n; 00210 if (n == 0 && !bytes) 00211 return -1; 00212 else if (n == 0) 00213 break; 00214 else if (ACE::write_n (this->mem_map_.handle (), buf, n) != n) 00215 ACE_ERROR_RETURN ((LM_ERROR, 00216 "%p\n", 00217 "write_n"), 00218 -1); 00219 } 00220 00221 // ssize_t n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv); 00222 // if (n == -1) 00223 // { 00224 // ACE_ERROR ((LM_ERROR, "%p\n", "recv")); 00225 // return -1; 00226 // } 00227 // else if (n == 0) 00228 // return -1; 00229 // else if (ACE::write_n (this->mem_map_.handle (), buf, n) != n) 00230 // ACE_ERROR_RETURN ((LM_ERROR, 00231 // "%p\n", 00232 // "write_n"), 00233 // -1); 00234 00235 // Grow the memory-mapping to encompass the entire temporary file. 00236 if (this->mem_map_.map (static_cast<size_t> (-1), 00237 PROT_RDWR, 00238 ACE_MAP_PRIVATE, 00239 (void*)0) == -1) 00240 ACE_ERROR_RETURN ((LM_ERROR, 00241 "%p\n", 00242 "map"), 00243 -1); 00244 // MAP_FAILED is used as a "first time in" flag. 00245 if (this->recv_pos_ == MAP_FAILED) 00246 { 00247 this->recv_pos_ = reinterpret_cast<char *> (this->mem_map_.addr ()); 00248 this->get_pos_ = this->recv_pos_; 00249 } 00250 00251 this->end_of_mapping_plus1_ = 00252 reinterpret_cast<char *> (this->mem_map_.addr ()) 00253 + this->mem_map_.size (); 00254 00255 return 0; 00256 }
int ACEXML_Mem_Map_Stream::open | ( | Connector * | connector, | |
const ACE_INET_Addr & | ||||
) | [virtual] |
Initialize this object.
Definition at line 143 of file Mem_Map_Stream.cpp.
References ACE_DEFAULT_FILE_PERMS, ACE_ERROR_RETURN, ACE_Connector< SVC_HANDLER, >::connect(), ACE_INET_Addr::get_host_name(), ACE_FILE_Addr::get_path_name(), ACE_INET_Addr::get_port_number(), LM_ERROR, rewind(), svc_handler_, and ACE_OS::unlink().
00145 { 00146 svc_handler_ = 0; 00147 00148 // Connect to the server at <addr>. If the handler has to be 00149 // connected to the server again, the Caching strategy takes care 00150 // and uses the same connection. 00151 if (connector->connect (svc_handler_, 00152 addr) == -1) 00153 { 00154 00155 ACE_ERROR_RETURN ((LM_ERROR, 00156 "%p %s %d\n", 00157 "Connect failed", 00158 addr.get_host_name (), 00159 addr.get_port_number ()), 00160 -1); 00161 } 00162 // Create a temporary filename. 00163 ACE_FILE_Addr file (ACE_sap_any_cast (ACE_FILE_Addr &)); 00164 00165 // Create the temporary file via the <ACE_Mem_Map> class API. 00166 if (this->mem_map_.open (file.get_path_name (), 00167 O_RDWR | O_CREAT | O_APPEND, 00168 ACE_DEFAULT_FILE_PERMS) == -1) 00169 ACE_ERROR_RETURN ((LM_ERROR, 00170 "%p\n", 00171 "open"), 00172 -1); 00173 // Make sure to unlink this right away so that if this process 00174 // crashes these files will be removed automatically. 00175 else if (ACE_OS::unlink (file.get_path_name ()) == -1) 00176 ACE_ERROR_RETURN ((LM_ERROR, 00177 "%p\n", 00178 "unlink"), 00179 -1); 00180 else 00181 // Initialize all the position pointers to 0. 00182 this->rewind (); 00183 00184 return 0; 00185 }
int ACEXML_Mem_Map_Stream::peek_char | ( | size_t | offset | ) | [virtual] |
Returns the nth character <offset> from the <get> position in the stream without advancing the <get> position. Automatically extends the backing store if necessary. Returns EOF if <offset> is past the end of the stream.
Definition at line 51 of file Mem_Map_Stream.cpp.
References get_pos_.
Referenced by ACEXML_HttpCharStream::peek().
00052 { 00053 // We may need to iterate if the size of <n> is large. 00054 while (this->get_pos_ + offset >= this->end_of_mapping_plus1_) 00055 if (this->grow_file_and_remap () == -1) 00056 return EOF; 00057 00058 return this->get_pos_[offset]; 00059 }
const char * ACEXML_Mem_Map_Stream::peek_str | ( | size_t | offset, | |
size_t | size | |||
) | [virtual] |
Return a pointer to an array of <size> characters starting at <offset> characters from the <get> position in the stream without advancing the <get> position. Automatically extends the backing store if necessary. Returns 0 if <offset> or <offset + size> is past the end of the stream.
Definition at line 88 of file Mem_Map_Stream.cpp.
References get_pos_.
00090 { 00091 // We will iterate if the size of <offset> is large. 00092 while (this->get_pos_ + (offset + size) > this->end_of_mapping_plus1_) 00093 if (this->grow_file_and_remap () == -1) 00094 return 0; 00095 00096 return &this->get_pos_[offset]; 00097 }
const char * ACEXML_Mem_Map_Stream::recv | ( | void | ) | const [virtual] |
Returns a pointer to array of characters starting at the <recv> position.
Definition at line 62 of file Mem_Map_Stream.cpp.
References recv_pos_.
00063 { 00064 return this->recv_pos_; 00065 }
const char * ACEXML_Mem_Map_Stream::recv | ( | size_t & | len | ) | [virtual] |
Returns a pointer to array of at most <len> characters starting at the <recv> position. If the <recv> position + <len> extends past the EOF then <len> is set to the number of characters between the <recv> position and the EOF and both the <get> and <recv> positions are advanced by <len>. Returns 0 if the <recv> position is at the EOF.
Definition at line 68 of file Mem_Map_Stream.cpp.
References get_pos_, grow_file_and_remap(), recv_pos_, and seek().
Referenced by ACEXML_HttpCharStream::get_url(), and ACEXML_HttpCharStream::read().
00069 { 00070 if (this->eof () && this->grow_file_and_remap () == -1) 00071 { 00072 len = 0; 00073 return 0; 00074 } 00075 const char *s = this->recv_pos_; 00076 this->seek (static_cast<ACE_OFF_T> (len), SEEK_CUR); 00077 len = this->get_pos_ - s; 00078 return s; 00079 }
size_t ACEXML_Mem_Map_Stream::recv_len | ( | void | ) | const [virtual] |
void ACEXML_Mem_Map_Stream::rewind | ( | void | ) | [virtual] |
Resets the <get> and <recv> positions to the beginning of the stream. This works since all the data has been cached in the memory-mapped backing store.
Definition at line 43 of file Mem_Map_Stream.cpp.
References ACE_Mem_Map::addr(), end_of_mapping_plus1_, get_pos_, mem_map_, recv_pos_, and ACE_Mem_Map::size().
Referenced by ACEXML_HttpCharStream::get_url(), open(), and ACEXML_HttpCharStream::rewind().
00044 { 00045 this->recv_pos_ = reinterpret_cast<char *> (this->mem_map_.addr ()); 00046 this->get_pos_ = this->recv_pos_; 00047 this->end_of_mapping_plus1_ = this->recv_pos_ + this->mem_map_.size (); 00048 }
Sets the <get> and <recv> positions as follows: o If <whence> is <SEEK_SET>, the positions are set to <offset> bytes from the start of the stream. o If <whence> is <SEEK_CUR>, the positions are set to the current <get> position plus <offset>. o If <whence> is <SEEK_END>, the positions are set to the size of the stream plus <offset>.
If offset is greater than EOF, both <get> and <recv> are set to EOF. Note special return value is returned to indicate this condition.
Definition at line 100 of file Mem_Map_Stream.cpp.
References ACE_NOTSUP_RETURN, ACE_Mem_Map::addr(), end_of_mapping_plus1_, get_pos_, and mem_map_.
Referenced by recv().
00101 { 00102 switch (whence) 00103 { 00104 case SEEK_SET: 00105 this->get_pos_ = 00106 reinterpret_cast<char *> (this->mem_map_.addr ()) 00107 + offset; 00108 break; 00109 00110 case SEEK_CUR: 00111 this->get_pos_ += offset; 00112 break; 00113 00114 case SEEK_END: 00115 this->get_pos_ = 00116 this->end_of_mapping_plus1_ + offset; 00117 // @@ Not sure how to implement this (yet). 00118 ACE_NOTSUP_RETURN (-1); 00119 } 00120 00121 // Make sure that the backing store will cover this. 00122 while (this->get_pos_ > this->end_of_mapping_plus1_) 00123 if (this->grow_file_and_remap () == -1) 00124 this->get_pos_ = this->end_of_mapping_plus1_; 00125 00126 this->recv_pos_ = this->get_pos_; 00127 return this->recv_pos_ - reinterpret_cast<char *> (this->mem_map_.addr ()); 00128 }
ssize_t ACEXML_Mem_Map_Stream::send_n | ( | const void * | buf, | |
size_t | size, | |||
ACE_Time_Value * | tv = 0 | |||
) | [virtual] |
Send <size> bytes in <buf> to the connected peer. This is a completely unbuffered call.
Definition at line 22 of file Mem_Map_Stream.cpp.
References ACE_Svc_Handler<, >::peer(), and svc_handler_.
Referenced by ACEXML_HttpCharStream::send_request().
00024 { 00025 return svc_handler_->peer ().send_n (buf, size, 0, tv); 00026 }
ACE_SOCK_Stream & ACEXML_Mem_Map_Stream::stream | ( | void | ) |
Returns the underlying <ACE_SOCK_Stream>.
Definition at line 16 of file Mem_Map_Stream.cpp.
References ACE_Svc_Handler<, >::peer(), and svc_handler_.
00017 { 00018 return svc_handler_->peer (); 00019 }
Svc_Handler * ACEXML_Mem_Map_Stream::svc_handler | ( | void | ) |
Returns the underlying service handler.
Definition at line 131 of file Mem_Map_Stream.cpp.
References svc_handler_.
00132 { 00133 return this->svc_handler_; 00134 }
char* ACEXML_Mem_Map_Stream::end_of_mapping_plus1_ [private] |
Address at the end of the file mapping.
Definition at line 183 of file Mem_Map_Stream.h.
Referenced by available(), eof(), grow_file_and_remap(), rewind(), and seek().
char* ACEXML_Mem_Map_Stream::get_pos_ [private] |
Pointer to the address where the next <get_char> method will start.
Definition at line 180 of file Mem_Map_Stream.h.
Referenced by available(), eof(), get_char(), grow_file_and_remap(), peek_char(), peek_str(), recv(), recv_len(), rewind(), and seek().
ACE_Mem_Map ACEXML_Mem_Map_Stream::mem_map_ [private] |
Memory-mapped file that we're iterating over.
Definition at line 171 of file Mem_Map_Stream.h.
Referenced by grow_file_and_remap(), rewind(), seek(), and ~ACEXML_Mem_Map_Stream().
char* ACEXML_Mem_Map_Stream::recv_pos_ [private] |
Pointer to the address where the next <recv> method will start.
Definition at line 174 of file Mem_Map_Stream.h.
Referenced by grow_file_and_remap(), recv(), recv_len(), and rewind().
Svc_Handler* ACEXML_Mem_Map_Stream::svc_handler_ [private] |
Connection to peer. The granularity is at the Svc_Handler level. The Svc_Handler has an SOCK_Stream.
Definition at line 168 of file Mem_Map_Stream.h.
Referenced by grow_file_and_remap(), open(), send_n(), stream(), svc_handler(), and ~ACEXML_Mem_Map_Stream().