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, "Mem_Map_Stream.cpp,v 1.15 2006/04/20 09:55:37 jwillemsen Exp")
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<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 off_t
00100 ACEXML_Mem_Map_Stream::seek (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 break;
00120 }
00121
00122
00123 while (this->get_pos_ > this->end_of_mapping_plus1_)
00124 if (this->grow_file_and_remap () == -1)
00125 this->get_pos_ = this->end_of_mapping_plus1_;
00126
00127 this->recv_pos_ = this->get_pos_;
00128 return this->recv_pos_ - reinterpret_cast<char *> (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
00150
00151
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
00164 ACE_FILE_Addr file (ACE_sap_any_cast (ACE_FILE_Addr &));
00165
00166
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
00175
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
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[8192];
00192
00193
00194
00195 ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT);
00196 ssize_t bytes = 0;
00197 ssize_t n = 0;
00198 while (1)
00199 {
00200 n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv);
00201 if (n == -1)
00202 {
00203 if (errno != EWOULDBLOCK)
00204 {
00205 ACE_ERROR ((LM_ERROR, "%p\n", "recv"));
00206 return -1;
00207 }
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
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 if (this->mem_map_.map (-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
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 }
00257
00258 ACEXML_Mem_Map_Stream::~ACEXML_Mem_Map_Stream (void)
00259 {
00260
00261 this->mem_map_.remove ();
00262 delete this->svc_handler_;
00263 }
00264