1 #include "ace/FILE_Addr.h"
3 #include "ace/Truncate.h"
5 #include "Mem_Map_Stream.h"
9 Mem_Map_Stream::stream ()
11 return svc_handler_
->peer ();
15 Mem_Map_Stream::send_n (const void *buf
, size_t size
, ACE_Time_Value
*tv
)
17 return svc_handler_
->peer ().send_n (buf
, size
, 0, tv
);
21 Mem_Map_Stream::eof () const
23 return this->get_pos_
>= this->end_of_mapping_plus1_
;
27 Mem_Map_Stream::get_char ()
29 if (this->eof () && this->grow_file_and_remap () == -1)
32 return *this->get_pos_
++;
36 Mem_Map_Stream::rewind ()
39 reinterpret_cast<char *> (this->mem_map_
.addr ());
40 this->get_pos_
= this->recv_pos_
;
41 this->end_of_mapping_plus1_
=
42 this->recv_pos_
+ this->mem_map_
.size ();
47 Mem_Map_Stream::peek_char (size_t offset
)
49 // We may need to iterate if the size of <n> is large.
50 while (this->get_pos_
+ offset
>= this->end_of_mapping_plus1_
)
51 if (this->grow_file_and_remap () == -1)
54 return this->get_pos_
[offset
];
58 Mem_Map_Stream::recv () const
60 return this->recv_pos_
;
64 Mem_Map_Stream::recv (size_t &len
)
66 if (this->eof () && this->grow_file_and_remap () == -1)
70 const char *s
= this->recv_pos_
;
71 ACE_OFF_T olen
= static_cast <ACE_OFF_T
> (len
);
72 this->seek (olen
, SEEK_CUR
);
73 len
= this->get_pos_
- s
;
78 Mem_Map_Stream::recv_len () const
80 return this->get_pos_
- this->recv_pos_
;
84 Mem_Map_Stream::peek_str (size_t offset
,
87 // We will iterate if the size of <offset> is large.
88 while (this->get_pos_
+ (offset
+ size
) > this->end_of_mapping_plus1_
)
89 if (this->grow_file_and_remap () == -1)
92 return &this->get_pos_
[offset
];
96 Mem_Map_Stream::seek (ACE_OFF_T offset
, int whence
)
102 reinterpret_cast<char *> (this->mem_map_
.addr ())
107 this->get_pos_
+= offset
;
112 this->end_of_mapping_plus1_
+ offset
;
113 // @@ Not sure how to implement this (yet).
114 ACE_NOTSUP_RETURN (-1);
117 // Make sure that the backing store will cover this.
118 while (this->get_pos_
> this->end_of_mapping_plus1_
)
119 if (this->grow_file_and_remap () == -1)
120 return (ACE_OFF_T
) -1;
122 this->recv_pos_
= this->get_pos_
;
124 ACE_Utils::truncate_cast
<ACE_OFF_T
> (
125 this->recv_pos_
- reinterpret_cast<char *> (this->mem_map_
.addr ()));
128 Mem_Map_Stream::Svc_Handler
*
129 Mem_Map_Stream::svc_handler ()
131 return this->svc_handler_
;
136 Mem_Map_Stream::open (STRAT_CONNECTOR
*connector
,
137 const ACE_INET_Addr
&addr
)
141 // Connect to the server at <addr>. If the handler has to be
142 // connected to the server again, the Caching strategy takes care
143 // and uses the same connection.
144 if (connector
->connect (svc_handler_
,
147 ACE_ERROR_RETURN ((LM_ERROR
,
150 addr
.get_host_name (),
151 addr
.get_port_number ()),
154 // Create a temporary filename.
155 ACE_FILE_Addr
file (ACE_sap_any_cast (ACE_FILE_Addr
&));
157 // Create the temporary file via the <ACE_Mem_Map> class API.
158 if (this->mem_map_
.open (file
.get_path_name (),
159 O_RDWR
| O_CREAT
| O_APPEND
,
160 ACE_DEFAULT_FILE_PERMS
) == -1)
161 ACE_ERROR_RETURN ((LM_ERROR
,
165 // Make sure to unlink this right away so that if this process
166 // crashes these files will be removed automatically.
168 else if (ACE_OS::unlink (file
.get_path_name ()) == -1)
169 ACE_ERROR_RETURN ((LM_ERROR
,
175 // Initialize all the position pointers to 0.
182 Mem_Map_Stream::grow_file_and_remap ()
184 char buf
[BUFSIZ
+ 1];
186 // Copy the next chunk of bytes from the socket into the temporary
188 ACE_Time_Value
tv (*OPTIONS::instance ()->timeout ());
190 ssize_t n
= this->svc_handler_
->peer ().recv_n (buf
,
196 if (OPTIONS::instance ()->debug ())
197 ACE_ERROR ((LM_ERROR
,
204 else if (ACE::write_n (this->mem_map_
.handle (), buf
, n
) != n
)
205 ACE_ERROR_RETURN ((LM_ERROR
,
210 // Grow the memory-mapping to encompass the entire temporary file.
211 if (this->mem_map_
.map (static_cast<size_t> (-1),
213 ACE_MAP_PRIVATE
| ACE_MAP_FIXED
,
214 ACE_DEFAULT_BASE_ADDR
) == -1)
215 ACE_ERROR_RETURN ((LM_ERROR
,
219 // MAP_FAILED is used as a "first time in" flag.
220 if (this->recv_pos_
== MAP_FAILED
)
222 this->recv_pos_
= reinterpret_cast<char *> (this->mem_map_
.addr ());
223 this->get_pos_
= this->recv_pos_
;
226 this->end_of_mapping_plus1_
=
227 reinterpret_cast<char *> (this->mem_map_
.addr ())
228 + this->mem_map_
.size ();
233 Mem_Map_Stream::~Mem_Map_Stream ()
235 // Remove the mapping and the file.
236 this->mem_map_
.remove ();