Go to the documentation of this file.00001
00002
00003 #include "ace/FILE_Addr.h"
00004 #include "ace/OS_NS_unistd.h"
00005 #include "ACEXML/common/Mem_Map_Stream.h"
00006
00007 ACE_RCSID(common, Mem_Map_Stream, "$Id: Mem_Map_Stream.cpp 82574 2008-08-08 19:35:06Z parsons $")
00008
00009 ACEXML_Mem_Map_Stream::ACEXML_Mem_Map_Stream (void)
00010 : svc_handler_ (0)
00011 {
00012
00013 }
00014
00015 ACE_SOCK_Stream &
00016 ACEXML_Mem_Map_Stream::stream (void)
00017 {
00018 return svc_handler_->peer ();
00019 }
00020
00021 ssize_t
00022 ACEXML_Mem_Map_Stream::send_n (const void *buf, size_t size,
00023 ACE_Time_Value *tv)
00024 {
00025 return svc_handler_->peer ().send_n (buf, size, 0, tv);
00026 }
00027
00028 int
00029 ACEXML_Mem_Map_Stream::eof (void) const
00030 {
00031 return this->get_pos_ >= this->end_of_mapping_plus1_;
00032 }
00033
00034 int
00035 ACEXML_Mem_Map_Stream::get_char (void)
00036 {
00037 if (this->eof () && this->grow_file_and_remap () == -1)
00038 return EOF;
00039 return *this->get_pos_++;
00040 }
00041
00042 void
00043 ACEXML_Mem_Map_Stream::rewind (void)
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 }
00049
00050 int
00051 ACEXML_Mem_Map_Stream::peek_char (size_t offset)
00052 {
00053
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 {
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 }
00080
00081 size_t
00082 ACEXML_Mem_Map_Stream::recv_len (void) const
00083 {
00084 return this->get_pos_ - this->recv_pos_;
00085 }
00086
00087 const char *
00088 ACEXML_Mem_Map_Stream::peek_str (size_t offset,
00089 size_t size)
00090 {
00091
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 }
00098
00099 ACE_OFF_T
00100 ACEXML_Mem_Map_Stream::seek (ACE_OFF_T offset, int whence)
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
00118 ACE_NOTSUP_RETURN (-1);
00119 }
00120
00121
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
00128 return
00129 ACE_Utils::truncate_cast<ACE_OFF_T> (
00130 this->recv_pos_ - reinterpret_cast<char *> (this->mem_map_.addr ()));
00131 }
00132
00133 Svc_Handler *
00134 ACEXML_Mem_Map_Stream::svc_handler (void)
00135 {
00136 return this->svc_handler_;
00137 }
00138
00139 size_t
00140 ACEXML_Mem_Map_Stream::available (void) const
00141 {
00142 return this->end_of_mapping_plus1_ - this->get_pos_;
00143 }
00144
00145 int
00146 ACEXML_Mem_Map_Stream::open (Connector *connector,
00147 const ACE_INET_Addr &addr)
00148 {
00149 svc_handler_ = 0;
00150
00151
00152
00153
00154 if (connector->connect (svc_handler_,
00155 addr) == -1)
00156 {
00157
00158 ACE_ERROR_RETURN ((LM_ERROR,
00159 "%p %s %d\n",
00160 "Connect failed",
00161 addr.get_host_name (),
00162 addr.get_port_number ()),
00163 -1);
00164 }
00165
00166 ACE_FILE_Addr file (ACE_sap_any_cast (ACE_FILE_Addr &));
00167
00168
00169 if (this->mem_map_.open (file.get_path_name (),
00170 O_RDWR | O_CREAT | O_APPEND,
00171 ACE_DEFAULT_FILE_PERMS) == -1)
00172 ACE_ERROR_RETURN ((LM_ERROR,
00173 "%p\n",
00174 "open"),
00175 -1);
00176
00177
00178 else if (ACE_OS::unlink (file.get_path_name ()) == -1)
00179 ACE_ERROR_RETURN ((LM_ERROR,
00180 "%p\n",
00181 "unlink"),
00182 -1);
00183 else
00184
00185 this->rewind ();
00186
00187 return 0;
00188 }
00189
00190 int
00191 ACEXML_Mem_Map_Stream::grow_file_and_remap (void)
00192 {
00193 char buf[8192];
00194
00195
00196
00197 ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT);
00198 ssize_t bytes = 0;
00199 ssize_t n = 0;
00200 while (1)
00201 {
00202 n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv);
00203 if (n < 0)
00204 {
00205 if (errno != EWOULDBLOCK)
00206 {
00207 ACE_ERROR ((LM_ERROR, "%p\n", "recv"));
00208 }
00209
00210 return -1;
00211 }
00212 bytes += n;
00213 if (n == 0 && !bytes)
00214 return -1;
00215 else if (n == 0)
00216 break;
00217 else if (ACE::write_n (this->mem_map_.handle (), buf, n) != n)
00218 ACE_ERROR_RETURN ((LM_ERROR,
00219 "%p\n",
00220 "write_n"),
00221 -1);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 if (this->mem_map_.map (static_cast<size_t> (-1),
00240 PROT_RDWR,
00241 ACE_MAP_PRIVATE,
00242 (void*)0) == -1)
00243 ACE_ERROR_RETURN ((LM_ERROR,
00244 "%p\n",
00245 "map"),
00246 -1);
00247
00248 if (this->recv_pos_ == MAP_FAILED)
00249 {
00250 this->recv_pos_ = reinterpret_cast<char *> (this->mem_map_.addr ());
00251 this->get_pos_ = this->recv_pos_;
00252 }
00253
00254 this->end_of_mapping_plus1_ =
00255 reinterpret_cast<char *> (this->mem_map_.addr ())
00256 + this->mem_map_.size ();
00257
00258 return 0;
00259 }
00260
00261 ACEXML_Mem_Map_Stream::~ACEXML_Mem_Map_Stream (void)
00262 {
00263
00264 this->mem_map_.remove ();
00265 delete this->svc_handler_;
00266 }
00267