iterator_handler.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 280 行
CPP
280 行
// -*- C++ -*-
// Iterator_Handler.cpp,v 1.9 2003/11/04 05:21:30 dhinton Exp
// Ossama Othman <ossama@uci.edu>
#include "ace/FILE_Connector.h"
#include "ace/Log_Msg.h"
#include "ace/Process_Manager.h"
#include "Iterator_Handler.h"
#include "ace/OS_NS_strings.h"
ACE_RCSID(AMI_Iterator, Iterator_Handler, "Iterator_Handler.cpp,v 1.9 2003/11/04 05:21:30 dhinton Exp")
Iterator_Handler::Iterator_Handler (void)
: file_ (ACE_sap_any_cast (const ACE_FILE_Addr &)),
file_io_ (),
contents_ (),
metadata_ (),
offset_ (0),
ami_handler_ (),
request_count_ (0)
{
// Nothing else
}
Iterator_Handler::~Iterator_Handler (void)
{
(void) this->file_io_.close ();
}
void
Iterator_Handler::next_chunk (CORBA::Boolean pending_data,
const Web_Server::Chunk_Type &chunk_data
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
if (pending_data)
{
Web_Server::Chunk_Type_var chunk = chunk_data;
// Append the received data to the corresponding
// buffer/temporary file.
if (this->file_io_.send (chunk->get_buffer (),
chunk->length ()) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("Unable to write retrieved data to ")
ACE_TEXT ("file")));
return;
}
else
this->offset_ += chunk->length ();
this->contents_->sendc_next_chunk (this->ami_handler_.in (),
this->offset_
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
else
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
this->file_.get_path_name ()));
(*this->request_count_)--; // No more data.
// Done with the iterator, so destroy it.
this->contents_->sendc_destroy (this->ami_handler_.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// File retrieval has completed, so spawn an external viewer to
// display its contents.
(void) this->spawn_viewer ();
}
}
void
Iterator_Handler::destroy (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
// Deactivate this reply handler.
this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
void
Iterator_Handler::run (int *request_count,
const char *pathname,
Web_Server::Iterator_Factory_ptr factory
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
Web_Server::Error_Result))
{
if (request_count != 0)
this->request_count_ = request_count;
else
// @@ Application code shouldn't throw system exceptions.
ACE_THROW (CORBA::BAD_PARAM ());
// Initialize the Content Iterator
this->initialize_content_iterator (pathname,
factory
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Activate this Reply Handler.
this->ami_handler_ = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
// Begin the asynchronous invocation.
this->contents_->sendc_next_chunk (this->ami_handler_.in (),
this->offset_
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
void
Iterator_Handler::initialize_content_iterator
(const char *pathname,
Web_Server::Iterator_Factory_ptr factory
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
Web_Server::Error_Result))
{
// Obtain a Content Iterator for the desired file.
factory->get_iterator (pathname,
this->contents_,
this->metadata_
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Create a temporary file to store the retrieved data.
ACE_FILE_Connector connector;
if (connector.connect (this->file_io_,
this->file_,
0,
ACE_Addr::sap_any,
0,
O_CREAT | O_TRUNC | O_WRONLY,
ACE_DEFAULT_FILE_PERMS) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Could not open file %p\n"),
this->file_.get_path_name ()));
else
(*this->request_count_)++;
}
void
Iterator_Handler::deactivate (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException))
{
// Get the POA used when activating the Reply Handler object.
PortableServer::POA_var poa =
this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
// Get the object ID associated with this servant.
PortableServer::ObjectId_var oid =
poa->servant_to_id (this ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Now deactivate the iterator object.
poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
int
Iterator_Handler::get_viewer (char *viewer,
size_t length)
{
const char *content_type =
this->metadata_->content_type.in ();
if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
{
const char lynx[] = "lynx";
if (length <= sizeof (lynx))
return -1;
else
ACE_OS::strcpy (viewer, lynx);
}
else if (ACE_OS::strcasecmp (content_type,
"text/plain") == 0)
{
const char more[] = "more";
if (length <= sizeof (more))
return -1;
else
ACE_OS::strcpy (viewer, more);
}
else if (ACE_OS::strcasecmp (content_type,
"application/postscript") == 0)
{
const char ghostview[] = "ghostview";
if (length <= sizeof (ghostview))
return -1;
else
ACE_OS::strcpy (viewer, ghostview);
}
else if (ACE_OS::strcasecmp (content_type,
"application/pdf") == 0)
{
const char acroread[] = "acroread";
if (length <= sizeof (acroread))
return -1;
else
ACE_OS::strcpy (viewer, acroread);
}
else if (ACE_OS::strcasecmp (content_type,
"image/jpeg") == 0
|| ACE_OS::strcasecmp (content_type,
"image/gif") == 0
|| ACE_OS::strcasecmp (content_type,
"image/tiff") == 0
|| ACE_OS::strcasecmp (content_type,
"image/png") == 0)
{
const char xv[] = "xv";
if (length <= sizeof (xv))
return -1;
else
ACE_OS::strcpy (viewer, xv);
}
else
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Unsupported MIME type: <%s>\n"),
content_type),
-1);
return 0;
}
int
Iterator_Handler::spawn_viewer (void)
{
char viewer[BUFSIZ];
if (this->get_viewer (viewer,
sizeof viewer) != 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Problem determining which external ")
ACE_TEXT ("viewer to use.\n")),
-1);
// Set up the command line that will be used when spawning the
// external viewer.
ACE_Process_Options opts;
opts.command_line (ACE_TEXT ("%s %s"),
viewer,
this->file_.get_path_name ());
pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
switch (result)
{
case 0:
// Child
return 0;
case ACE_INVALID_PID:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error during viewer spawn of %p\n"),
opts.command_line_buf ()),
-1);
default:
// Parent
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
viewer,
result));
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?