ACEXML_Mem_Map_Stream Class Reference

Provides a memory-mapped stream abstraction to simplify parsing of tokens. More...

#include <ACEXML/common/Mem_Map_Stream.h>

Collaboration diagram for ACEXML_Mem_Map_Stream:

Collaboration graph
[legend]
List of all members.

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_Streamstream (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_Handlersvc_handler (void)
 Returns the underlying service handler.

Private Member Functions

int grow_file_and_remap (void)

Private Attributes

Svc_Handlersvc_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.

Detailed Description

Provides a memory-mapped stream abstraction to simplify parsing of tokens.

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.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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]

Returns the length in bytes between the <get> position and the <recv> position.

Definition at line 82 of file Mem_Map_Stream.cpp.

References get_pos_, and recv_pos_.

00083 {
00084   return this->get_pos_ - this->recv_pos_;
00085 }

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 }

ACE_OFF_T ACEXML_Mem_Map_Stream::seek ( ACE_OFF_T  offset,
int  whence = SEEK_CUR 
) [virtual]

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 }


Member Data Documentation

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().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:37:16 2010 for ACEXML by  doxygen 1.4.7