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 78399 2007-05-18 02:54:37Z sowayaa $")
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 return this->recv_pos_ - reinterpret_cast<char *> (this->mem_map_.addr ());
00128 }
00129
00130 Svc_Handler *
00131 ACEXML_Mem_Map_Stream::svc_handler (void)
00132 {
00133 return this->svc_handler_;
00134 }
00135
00136 size_t
00137 ACEXML_Mem_Map_Stream::available (void) const
00138 {
00139 return this->end_of_mapping_plus1_ - this->get_pos_;
00140 }
00141
00142 int
00143 ACEXML_Mem_Map_Stream::open (Connector *connector,
00144 const ACE_INET_Addr &addr)
00145 {
00146 svc_handler_ = 0;
00147
00148
00149
00150
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
00163 ACE_FILE_Addr file (ACE_sap_any_cast (ACE_FILE_Addr &));
00164
00165
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
00174
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
00182 this->rewind ();
00183
00184 return 0;
00185 }
00186
00187 int
00188 ACEXML_Mem_Map_Stream::grow_file_and_remap (void)
00189 {
00190 char buf[8192];
00191
00192
00193
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
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
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
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