Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Mem_Map_Stream.cpp

Go to the documentation of this file.
00001 // $Id: Mem_Map_Stream.cpp,v 1.1.1.1.2.1 2003/04/21 19:14:54 chad Exp $
00002 
00003 #include "ace/FILE_Addr.h"
00004 #include "ACEXML/common/Mem_Map_Stream.h"
00005 
00006 ACE_RCSID(common, Mem_Map_Stream, "$Id: Mem_Map_Stream.cpp,v 1.1.1.1.2.1 2003/04/21 19:14:54 chad Exp $")
00007 
00008 ACEXML_Mem_Map_Stream::ACEXML_Mem_Map_Stream (void)
00009 {
00010 
00011 }
00012 
00013 ACE_SOCK_Stream &
00014 ACEXML_Mem_Map_Stream::stream (void)
00015 {
00016   return svc_handler_->peer ();
00017 }
00018 
00019 ssize_t
00020 ACEXML_Mem_Map_Stream::send_n (const void *buf, size_t size,
00021                                ACE_Time_Value *tv)
00022 {
00023   return svc_handler_->peer ().send_n (buf, size, 0, tv);
00024 }
00025 
00026 int
00027 ACEXML_Mem_Map_Stream::eof (void) const
00028 {
00029   return this->get_pos_ >= this->end_of_mapping_plus1_;
00030 }
00031 
00032 int
00033 ACEXML_Mem_Map_Stream::get_char (void)
00034 {
00035   if (this->eof () && this->grow_file_and_remap () == -1)
00036     return EOF;
00037 
00038   return *this->get_pos_++;
00039 }
00040 
00041 void
00042 ACEXML_Mem_Map_Stream::rewind (void)
00043 {
00044   this->recv_pos_ = ACE_reinterpret_cast (char *,
00045                           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 }
00049 
00050 int
00051 ACEXML_Mem_Map_Stream::peek_char (size_t offset)
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 }
00060 
00061 const char *
00062 ACEXML_Mem_Map_Stream::recv (void) const
00063 {
00064   return this->recv_pos_;
00065 }
00066 
00067 const char *
00068 ACEXML_Mem_Map_Stream::recv (size_t &len)
00069 {
00070   if (this->eof () && this->grow_file_and_remap () == -1)
00071     return 0;
00072 
00073   const char *s = this->recv_pos_;
00074   this->seek (ACE_static_cast(off_t, len), SEEK_CUR);
00075   len = this->get_pos_ - s;
00076   return s;
00077 }
00078 
00079 size_t
00080 ACEXML_Mem_Map_Stream::recv_len (void) const
00081 {
00082   return this->get_pos_ - this->recv_pos_;
00083 }
00084 
00085 const char *
00086 ACEXML_Mem_Map_Stream::peek_str (size_t offset,
00087                                  size_t size)
00088 {
00089   // We will iterate if the size of <offset> is large.
00090   while (this->get_pos_ + (offset + size) > this->end_of_mapping_plus1_)
00091     if (this->grow_file_and_remap () == -1)
00092       return 0;
00093 
00094   return &this->get_pos_[offset];
00095 }
00096 
00097 off_t
00098 ACEXML_Mem_Map_Stream::seek (off_t offset, int whence)
00099 {
00100   switch (whence)
00101     {
00102     case SEEK_SET:
00103       this->get_pos_ =
00104         ACE_reinterpret_cast (char *,
00105                               this->mem_map_.addr ())
00106         + offset;
00107       break;
00108 
00109     case SEEK_CUR:
00110       this->get_pos_ += offset;
00111       break;
00112 
00113     case SEEK_END:
00114       this->get_pos_ =
00115         this->end_of_mapping_plus1_ + offset;
00116       // @@ Not sure how to implement this (yet).
00117       ACE_NOTSUP_RETURN (-1);
00118       break;
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_ - ACE_reinterpret_cast (char *,
00128                                                  this->mem_map_.addr ());
00129 }
00130 
00131 Svc_Handler *
00132 ACEXML_Mem_Map_Stream::svc_handler (void)
00133 {
00134   return this->svc_handler_;
00135 }
00136 
00137 size_t
00138 ACEXML_Mem_Map_Stream::available (void) const
00139 {
00140   return this->end_of_mapping_plus1_ - this->get_pos_;
00141 }
00142 
00143 int
00144 ACEXML_Mem_Map_Stream::open (Connector *connector,
00145                              const ACE_INET_Addr &addr)
00146 {
00147   svc_handler_ = 0;
00148 
00149   // Connect to the server at <addr>. If the handler has to be
00150   // connected to the server again, the Caching strategy takes care
00151   // and uses the same connection.
00152   if (connector->connect (svc_handler_,
00153                           addr) == -1)
00154     {
00155 
00156       ACE_ERROR_RETURN ((LM_ERROR,
00157                          "%p %s %d\n",
00158                          "Connect failed",
00159                          addr.get_host_name (),
00160                          addr.get_port_number ()),
00161                         -1);
00162     }
00163   // Create a temporary filename.
00164   ACE_FILE_Addr file (ACE_sap_any_cast (ACE_FILE_Addr &));
00165 
00166   // Create the temporary file via the <ACE_Mem_Map> class API.
00167   if (this->mem_map_.open (file.get_path_name (),
00168                            O_RDWR | O_CREAT | O_APPEND,
00169                            ACE_DEFAULT_FILE_PERMS) == -1)
00170     ACE_ERROR_RETURN ((LM_ERROR,
00171                        "%p\n",
00172                        "open"),
00173                       -1);
00174   // Make sure to unlink this right away so that if this process
00175   // crashes these files will be removed automatically.
00176   else if (ACE_OS::unlink (file.get_path_name ()) == -1)
00177     ACE_ERROR_RETURN ((LM_ERROR,
00178                        "%p\n",
00179                        "unlink"),
00180                       -1);
00181   else
00182     // Initialize all the position pointers to 0.
00183     this->rewind ();
00184 
00185   return 0;
00186 }
00187 
00188 int
00189 ACEXML_Mem_Map_Stream::grow_file_and_remap (void)
00190 {
00191   char buf[BUFSIZ + 1];
00192 
00193   // Copy the next chunk of bytes from the socket into the temporary
00194   // file.
00195   ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT);
00196 
00197   ssize_t n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv);
00198   if (n == -1)
00199     {
00200       ACE_ERROR ((LM_ERROR, "%p\n", "recv"));
00201       return -1;
00202     }
00203   else if (n == 0)
00204     return -1;
00205   else if (ACE::write_n (this->mem_map_.handle (), buf, n) != n)
00206     ACE_ERROR_RETURN ((LM_ERROR,
00207                        "%p\n",
00208                        "write_n"),
00209                       -1);
00210 
00211   // Grow the memory-mapping to encompass the entire temporary file.
00212   if (this->mem_map_.map (-1,
00213                           PROT_RDWR,
00214                           ACE_MAP_PRIVATE | ACE_MAP_FIXED,
00215                           ACE_DEFAULT_BASE_ADDR) == -1)
00216     ACE_ERROR_RETURN ((LM_ERROR,
00217                        "%p\n",
00218                        "map"),
00219                       -1);
00220   // MAP_FAILED is used as a "first time in" flag.
00221   if (this->recv_pos_ == MAP_FAILED)
00222     {
00223       this->recv_pos_ = ACE_reinterpret_cast (char *,
00224                                               this->mem_map_.addr ());
00225       this->get_pos_ = this->recv_pos_;
00226     }
00227 
00228   this->end_of_mapping_plus1_ =
00229     ACE_reinterpret_cast (char *,
00230                           this->mem_map_.addr ())
00231     + this->mem_map_.size ();
00232 
00233   return 0;
00234 }
00235 
00236 ACEXML_Mem_Map_Stream::~ACEXML_Mem_Map_Stream (void)
00237 {
00238   // Remove the mapping and the file.
00239   this->mem_map_.remove ();
00240 }
00241 
00242 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00243 template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
00244 template class ACE_Connector <Svc_Handler, ACE_SOCK_CONNECTOR>;
00245 template class ACE_Svc_Tuple<Svc_Handler>;
00246 template class ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *>;
00247 template class ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>;
00248 template class ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>;
00249 template class ACE_Map_Reverse_Iterator<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>;
00250 template class ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>;
00251 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00252 #pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
00253 #pragma instantiate ACE_Connector <Svc_Handler, ACE_SOCK_CONNECTOR>
00254 #pragma instantiate ACE_Svc_Tuple<Svc_Handler>
00255 #pragma instantiate ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *>
00256 #pragma instantiate ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>
00257 #pragma instantiate ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>
00258 #pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>
00259 #pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<Svc_Handler> *, ACE_SYNCH_RW_MUTEX>
00260 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

Generated on Mon Jun 16 13:23:22 2003 for ACEXML by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002