Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / examples / Content_Server / AMI_Iterator / Iterator_Handler.cpp
blob398e56f31ae9b95c3b6076f299b00a1c4a8237f2
1 // -*- C++ -*-
2 // Ossama Othman <ossama@uci.edu>
4 #include "ace/FILE_Connector.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Process_Manager.h"
7 #include "Iterator_Handler.h"
8 #include "ace/OS_NS_strings.h"
9 #include "ace/OS_NS_string.h"
11 Iterator_Handler::Iterator_Handler ()
12 : file_ (ACE_sap_any_cast (const ACE_FILE_Addr &)),
13 file_io_ (),
14 contents_ (),
15 metadata_ (),
16 offset_ (0),
17 ami_handler_ (),
18 request_count_ (0)
20 // Nothing else
23 Iterator_Handler::~Iterator_Handler ()
25 (void) this->file_io_.close ();
28 void
29 Iterator_Handler::next_chunk (CORBA::Boolean pending_data,
30 const Web_Server::Chunk_Type &chunk_data)
32 if (pending_data)
34 Web_Server::Chunk_Type_var chunk = chunk_data;
36 // Append the received data to the corresponding
37 // buffer/temporary file.
38 if (this->file_io_.send (chunk->get_buffer (),
39 chunk->length ()) == -1)
41 ACE_ERROR ((LM_ERROR,
42 ACE_TEXT ("%p\n"),
43 ACE_TEXT ("Unable to write retrieved data to ")
44 ACE_TEXT ("file")));
45 return;
47 else
48 this->offset_ += chunk->length ();
50 this->contents_->sendc_next_chunk (this->ami_handler_.in (),
51 this->offset_);
53 else
55 ACE_DEBUG ((LM_INFO,
56 ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
57 this->file_.get_path_name ()));
59 (*this->request_count_)--; // No more data.
61 // Done with the iterator, so destroy it.
62 this->contents_->sendc_destroy (this->ami_handler_.in ());
64 // File retrieval has completed, so spawn an external viewer to
65 // display its contents.
67 (void) this->spawn_viewer ();
70 void
71 Iterator_Handler::destroy ()
73 // Deactivate this reply handler.
74 this->deactivate ();
78 void
79 Iterator_Handler::run (int *request_count,
80 const char *pathname,
81 Web_Server::Iterator_Factory_ptr factory)
83 if (request_count != 0)
84 this->request_count_ = request_count;
85 else
86 // @@ Application code shouldn't throw system exceptions.
87 throw CORBA::BAD_PARAM ();
88 // Initialize the Content Iterator
89 this->initialize_content_iterator (pathname,
90 factory);
92 // Activate this Reply Handler.
93 this->ami_handler_ = this->_this ();
95 // Begin the asynchronous invocation.
96 this->contents_->sendc_next_chunk (this->ami_handler_.in (),
97 this->offset_);
100 void
101 Iterator_Handler::initialize_content_iterator
102 (const char *pathname,
103 Web_Server::Iterator_Factory_ptr factory)
105 // Obtain a Content Iterator for the desired file.
106 factory->get_iterator (pathname,
107 this->contents_,
108 this->metadata_);
110 // Create a temporary file to store the retrieved data.
111 ACE_FILE_Connector connector;
113 if (connector.connect (this->file_io_,
114 this->file_,
116 ACE_Addr::sap_any,
118 O_CREAT | O_TRUNC | O_WRONLY,
119 ACE_DEFAULT_FILE_PERMS) == -1)
120 ACE_ERROR ((LM_ERROR,
121 ACE_TEXT ("Could not open file %p\n"),
122 this->file_.get_path_name ()));
123 else
124 (*this->request_count_)++;
127 void
128 Iterator_Handler::deactivate ()
130 // Get the POA used when activating the Reply Handler object.
131 PortableServer::POA_var poa =
132 this->_default_POA ();
134 // Get the object ID associated with this servant.
135 PortableServer::ObjectId_var oid =
136 poa->servant_to_id (this);
138 // Now deactivate the iterator object.
139 poa->deactivate_object (oid.in ());
144 Iterator_Handler::get_viewer (char *viewer,
145 size_t length)
147 const char *content_type =
148 this->metadata_->content_type.in ();
150 if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
152 const char lynx[] = "lynx";
153 if (length <= sizeof (lynx))
154 return -1;
155 else
156 ACE_OS::strcpy (viewer, lynx);
158 else if (ACE_OS::strcasecmp (content_type,
159 "text/plain") == 0)
161 const char more[] = "more";
162 if (length <= sizeof (more))
163 return -1;
164 else
165 ACE_OS::strcpy (viewer, more);
167 else if (ACE_OS::strcasecmp (content_type,
168 "application/postscript") == 0)
170 const char ghostview[] = "ghostview";
171 if (length <= sizeof (ghostview))
172 return -1;
173 else
174 ACE_OS::strcpy (viewer, ghostview);
176 else if (ACE_OS::strcasecmp (content_type,
177 "application/pdf") == 0)
179 const char acroread[] = "acroread";
180 if (length <= sizeof (acroread))
181 return -1;
182 else
183 ACE_OS::strcpy (viewer, acroread);
185 else if (ACE_OS::strcasecmp (content_type,
186 "image/jpeg") == 0
187 || ACE_OS::strcasecmp (content_type,
188 "image/gif") == 0
189 || ACE_OS::strcasecmp (content_type,
190 "image/tiff") == 0
191 || ACE_OS::strcasecmp (content_type,
192 "image/png") == 0)
194 const char xv[] = "xv";
195 if (length <= sizeof (xv))
196 return -1;
197 else
198 ACE_OS::strcpy (viewer, xv);
200 else
201 ACE_ERROR_RETURN ((LM_ERROR,
202 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
203 content_type),
204 -1);
206 return 0;
210 Iterator_Handler::spawn_viewer ()
212 char viewer[BUFSIZ];
214 if (this->get_viewer (viewer,
215 sizeof viewer) != 0)
216 ACE_ERROR_RETURN ((LM_ERROR,
217 ACE_TEXT ("Problem determining which external ")
218 ACE_TEXT ("viewer to use.\n")),
219 -1);
221 // Set up the command line that will be used when spawning the
222 // external viewer.
223 ACE_Process_Options opts;
224 opts.command_line (ACE_TEXT ("%s %s"),
225 viewer,
226 this->file_.get_path_name ());
228 pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
230 switch (result)
232 case 0:
233 // Child
234 return 0;
235 case ACE_INVALID_PID:
236 ACE_ERROR_RETURN ((LM_ERROR,
237 ACE_TEXT ("Error during viewer spawn of %p\n"),
238 opts.command_line_buf ()),
239 -1);
240 default:
241 // Parent
242 ACE_DEBUG ((LM_INFO,
243 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
244 viewer,
245 result));
246 break;
249 return 0;