1 #include "ace/FILE_Addr.h"
2 #include "ace/OS_NS_unistd.h"
3 #include "ace/Truncate.h"
5 #include "ACEXML/common/Mem_Map_Stream.h"
7 ACEXML_Mem_Map_Stream::ACEXML_Mem_Map_Stream ()
11 end_of_mapping_plus1_ (0)
16 ACEXML_Mem_Map_Stream::stream ()
18 return svc_handler_
->peer ();
22 ACEXML_Mem_Map_Stream::send_n (const void *buf
, size_t size
,
25 return svc_handler_
->peer ().send_n (buf
, size
, 0, tv
);
29 ACEXML_Mem_Map_Stream::eof () const
31 return this->get_pos_
>= this->end_of_mapping_plus1_
;
35 ACEXML_Mem_Map_Stream::get_char ()
37 if (this->eof () && this->grow_file_and_remap () == -1)
39 return *this->get_pos_
++;
43 ACEXML_Mem_Map_Stream::rewind ()
45 this->recv_pos_
= reinterpret_cast<char *> (this->mem_map_
.addr ());
46 this->get_pos_
= this->recv_pos_
;
47 this->end_of_mapping_plus1_
= this->recv_pos_
+ this->mem_map_
.size ();
51 ACEXML_Mem_Map_Stream::peek_char (size_t offset
)
53 // We may need to iterate if the size of <n> is large.
54 while (this->get_pos_
+ offset
>= this->end_of_mapping_plus1_
)
55 if (this->grow_file_and_remap () == -1)
58 return this->get_pos_
[offset
];
62 ACEXML_Mem_Map_Stream::recv () const
64 return this->recv_pos_
;
68 ACEXML_Mem_Map_Stream::recv (size_t &len
)
70 if (this->eof () && this->grow_file_and_remap () == -1)
75 const char *s
= this->recv_pos_
;
76 this->seek (static_cast<ACE_OFF_T
> (len
), SEEK_CUR
);
77 len
= this->get_pos_
- s
;
82 ACEXML_Mem_Map_Stream::recv_len () const
84 return this->get_pos_
- this->recv_pos_
;
88 ACEXML_Mem_Map_Stream::peek_str (size_t offset
,
91 // We will iterate if the size of <offset> is large.
92 while (this->get_pos_
+ (offset
+ size
) > this->end_of_mapping_plus1_
)
93 if (this->grow_file_and_remap () == -1)
96 return &this->get_pos_
[offset
];
100 ACEXML_Mem_Map_Stream::seek (ACE_OFF_T offset
, int whence
)
106 reinterpret_cast<char *> (this->mem_map_
.addr ())
111 this->get_pos_
+= offset
;
116 this->end_of_mapping_plus1_
+ offset
;
117 // @@ Not sure how to implement this (yet).
118 ACE_NOTSUP_RETURN (-1);
121 // Make sure that the backing store will cover this.
122 while (this->get_pos_
> this->end_of_mapping_plus1_
)
123 if (this->grow_file_and_remap () == -1)
124 this->get_pos_
= this->end_of_mapping_plus1_
;
126 this->recv_pos_
= this->get_pos_
;
129 ACE_Utils::truncate_cast
<ACE_OFF_T
> (
130 this->recv_pos_
- reinterpret_cast<char *> (this->mem_map_
.addr ()));
134 ACEXML_Mem_Map_Stream::svc_handler ()
136 return this->svc_handler_
;
140 ACEXML_Mem_Map_Stream::available () const
142 return this->end_of_mapping_plus1_
- this->get_pos_
;
146 ACEXML_Mem_Map_Stream::open (Connector
*connector
,
147 const ACE_INET_Addr
&addr
)
151 // Connect to the server at <addr>. If the handler has to be
152 // connected to the server again, the Caching strategy takes care
153 // and uses the same connection.
154 if (connector
->connect (svc_handler_
,
157 ACE_ERROR_RETURN ((LM_ERROR
,
160 addr
.get_host_name (),
161 addr
.get_port_number ()),
164 // Create a temporary filename.
165 ACE_FILE_Addr
file (ACE_sap_any_cast (ACE_FILE_Addr
&));
167 // Create the temporary file via the <ACE_Mem_Map> class API.
168 if (this->mem_map_
.open (file
.get_path_name (),
169 O_RDWR
| O_CREAT
| O_APPEND
,
170 ACE_DEFAULT_FILE_PERMS
) == -1)
171 ACE_ERROR_RETURN ((LM_ERROR
,
175 // Make sure to unlink this right away so that if this process
176 // crashes these files will be removed automatically.
177 else if (ACE_OS::unlink (file
.get_path_name ()) == -1)
178 ACE_ERROR_RETURN ((LM_ERROR
,
183 // Initialize all the position pointers to 0.
190 ACEXML_Mem_Map_Stream::grow_file_and_remap ()
194 // Copy the next chunk of bytes from the socket into the temporary
196 ACE_Time_Value
tv (ACE_DEFAULT_TIMEOUT
);
200 ssize_t
const n
= this->svc_handler_
->peer ().recv (buf
, sizeof buf
, 0, &tv
);
203 if (errno
!= EWOULDBLOCK
)
205 ACE_ERROR ((LM_ERROR
, "%p\n", "recv"));
211 if (n
== 0 && !bytes
)
215 else if (ACE::write_n (this->mem_map_
.handle (), buf
, n
) != n
)
216 ACE_ERROR_RETURN ((LM_ERROR
,
222 // ssize_t n = this->svc_handler_->peer ().recv (buf, sizeof buf, 0, &tv);
225 // ACE_ERROR ((LM_ERROR, "%p\n", "recv"));
230 // else if (ACE::write_n (this->mem_map_.handle (), buf, n) != n)
231 // ACE_ERROR_RETURN ((LM_ERROR,
236 // Grow the memory-mapping to encompass the entire temporary file.
237 if (this->mem_map_
.map (static_cast<size_t> (-1),
241 ACE_ERROR_RETURN ((LM_ERROR
,
245 // MAP_FAILED is used as a "first time in" flag.
246 if (this->recv_pos_
== MAP_FAILED
)
248 this->recv_pos_
= reinterpret_cast<char *> (this->mem_map_
.addr ());
249 this->get_pos_
= this->recv_pos_
;
252 this->end_of_mapping_plus1_
=
253 reinterpret_cast<char *> (this->mem_map_
.addr ())
254 + this->mem_map_
.size ();
259 ACEXML_Mem_Map_Stream::~ACEXML_Mem_Map_Stream ()
261 // Remove the mapping and the file.
262 this->mem_map_
.remove ();
263 delete this->svc_handler_
;